Использование Azure Key Vault для передачи безопасного значения параметра во время развертывания
Вместо указания защищенного значения (например, пароля) непосредственно в шаблоне или файле параметров, можно получить значение во время развертывания из хранилища ключей Azure. Для получения значения нужно указать в параметре ссылку на хранилище ключей и секрет. Это значение никогда не будет раскрыто, так как указывается только его идентификатор в хранилище ключей.
Внимание
В этой статье основное внимание уделяется передаче конфиденциального значения в качестве параметра шаблона. Когда секрет передается в качестве параметра, хранилище ключей и группа ресурсов, в которую выполняется развертывание, могут находиться в разных подписках.
В статье не рассматривается настройка свойства виртуальной машины для URL-адреса сертификата в хранилище ключей. Шаблон быстрого запуска такого сценария описан в статье Установка сертификата на виртуальной машине из хранилища ключей Azure.
Развертывание хранилищ Key Vault и секретов
Чтобы получить доступ к хранилищу ключей во время развертывания шаблона, задайте для enabledForTemplateDeployment
хранилища ключей значение true
.
Если у вас уже есть хранилище ключей, убедитесь, что в нем разрешено развертывание шаблонов.
az keyvault update --name ExampleVault --enabled-for-template-deployment true
Чтобы создать новое хранилище ключей и добавить секрет, используйте следующее.
az group create --name ExampleGroup --location centralus
az keyvault create \
--name ExampleVault \
--resource-group ExampleGroup \
--location centralus \
--enabled-for-template-deployment true
az keyvault secret set --vault-name ExampleVault --name "ExamplePassword" --value "hVFkk965BuUv"
В качестве владельца хранилища ключей вы автоматически имеете возможность создания секретов. Если необходимо разрешить другим пользователям создавать секреты, используйте следующее.
az keyvault set-policy \
--upn <user-principal-name> \
--name ExampleVault \
--secret-permissions set delete get list
Политики доступа не нужны, если пользователь развертывает шаблон, который получает секрет. Добавляйте пользователя в политики доступа, только если он должен работать непосредственно с секретами. Разрешения на развертывание определены в следующем разделе.
Дополнительные сведения о создании хранилищ ключей и добавлении секретных кодов представлены в следующих статьях:
- Краткое руководство. Настройка и получение секрета из Azure Key Vault с помощью Azure CLI
- Настройка и получение секретных кодов с помощью PowerShell
- Краткое руководство. Настройка и получение секрета из Azure Key Vault с помощью портала Azure
- Краткое руководство. Настройка и получение секрета из Azure Key Vault с помощью веб-приложения .NET
- Краткое руководство. Настройка и получение секрета из Azure Key Vault с помощью веб-приложения Node
Предоставление развертыванию доступа к секретам
Пользователь, развертывающий шаблон, должен иметь на Microsoft.KeyVault/vaults/deploy/action
доступ к области группы ресурсов и хранилищу ключей. Проверяя этот доступ, Azure Resource Manager предотвращает доступ неутвержденного пользователя к секрету, передавая идентификатор ресурса для хранилища ключей. Можно предоставить доступ к развертыванию пользователям без предоставления доступа на запись в секреты.
Оно имеется у ролей Владелец и Участник. Если вы создали хранилище ключей, вы являетесь владельцем и имеете такое разрешение.
Для других пользователей предоставьте разрешение Microsoft.KeyVault/vaults/deploy/action
. Ниже показано, как создать роль с минимальным разрешением и назначить ее пользователю.
Создание JSON-файла определения пользовательской роли
{ "Name": "Key Vault resource manager template deployment operator", "IsCustom": true, "Description": "Lets you deploy a resource manager template with the access to the secrets in the Key Vault.", "Actions": [ "Microsoft.KeyVault/vaults/deploy/action" ], "NotActions": [], "DataActions": [], "NotDataActions": [], "AssignableScopes": [ "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e" ] }
Замените "00000000-0000-0000-0000-000000000000" на идентификатор подписки.
Создание новой роли с помощью JSON-файла:
az role definition create --role-definition "<path-to-role-file>" az role assignment create \ --role "Key Vault resource manager template deployment operator" \ --scope /subscriptions/<Subscription-id>/resourceGroups/<resource-group-name> \ --assignee <user-principal-name> \ --resource-group ExampleGroup
В этих примерах роль назначается пользователю на уровне группы ресурсов.
При использовании хранилища ключей с шаблоном для управляемого приложения необходимо предоставить доступ к субъекту-службе Поставщик ресурсов устройств. Дополнительные сведения см. в статье Доступ к секрету Key Vault при развертывании Управляемых приложений Azure.
Секреты ссылки со статическим идентификатором
Этот способ дает возможность ссылаться на хранилище ключей в файле параметров, а не в шаблоне. На следующем рисунке показано, как файл параметров ссылается на секрет и передает это значение в шаблон.
Учебник: интеграция хранилища ключей Azure в диспетчер ресурсов при развертывании шаблона с помощью данного метода.
Следующий шаблон развертывает сервер SQL, который содержит пароль администратора. В качестве параметра пароля задается защищенная строка. Но шаблон не указывает, откуда берется это значение.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"sqlServerName": {
"type": "string"
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
},
"adminLogin": {
"type": "string"
},
"adminPassword": {
"type": "securestring"
}
},
"resources": [
{
"type": "Microsoft.Sql/servers",
"apiVersion": "2021-11-01",
"name": "[parameters('sqlServerName')]",
"location": "[parameters('location')]",
"properties": {
"administratorLogin": "[parameters('adminLogin')]",
"administratorLoginPassword": "[parameters('adminPassword')]",
"version": "12.0"
}
}
]
}
Теперь создайте файл параметров для предыдущего шаблона. В файле параметров укажите параметр, который совпадает с именем параметра в шаблоне. Для значения параметра используйте ссылку на секрет из хранилища ключей. Для ссылки на секретный код необходимо передать идентификатор ресурса хранилища ключей и имя секрета.
В приведенном ниже файле параметров секрет хранилища ключей уже должен существовать. При этом для идентификатора ресурса используется статическое значение.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"adminLogin": {
"value": "exampleadmin"
},
"adminPassword": {
"reference": {
"keyVault": {
"id": "/subscriptions/<subscription-id>/resourceGroups/<rg-name>/providers/Microsoft.KeyVault/vaults/<vault-name>"
},
"secretName": "ExamplePassword"
}
},
"sqlServerName": {
"value": "<your-server-name>"
}
}
}
Если необходимо использовать версию секрета, отличную от текущей, включите свойство secretVersion
.
"secretName": "ExamplePassword",
"secretVersion": "cd91b2b7e10e492ebb870a6ee0591b68"
Разверните шаблон и передайте файл параметров.
az group create --name SqlGroup --location westus2
az deployment group create \
--resource-group SqlGroup \
--template-uri <template-file-URI> \
--parameters <parameter-file>
Ссылка на секреты с динамическим идентификатором
Выше мы рассмотрели способ передачи статического идентификатора ресурса для секрета хранилища ключей из параметра. В некоторых сценариях нужно использовать ссылку на секрет хранилища ключей, который изменяется в зависимости от текущего развертывания. Или можно просто передать значения параметра в шаблон вместо создания ссылочного параметра в файле параметров. Решение заключается в динамическом создании идентификатора ресурса для секрета хранилища ключей с помощью связанного шаблона.
Динамически создавать идентификатор ресурса в файле параметров нельзя, так как в файле параметров не разрешены выражения шаблонов.
В родительском шаблоне добавьте вложенный шаблон и передайте параметр, содержащий динамически созданный идентификатор ресурса. На следующем рисунке показано, как параметр в связанном шаблоне ссылается на секрет.
Следующий шаблон динамически создает идентификатор хранилища ключей и передает его в качестве параметра.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "The location where the resources will be deployed."
}
},
"vaultName": {
"type": "string",
"metadata": {
"description": "The name of the keyvault that contains the secret."
}
},
"secretName": {
"type": "string",
"metadata": {
"description": "The name of the secret."
}
},
"vaultResourceGroupName": {
"type": "string",
"metadata": {
"description": "The name of the resource group that contains the keyvault."
}
},
"vaultSubscription": {
"type": "string",
"defaultValue": "[subscription().subscriptionId]",
"metadata": {
"description": "The name of the subscription that contains the keyvault."
}
}
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2020-10-01",
"name": "dynamicSecret",
"properties": {
"mode": "Incremental",
"expressionEvaluationOptions": {
"scope": "inner"
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"adminLogin": {
"type": "string"
},
"adminPassword": {
"type": "securestring"
},
"location": {
"type": "string"
}
},
"variables": {
"sqlServerName": "[concat('sql-', uniqueString(resourceGroup().id, 'sql'))]"
},
"resources": [
{
"type": "Microsoft.Sql/servers",
"apiVersion": "2021-11-01",
"name": "[variables('sqlServerName')]",
"location": "[parameters('location')]",
"properties": {
"administratorLogin": "[parameters('adminLogin')]",
"administratorLoginPassword": "[parameters('adminPassword')]"
}
}
],
"outputs": {
"sqlFQDN": {
"type": "string",
"value": "[reference(variables('sqlServerName')).fullyQualifiedDomainName]"
}
}
},
"parameters": {
"location": {
"value": "[parameters('location')]"
},
"adminLogin": {
"value": "ghuser"
},
"adminPassword": {
"reference": {
"keyVault": {
"id": "[resourceId(parameters('vaultSubscription'), parameters('vaultResourceGroupName'), 'Microsoft.KeyVault/vaults', parameters('vaultName'))]"
},
"secretName": "[parameters('secretName')]"
}
}
}
}
}
]
}
Следующие шаги
- Дополнительные сведения о хранилищах ключей см. в статье Что такое хранилище ключей Azure?
- Полные примеры использования ссылок на секреты ключей приведены на этой странице сайта GitHub.
- Описание модуля Microsoft Learn, который охватывает передачу безопасного значения из хранилища ключей, см. Управление сложными облачными развертываниями с помощью расширенных функций шаблонов ARM.