Создать секрет Azure Keyvault, не раскрывая значения

Мое требование — автоматизировать создание секретов в Keyvault, не раскрывая значения этих секретов во время выполнения конвейера (AzureDevops Server).

пробовал разные варианты, такие как наличие входных параметров (он будет отображать значения при выполнении инициализации), переменные времени выполнения и т. д. (список переменных или динамическое создание по входным данным невозможно), но не смог удовлетворить наши требования.

Наконец, планировалось использовать приведенный ниже сценарий для чтения значений из группы библиотек и создания значений в хранилище ключей. Но когда мы маскируем секретные значения в группе «Библиотека» (путем блокировки), секреты создаются только с нулевым значением. Итак, есть ли способ получить секретные переменные значений и создать их в хранилище ключей, только если секретное значение отличается (если существует)

-bash: | 
   az login --service-principal --username $(spid) --password $(spsecret) --tenant $(tenantid)
   az account set --subscription ${{ variables.subscription }}
   az config set extension.use_dynamic_install=yes_without_prompt
   groupID=`az pipelines variable-group list -p myproject --group-name ${{ environment }}-${{ parameters.myapp}}-kv-secret --query '[].id' -o tsv`
   echo "grouup id is $groupID"
   variables=$(az pipelines variable-group variable list -p myproject --group-id $groupID --output json)
   echo "$variables" | jq -r 'keys[] as $k | "\($k)=\(.[$k].value)"' | while read variable; do
   name=$(echo "$variable" | cut -d= -f1)
   value=$(echo "$variable" | cut -d= -f2)
   if ! az keyvault secret show --vault-name "$(${{ variables.podkv }})" --name "$name" &>/dev/null; then
     expiryDate=$(date -u -d '+2 years' '+%Y-%m-%dT%H:%MZ')
     az keyvault secret set --vault-name "$(${{ variables.podkv }})" --name "$name" --value "$value" --expires $expiryDate
     secretValue=$(az keyvault secret show --vault-name "$(${{ variables.podkv }})" --name "$name" --query value --output tsv)
     if [[ "$secretValue" != "$value" ]]; then
       echo "Failed to create secret $secretName in Key Vault $keyVaultName"
     exit 1
     fi
     if [[ "$secretValue" == "$value" ]]; then
       echo "Created secret $secretName in Key Vault $keyVaultName, hence cleaning the variable from the keyvault"
       az pipelines variable-group variable delete --group-id $groupID --name "$name --yes"
     fi
   fi
   done

Обновлен скрипт,

где секрет обновляется каждый раз, даже если в файле одно и то же значение.

while IFS= read -r line    
do    
  name=$(echo "$line" | cut -d '=' -f 1)    
  value=$(echo "$line" | cut -d '=' -f 2)    
  if ! az keyvault secret show --vault-name "$(${{ variables.podkv }})" --name "$name" &>/dev/null; then    
    expiryDate=$(date -u -d '+2 years' '+%Y-%m-%dT%H:%MZ')    
    az keyvault secret set --vault-name "$(${{ variables.podkv }})" --name "$name" --value "$value" --expires $expiryDate --output none  
    secretValue=$(az keyvault secret show --vault-name "$(${{ variables.podkv }})" --name "$name" --query value --output tsv)    
    if [[ "$secretValue" != "$value" ]]; then    
      echo "Failed to create secret $name in Key Vault ${{ variables.podkv }}"    
      exit 1    
    else    
      echo "Created secret $name in Key Vault ${{ variables.podkv }}, hence cleaning the variable from the keyvault"    
    fi    
  else    
    echo "The secretName $name already exists, so checking if the secret value is the same"    
    existing_secretvalue=$(az keyvault secret show --name "$name" --vault-name "$(${{ variables.podkv }})" --query "value")    
    if [[ "$existing_secretValue" != "$value" ]]; then    
      echo "there is secret value change for the secretname $name , so Creating a new secret value for the existing secret $name"    
      expiryDate=$(date -u -d '+2 years' '+%Y-%m-%dT%H:%MZ')    
      az keyvault secret set --vault-name "$(${{ variables.podkv }})" --name "$name" --value "$value" --expires $expiryDate --output none  
      new_secretValue=$(az keyvault secret show --vault-name "$(${{ variables.podkv }})" --name "$name" --query value --output tsv)    
      if [[ "$new_secretValue" != "$value" ]]; then    
        echo "Failed to create secret $name in Key Vault ${{ variables.podkv }}"    
        exit 1    
      else    
        echo "Created secret $name in Key Vault ${{ variables.podkv }}, hence cleaning the variable from the keyvault"    
      fi  
    fi  
  fi  
done < "$(keyvault.secureFilePath)"
Finally planned to use the below script to read values from library group and create the values in key vault — вам следует поступить наоборот: создать группы переменных с переменными, связанными с Azure Keyvault. Имейте в виду, что после создания группы переменных с секретной переменной вы не сможете получить ее с помощью портала Azure DevOps.
Rui Jarimba 22.07.2024 10:44
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
0
1
130
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Мое требование — автоматизировать создание секретов в Keyvault, не раскрывая значения этих секретов во время выполнения конвейера.

При использовании Azure CLI вы можете использовать формат вывода --output none, чтобы конфиденциальная информация не отображалась на консоли.

Пример:

az keyvault secret set ... --output none

См. Выходной формат «Нет» для более подробной информации.

Ответ принят как подходящий

когда мы маскируем секретные значения в группе «Библиотека» (путем блокировки), секреты создаются только с нулевым значением.

Это ожидаемое поведение. Когда мы устанавливаем секретную переменную в группе переменных, мы не можем использовать Rest API или Azure DevOps CLI для получения этой переменной. Он будет отображаться как значение NULL.

В этом случае я боюсь, что метод группы переменных не сможет удовлетворить ваши требования.

есть ли способ получить значения секретных переменных

Основываясь на вашем описании, я предлагаю вам сохранить переменные в файле и добавить его в безопасный файл Azure DevOps (Конвейеры -> Библиотека -> Защищенный файл).

Защищенный файл можно загрузить только с помощью задачи Загрузка защищенного файла версии 1 в Azure Pipelines.

Вот шаги:

Шаг 1: Мы можем создать файл и сохранить переменные.

Например:

test.txt

var1=value1
var2=value2
var3=value3

Шаг 2: Загрузите файл в защищенный файл.

Например:

Шаг 3. Мы можем использовать задачу «Загрузить защищенный файл версии 1», чтобы загрузить защищенный файл, а затем использовать сценарий bash для зацикливания значений в файле. Наконец, мы можем установить значение хранилища ключей.

Вот пример:

steps:
- task: DownloadSecureFile@1
  name: keyvault
  inputs:
    secureFile: 'test.txt'
- bash: |
    while IFS= read -r line
    do
        name=$(echo "$line" | cut -d '=' -f 1)
        value=$(echo "$line" | cut -d '=' -f 2)

      if ! az keyvault secret show --vault-name "$(${{ variables.podkv }})" --name "$name" &>/dev/null; then
      expiryDate=$(date -u -d '+2 years' '+%Y-%m-%dT%H:%MZ')
      az keyvault secret set --vault-name "$(${{ variables.podkv }})" --name "$name" --value "$value" --expires $expiryDate
      secretValue=$(az keyvault secret show --vault-name "$(${{ variables.podkv }})" --name "$name" --query value --output tsv)
      if [[ "$secretValue" != "$value" ]]; then
        echo "Failed to create secret $secretName in Key Vault $keyVaultName"
      exit 1
      fi
      if [[ "$secretValue" == "$value" ]]; then
        echo "Created secret $secretName in Key Vault $keyVaultName, hence cleaning the variable from the keyvault"
        az pipelines variable-group variable delete --group-id $groupID --name "$name --yes"
      fi
    fi
    done < "$(keyvault.secureFilePath)"

В этом случае значение переменной не будет отображаться во время работы конвейера. Защищенный файл будет автоматически удален (на компьютере с агентом) после завершения запуска конвейера.

Для получения более подробной информации вы можете обратиться к этому документу: Используйте защищенные файлы

создавайте их в хранилище ключей, только если секретное значение отличается (если существует)

Вы можете добавить Azure CLI: Получить секрет из Key Vault в цикл bash для сравнения значения секрета и текущего значения переменной.

Обновлять:

Я могу воспроизвести ту же проблему при использовании того же сценария bash.

Причина проблемы в том, что когда мы используем Azure CLI для получения существующего секретного значения. он автоматически добавит \r в конце значения.

Эта строка:

existing_secretvalue=$(az keyvault secret show --name "$name" --vault-name "$(${{ variables.podkv }})" --query "value")    

Например:

Чтобы решить эту проблему, вы можете добавить --output tsv, чтобы отформатировать вывод секретного значения.

Например:

az keyvault secret show --vault-name "$(${{ variables.podkv }})" --name "$name" --query value --output tsv

Обновление2:

он не будет выбирать значение для переменной, которая имеет в своем значении специальный символ "=".

Чтобы решить эту проблему, вы можете использовать следующий сценарий bash для чтения переменных в файле.

while IFS=$'=' read -r key values;
do    
  name=$key
  value=$values   
  echo $name
  echo $value
done < "$(keyvault.secureFilePath)"

Результат:

Команда echo используется для подтверждения правильности значения. Вы можете удалить его в своем bash-скрипте.

Это решение сработало. Но единственная проблема, с которой я сталкиваюсь, заключается в том, что каждый раз создается новая версия секрета, даже если значение этой переменной в защищенном файле одинаковое.

Vowneee 23.07.2024 07:26

добавил мой скрипт в обновленную часть вопроса о скрипте

Vowneee 23.07.2024 07:43

@Vownee Спасибо, что поделились. Скрипт проверю дальше. Если будут какие-то обновления, я вам сообщу.

Kevin Lu-MSFT 23.07.2024 08:03

@Vowneee, я могу воспроизвести ту же проблему, что и твоя. Причина проблемы в том, что выходные данные Azure CLI: az keyvault secret show --name "$name" --vault-name "$(${{ variables.podkv }})" --query "value" добавит дополнительный \r в конец строки. Нам нужно его отформатировать. Пожалуйста, обратитесь к обновленному ответу.

Kevin Lu-MSFT 23.07.2024 09:10

Хорошо... Я тоже принял ответ. Не хватает одного: не очищается защищенный файл, добавленный из окна защищенного файла AzureDevops, после создания секретов. что может сбить с толку наших пользователей, могут ли они загружать туда новый файл с тем же именем или нет (у нас есть некоторые условия, чтобы иметь имя защищенного файла, поэтому сохранение защищенного файла снова введет пользователей в заблуждение во второй раз, когда они попытаются обновить хранилища ключей.

Vowneee 23.07.2024 19:34

Опять же, проблема здесь в том, что он не выберет значение для переменной, которая имеет в своем значении специальный символ " = ". У нас есть длинные значения строки подключения и т. д., значение которых имеет " = ". мы хотим сохранить это как то же значение. но здесь он просто создает значение до появления " = "..... например: dev-variable1 = "dev-valuchangedfrom=1to=3".. который создает переменную со значением до "dev-valuchangedfrom"

Vowneee 24.07.2024 17:47

@Vowneee, я понимаю проблему. Завтра я проведу еще больше тестов и сообщу вам новости.

Kevin Lu-MSFT 24.07.2024 18:20

@Vownee Пожалуйста, обратитесь к обновлению 2 в моем ответе. Он может вывести правильное значение, содержит =

Kevin Lu-MSFT 25.07.2024 08:46

Другие вопросы по теме

Возникает ошибка при попытке отключить конвейер Azure DevOps с помощью Powershell
Автоматическое преобразование значения Azure DevOps в целочисленный тип в yaml
Есть ли способ создать повторно используемые и масштабируемые конвейеры сборки и развертывания для аналогичных служб в среде Azure DevOps?
Проблема при создании рабочего элемента Azure DevOps с полями Microsoft.VSTS.Common.Priority и Microsoft.VSTS.Common.StackRank
Некоторые конвейеры сборки ADO отображают все рабочие элементы в связанных элементах, а другие — только соответствующие элементы. Ищем идеи
Родительская ссылка Azure DevOps REST API на существующую ошибку рабочего элемента
Как предоставить разрешения на вызов REST API Azure DevOps с помощью System.AccessToken?
Как включить или отключить вкладки на основе шаблона значений поля в Azure DevOps WITD XML
Azure DevOps YAML: могу ли я запустить задание на другом агенте?
Как установить условные переходы состояний на основе логического поля в Azure DevOps WITD XML