Поделиться через


Использование 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, которое находится в группе ресурсов Секретов:

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 функции.

Наведите ссылку на хранилище ключей, указав идентификатор подписки, имя группы ресурсов и имя хранилища ключей. Значение секрета можно получить, указав имя секрета. При необходимости можно указать версию секрета; Последняя версия используется, если вы этого не сделали.

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 используйте секретные переменные для хранения защищенных данных.