Gerenciar segredos usando o Bicep

As implantações geralmente exigem que os segredos sejam armazenados e propagados com segurança em todo o ambiente do Azure. O Bicep e o Azure fornecem muitos recursos para ajudá-lo a gerenciar segredos em suas implantações.

Evite segredos onde puder

Em muitas situações, é possível evitar o uso de segredos. Muitos recursos do Azure dão suporte a identidades gerenciadas, que permitem que eles se autentiquem e sejam autorizados a acessar outros recursos no Azure, sem que você precise manipular ou gerenciar credenciais. Além disso, alguns serviços do Azure podem gerar certificados HTTPS para você automaticamente, evitando que você manipule certificados e chaves privadas. Use identidades gerenciadas e certificados gerenciados por serviço sempre que possível.

Use parâmetros seguros

Quando precisar fornecer segredos para suas implantações do Bíceps como parâmetros, use o @secure() decorador. Quando você marca um parâmetro como seguro, o Azure Resource Manager evita registrar o valor ou exibi-lo no portal do Azure, na CLI do Azure ou no Azure PowerShell.

Evite saídas para segredos

Não use saídas Bicep para dados seguros. As saídas são registradas no histórico de implantação e qualquer pessoa com acesso à implantação pode visualizar os valores das saídas de uma implantação.

Se você precisar gerar um segredo dentro de uma implantação do Bicep e disponibilizá-lo para o chamador ou para outros recursos, considere usar uma das seguintes abordagens.

Procure segredos dinamicamente

Às vezes, você precisa acessar um segredo de um recurso para configurar outro recurso.

Por exemplo, você pode ter criado uma conta de armazenamento em outra implantação e precisar acessar sua chave primária para configurar um aplicativo do Azure Functions. Você pode usar a existing palavra-chave para obter uma referência fortemente tipada à conta de armazenamento pré-criada e, em seguida, usar o método da conta de armazenamento para criar uma cadeia de listKeys() conexão com a chave primária:

O exemplo a seguir faz parte de um exemplo maior. Para obter um arquivo Bicep que você pode implantar, consulte o arquivo completo.

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'
  }
}

Ao usar essa abordagem, você evita passar segredos para dentro ou para fora do seu arquivo Bicep.

Você também pode usar essa abordagem para armazenar segredos em um cofre de chaves.

Usar o Cofre da Chave

O Azure Key Vault foi projetado para armazenar e gerenciar dados seguros. Use um cofre de chaves para gerenciar seus segredos, certificados, chaves e outros dados que precisam ser protegidos e compartilhados.

Você pode criar e gerenciar cofres e segredos usando o Bicep. Defina seus cofres criando um recurso com o tipo Microsoft.KeyVault/vaults.

Ao criar um cofre, você precisa determinar quem e o que pode acessar seus dados. Se você planeja ler os segredos do cofre de dentro de um arquivo Bicep, defina a enabledForTemplateDeployment propriedade como true.

Adicionar segredos a um cofre de chaves

Os segredos são um recurso filho e podem ser criados usando o tipo Microsoft.KeyVault/vaults/secrets. O exemplo a seguir demonstra como criar um cofre e um segredo:

O exemplo a seguir faz parte de um exemplo maior. Para obter um arquivo Bicep que você pode implantar, consulte o arquivo completo.

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'
  }
}

Gorjeta

Quando você usa pipelines de implantação automatizados, às vezes pode ser um desafio determinar como inicializar segredos do cofre de chaves para suas implantações. Por exemplo, se você recebeu uma chave de API para usar ao se comunicar com uma API externa, o segredo precisa ser adicionado a um cofre antes de poder ser usado em suas implantações.

Quando você trabalha com segredos que vêm de terceiros, talvez seja necessário adicioná-los manualmente ao seu cofre e, em seguida, você pode fazer referência ao segredo para todos os usos subsequentes.

Usar um cofre de chaves com módulos

Quando você usa módulos Bicep, você pode fornecer parâmetros seguros usando a getSecret função.

Você também pode fazer referência a um cofre de chaves definido em outro grupo de recursos usando as existing palavras-chave e scope juntas. No exemplo a seguir, o arquivo Bicep é implantado em um grupo de recursos chamado Rede. O valor para o parâmetro mySecret do módulo é definido em um cofre de chaves chamado contosonetworkingsecrets localizado no grupo de recursos Secrets :

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')
  }
}

Usar um cofre de chaves em um arquivo .bicepparam

Ao usar .bicepparam o formato de arquivo, você pode fornecer valores seguros para parâmetros usando a getSecret função.

Faça referência ao KeyVault fornecendo o ID da assinatura, o nome do grupo de recursos e o nome do cofre da chave. Você pode obter o valor do segredo fornecendo o nome do segredo. Opcionalmente, você pode fornecer a versão secreta. Se você não fornecer a versão secreta, a versão mais recente será usada.

using './main.bicep'

param secureUserName = az.getSecret('<subscriptionId>', '<resourceGroupName>', '<keyVaultName>', '<secretName>', '<secretVersion>')
param securePassword = az.getSecret('<subscriptionId>', '<resourceGroupName>', '<keyVaultName>', '<secretName>')

Trabalhar com segredos em pipelines

Quando você implanta seus recursos do Azure usando um pipeline, precisa tomar cuidado para lidar com seus segredos adequadamente.

  • Evite armazenar segredos em seu repositório de código. Por exemplo, não adicione segredos a arquivos de parâmetros ou a seus arquivos YAML de definição de pipeline.
  • Nas Ações do GitHub, use segredos criptografados para armazenar dados seguros. Use a varredura secreta para detetar qualquer cometimento acidental de segredos.
  • No Azure Pipelines, use variáveis secretas para armazenar dados seguros.