Мое требование — автоматизировать создание секретов в 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)"
Мое требование — автоматизировать создание секретов в 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-скрипте.
Это решение сработало. Но единственная проблема, с которой я сталкиваюсь, заключается в том, что каждый раз создается новая версия секрета, даже если значение этой переменной в защищенном файле одинаковое.
добавил мой скрипт в обновленную часть вопроса о скрипте
@Vownee Спасибо, что поделились. Скрипт проверю дальше. Если будут какие-то обновления, я вам сообщу.
@Vowneee, я могу воспроизвести ту же проблему, что и твоя. Причина проблемы в том, что выходные данные Azure CLI: az keyvault secret show --name "$name" --vault-name "$(${{ variables.podkv }})" --query "value"
добавит дополнительный \r
в конец строки. Нам нужно его отформатировать. Пожалуйста, обратитесь к обновленному ответу.
Хорошо... Я тоже принял ответ. Не хватает одного: не очищается защищенный файл, добавленный из окна защищенного файла AzureDevops, после создания секретов. что может сбить с толку наших пользователей, могут ли они загружать туда новый файл с тем же именем или нет (у нас есть некоторые условия, чтобы иметь имя защищенного файла, поэтому сохранение защищенного файла снова введет пользователей в заблуждение во второй раз, когда они попытаются обновить хранилища ключей.
Опять же, проблема здесь в том, что он не выберет значение для переменной, которая имеет в своем значении специальный символ " = ". У нас есть длинные значения строки подключения и т. д., значение которых имеет " = ". мы хотим сохранить это как то же значение. но здесь он просто создает значение до появления " = "..... например: dev-variable1 = "dev-valuchangedfrom=1to=3".. который создает переменную со значением до "dev-valuchangedfrom"
@Vowneee, я понимаю проблему. Завтра я проведу еще больше тестов и сообщу вам новости.
@Vownee Пожалуйста, обратитесь к обновлению 2 в моем ответе. Он может вывести правильное значение, содержит =
Finally planned to use the below script to read values from library group and create the values in key vault
— вам следует поступить наоборот: создать группы переменных с переменными, связанными с Azure Keyvault. Имейте в виду, что после создания группы переменных с секретной переменной вы не сможете получить ее с помощью портала Azure DevOps.