Administrar secretos con Bicep

Las implementaciones a menudo requieren que los secretos se almacenen y propaguen de forma segura en todo el entorno de Azure. Bicep y Azure proporcionan muchas características para ayudarle a administrar secretos en sus implementaciones.

Evitar los secretos siempre sea posible

En muchas situaciones, es posible evitar el uso de secretos. Muchos recursos de Azure admiten identidades administradas, que les permiten autenticarse y estar autorizados a obtener acceso a otros recursos de Azure, sin tener que controlar ni administrar credenciales. Además, algunos servicios de Azure pueden generar automáticamente certificados HTTPS, lo que evita que el control de certificados y claves privadas. Use identidades administradas y certificados administrados por el servicio siempre que sea posible.

Usar parámetros seguros

Cuando necesite proporcionar secretos a las implementaciones de Bicep como parámetros, use el decorador @secure(). Al marcar un parámetro como seguro, Azure Resource Manager evita registrar el valor o mostrarlo en Azure Portal, la CLI de Azure o Azure PowerShell.

Evitar las salidas para los secretos

No use salidas de Bicep para los datos seguros. Los resultados se registran en el historial de implementaciones y cualquier persona con acceso a la implementación puede ver los valores de los resultados de una implementación.

Si necesita generar un secreto dentro de una implementación de Bicep y que esté disponible para el autor de la llamada o para otros recursos, considere la posibilidad de usar uno de los siguientes métodos.

Buscar los secretos dinámicamente

A veces, necesita obtener acceso a un secreto desde un recurso para configurar otro recurso.

Por ejemplo, es posible que haya creado una cuenta de almacenamiento en otra implementación y que tenga que tener acceso a su clave principal para configurar una aplicación de Azure Functions. Puede usar la palabra clave existing para obtener una referencia fuertemente tipada a la cuenta de almacenamiento creada previamente y, posteriormente, usar el método listKeys() de la cuenta de almacenamiento para crear una cadena de conexión con la clave principal:

El ejemplo siguiente forma parte de un ejemplo más grande. Para ver un archivo de Bicep que puede implementar, consulte el archivo completo.

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@2021-02-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
        }
      ]
    }
  }
}

Con este método, evitará pasar secretos dentro o fuera del archivo Bicep.

También puede usar este método para almacenar secretos en un almacén de claves.

Usar el almacén de claves

Azure Key Vault está diseñado para almacenar y administrar datos seguros. Use un almacén de claves para administrar los secretos, certificados, claves y otros datos que deben protegerse y compartirse.

Puede crear y administrar almacenes y secretos con Bicep. Para definir las redes virtuales, cree un recurso con el tipo Microsoft.KeyVault/vaults.

Al crear un almacén, debe determinar quién y qué puede obtener acceso a sus datos. Si tiene previsto leer los secretos del almacén desde un archivo Bicep, establezca la propiedad enabledForTemplateDeployment en true.

Agregar secretos a un almacén de claves

Los secretos son un recurso secundario y se pueden crear con el tipo Microsoft.KeyVault/vaults/secrets. En el ejemplo siguiente se muestra cómo crear un almacén y un secreto:

El ejemplo siguiente forma parte de un ejemplo más grande. Para ver un archivo de Bicep que puede implementar, consulte el archivo completo.

resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' = {
  name: keyVaultName
  location: location
  properties: {
    enabledForTemplateDeployment: true
    tenantId: tenant().tenantId
    accessPolicies: [
    ]
    sku: {
      name: 'standard'
      family: 'A'
    }
  }
}

resource keyVaultSecret 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = {
  parent: keyVault
  name: 'MySecretName'
  properties: {
    value: 'MyVerySecretValue'
  }
}

Sugerencia

Al usar canalizaciones de implementación automatizadas, a veces puede ser difícil determinar cómo iniciar los secretos del almacén de claves para las implementaciones. Por ejemplo, si se le ha proporcionado una clave de API para usar al comunicarse con una API externa, el secreto debe agregarse a un almacén para poder usarlo en las implementaciones.

Cuando trabaja con secretos procedentes de un tercero, es posible que deba agregarlos manualmente al almacén y, posteriormente, puede hacer referencia al secreto para todos los usos posteriores.

Usar un almacén de claves con módulos

Al usar módulos Bicep, puede proporcionar parámetros seguros mediante la función getSecret.

También puede hacer referencia a un almacén de claves definido en otro grupo de recursos con las palabras clave existing y scope juntas. En el siguiente ejemplo, el archivo Bicep se implementa en un grupo de recursos denominado Redes. El valor del parámetro del módulo mySecret se define en un almacén de claves denominado contosonetworkingsecrets ubicado en el grupo de recursos Secretos:

resource networkingSecretsKeyVault 'Microsoft.KeyVault/vaults@2019-09-01' existing = {
  scope: resourceGroup('Secrets')
  name: 'contosonetworkingsecrets'
}

module exampleModule 'module.bicep' = {
  name: 'exampleModule'
  params: {
    mySecret: networkingSecretsKeyVault.getSecret('mySecret')
  }
}

Uso de un almacén de claves en un archivo .bicepparam

Al usar módulos el formato de archivo .bicepparam, puede proporcionar parámetros seguros mediante la getSecretfunción.

Haga referencia a KeyVault proporcionando el identificador de suscripción, el nombre del grupo de recursos y el nombre del almacén de claves. Puede obtener el valor del secreto proporcionando el nombre del secreto. Opcionalmente, puede proporcionar la versión del secreto. Si no proporciona la versión del secreto, se usa la versión más reciente.

using './main.bicep'

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

Trabajar con secretos en canalizaciones

Al implementar los recursos de Azure mediante una canalización, debe tener cuidado de administrar los secretos de forma adecuada.

  • Evite almacenar secretos en el repositorio de código. Por ejemplo, no agregue secretos a los archivos de parámetros o a los archivos YAML de definición de canalización.
  • En Acciones de GitHub, use secretos cifrados para almacenar datos seguros. Use el análisis de secretos para detectar cualquier confirmación accidental de secretos.
  • En Azure Pipelines, use variables secretas para almacenar datos seguros.