Управление секретами с помощью Bicep
Для развертываний часто требуется безопасно хранить секреты и распространять их в среде Azure. В Bicep и Azure есть множество функций, которые помогут вам управлять секретами в развертываниях.
При возможности не используйте секреты
Во многих случаях секреты можно вообще не использовать. Многие ресурсы Azure поддерживают управляемые удостоверения, позволяющие им выполнять проверку подлинности и получать разрешение на доступ к другим ресурсам в Azure без обработки учетных данных и управления ими. Кроме того, некоторые службы Azure могут автоматически создавать сертификаты HTTPS, чтобы не обрабатывать сертификаты и закрытые ключи. По возможности используйте управляемые удостоверения и сертификаты, управляемые службами.
Используйте защищенные параметры
Если вам нужно предоставить секреты в развертывания Bicep в качестве параметров, используйте декоратор @secure()
. Если пометить параметр как безопасный, Azure Resource Manager не будет вносить значение в журнал или отображать его на портале Azure, в Azure CLI или Azure PowerShell.
Не используйте выходных данных для секретов
Не используйте выходные данные Bicep для защищенных данных. Выходные данные регистрируются в журнале развертывания, и любой человек, у кого есть доступ к развертыванию, может просмотреть значения выходных данных развертывания.
Если вам нужно создать секрет в развертывании Bicep и сделать его доступным для вызывающего или других ресурсов, рассмотрите один из описанных ниже подходов.
Ищите секреты динамически
Иногда для настройки одного ресурса требуется доступ к секрету другого ресурса.
Например, если вы создали учетную запись хранения в другом развертывании и вам нужно получить доступ к ее первичному ключу для настройки приложения решения "Функции Azure". С помощью ключевого слова existing
вы можете получить строго типизированную ссылку на предварительно созданную учетную запись хранения, а затем с помощью метода listKeys()
учетной записи хранения создать строку подключения с первичным ключом:
Следующий пример является частью большего примера. Для файла Bicep, который вы можете развернуть, см. полный файл.
param location string = resourceGroup().location
param storageAccountName string
param functionAppName string = 'fn-${uniqueString(resourceGroup().id)}'
var appServicePlanName = 'MyPlan'
var applicationInsightsName = 'MyApplicationInsights'
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' existing = {
name: storageAccountName
}
var storageAccountConnectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value}'
resource functionApp 'Microsoft.Web/sites@2023-12-01' = {
name: functionAppName
location: location
kind: 'functionapp'
properties: {
httpsOnly: true
serverFarmId: appServicePlan.id
siteConfig: {
appSettings: [
{
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
value: applicationInsights.properties.InstrumentationKey
}
{
name: 'AzureWebJobsStorage'
value: storageAccountConnectionString
}
{
name: 'FUNCTIONS_EXTENSION_VERSION'
value: '~3'
}
{
name: 'FUNCTIONS_WORKER_RUNTIME'
value: 'dotnet'
}
{
name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING'
value: storageAccountConnectionString
}
]
}
}
}
resource appServicePlan 'Microsoft.Web/serverfarms@2023-12-01' = {
name: appServicePlanName
location: location
sku: {
name: 'Y1'
tier: 'Dynamic'
}
}
resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
name: applicationInsightsName
location: location
kind: 'web'
properties: {
Application_Type: 'web'
publicNetworkAccessForIngestion: 'Enabled'
publicNetworkAccessForQuery: 'Enabled'
}
}
Использование этого метода позволяет избежать передачи секретов в файл Bicep или из него.
Этот способ также можно использовать для хранения секретов в хранилище ключей.
Использование Key Vault
Azure Key Vault используется для хранения защищенных данных и управления ими. Используйте хранилище ключей для управления секретами, сертификатами, ключами и другими данными, которые необходимо защитить и совместно использовать.
С помощью Bicep можно создавать хранилища ключей и секреты и управлять ими. Определите свои хранилища, создав ресурс с типом Microsoft.KeyVault/vaults
.
При создании хранилища ключей необходимо определить, кто и что могут получать доступ к его данным. Если вы планируете считывать секреты хранилища ключей из файла Bicep, установите для свойства enabledForTemplateDeployment
значение true
.
Добавление секретов в хранилище ключей
Секрет — это дочерний ресурс, который можно создавать с помощью типа Microsoft.KeyVault/vaults/secrets
. В следующем примере показано создание хранилища ключей и секрета:
Следующий пример является частью большего примера. Для файла Bicep, который вы можете развернуть, см. полный файл.
param location string = resourceGroup().location
param keyVaultName string = 'mykv${uniqueString(resourceGroup().id)}'
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
name: keyVaultName
location: location
properties: {
enabledForTemplateDeployment: true
tenantId: tenant().tenantId
accessPolicies: [
]
sku: {
name: 'standard'
family: 'A'
}
}
}
resource keyVaultSecret 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = {
parent: keyVault
name: 'MySecretName'
properties: {
value: 'MyVerySecretValue'
}
}
Совет
При использовании автоматизированных конвейеров развертываний иногда бывает сложно определить, как выполнить начальную загрузку секретов хранилища ключей для развертываний. Например, если вам предоставлен ключ API для связи с внешним API, перед использованием в развертываниях секрет нужно добавить в хранилище ключей.
При работе с секретами от третьей стороны может потребоваться вручную добавить их в хранилище ключей, а затем ссылаться на них для всех последующих использований.
Использование хранилища ключей с модулями
При использовании модулей Bicep можно предоставить защищенные параметры с помощью функции getSecret
.
Вы также можете ссылаться на хранилище ключей, определенное в другой группе ресурсов, используя вместе ключевые слова existing
и scope
вместе. В следующем примере файл Bicep развертывается в группе ресурсов с именем Networking. Значение параметра mySecret модуля определяется в хранилище ключей contosonetworkingsecrets, расположенном в группе ресурсов Secret:
resource networkingSecretsKeyVault 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
scope: resourceGroup('Secrets')
name: 'contosonetworkingsecrets'
}
module exampleModule 'module.bicep' = {
name: 'exampleModule'
params: {
mySecret: networkingSecretsKeyVault.getSecret('mySecret')
}
}
Использование хранилища ключей в файле Bicepparam
При использовании .bicepparam
формата файла можно предоставить безопасные значения параметрам с помощью getSecret
функции.
Наведите ссылку на KeyVault, указав идентификатор подписки, имя группы ресурсов и имя хранилища ключей. Значение секрета можно получить, указав имя секрета. При необходимости можно указать версию секрета. Если вы не предоставляете секретную версию, используется последняя версия.
using './main.bicep'
param secureUserName = az.getSecret('<subscriptionId>', '<resourceGroupName>', '<keyVaultName>', '<secretName>', '<secretVersion>')
param securePassword = az.getSecret('<subscriptionId>', '<resourceGroupName>', '<keyVaultName>', '<secretName>')
Работа с секретами в конвейерах
При развертывании ресурсов Azure с помощью конвейера необходимо обеспечить правильную обработку секретов.
- Избегайте хранения секретов в репозитории кода. Например, не добавляйте секрет к файлам параметров или YAML-файлам определения конвейера.
- В GitHub Actions используйте зашифрованные секреты для хранения защищенных данных. Используйте сканирование секретов, чтобы обнаружить любые случайные фиксации секретов.
- В Azure Pipelines используйте секретные переменные для хранения защищенных данных.
Связанные ресурсы
- Документация по ресурсам
- Функции Azure
- Функции Bicep
- Шаблоны быстрого запуска
- Azure Pipelines
- Действия GitHub