Gestire i segreti con Bicep

Le distribuzioni richiedono spesso che i segreti vengano archiviati e propagati in modo sicuro in tutto l'ambiente Azure. Bicep e Azure offrono molte funzionalità per facilitare la gestione dei segreti nelle distribuzioni.

Evitare segreti in cui è possibile

In molte situazioni, è possibile evitare di usare i segreti. Molte risorse di Azure supportano le identità gestite, che consentono loro di eseguire l'autenticazione e di essere autorizzate ad accedere ad altre risorse in Azure, senza dover gestire o gestire le credenziali. Inoltre, alcuni servizi di Azure possono generare automaticamente certificati HTTPS, evitando di gestire certificati e chiavi private. Usare le identità gestite e i certificati gestiti dal servizio laddove possibile.

Usare parametri sicuri

Quando è necessario fornire segreti alle distribuzioni Bicep come parametri, usare l'elemento @secure() Decorator. Quando si contrassegna un parametro come sicuro, Azure Resource Manager evita di registrare il valore o visualizzarlo nel portale di Azure, nell'interfaccia della riga di comando di Azure o Azure PowerShell.

Evitare output per i segreti

Non usare gli output Bicep per i dati sicuri. Gli output vengono registrati nella cronologia di distribuzione e chiunque abbia accesso alla distribuzione può visualizzare i valori degli output di una distribuzione.

Se è necessario generare un segreto all'interno di una distribuzione Bicep e renderlo disponibile al chiamante o ad altre risorse, è consigliabile usare uno degli approcci seguenti.

Cercare i segreti in modo dinamico

In alcuni casi, è necessario accedere a un segreto da una risorsa per configurare un'altra risorsa.

Ad esempio, è possibile che sia stato creato un account di archiviazione in un'altra distribuzione e che sia necessario accedere alla relativa chiave primaria per configurare un'app Funzioni di Azure. È possibile usare la existing parola chiave per ottenere un riferimento fortemente tipizzato all'account di archiviazione già creato e quindi usare il metodo dell'account di listKeys() archiviazione per creare una stringa di connessione con la chiave primaria:

L'esempio seguente fa parte di un esempio più ampio. Per un file Bicep che è possibile distribuire, vedere il file 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
        }
      ]
    }
  }
}

Usando questo approccio, si evita di passare segreti al file Bicep o all'esterno del file Bicep.

È anche possibile usare questo approccio per archiviare i segreti in un insieme di credenziali delle chiavi.

Usare Key Vault

Azure Key Vault è progettato per archiviare e gestire dati sicuri. Usare un insieme di credenziali delle chiavi per gestire segreti, certificati, chiavi e altri dati che devono essere protetti e condivisi.

È possibile creare e gestire insiemi di credenziali e segreti usando Bicep. Definire gli insiemi di credenziali creando una risorsa con il tipo Microsoft.KeyVault/vaults.

Quando si crea un insieme di credenziali, è necessario determinare chi e cosa può accedere ai dati. Se si prevede di leggere i segreti dell'insieme di credenziali dall'interno di un file Bicep, impostare la enabledForTemplateDeployment proprietà su true.

Aggiungere segreti a un insieme di credenziali delle chiavi

I segreti sono una risorsa figlio e possono essere creati usando il tipo Microsoft.KeyVault/vaults/secrets. L'esempio seguente illustra come creare un insieme di credenziali e un segreto:

L'esempio seguente fa parte di un esempio più ampio. Per un file Bicep che è possibile distribuire, vedere il file 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'
  }
}

Suggerimento

Quando si usano pipeline di distribuzione automatizzate, a volte può essere difficile determinare come eseguire il bootstrap dei segreti dell'insieme di credenziali delle chiavi per le distribuzioni. Ad esempio, se è stata fornita una chiave API da usare durante la comunicazione con un'API esterna, è necessario aggiungere il segreto a un insieme di credenziali prima che possa essere usato nelle distribuzioni.

Quando si usano segreti provenienti da terze parti, potrebbe essere necessario aggiungerli manualmente all'insieme di credenziali e quindi è possibile fare riferimento al segreto per tutti gli usi successivi.

Usare un insieme di credenziali delle chiavi con moduli

Quando si usano moduli Bicep, è possibile fornire parametri sicuri usando la getSecret funzione .

È anche possibile fare riferimento a un insieme di credenziali delle chiavi definito in un altro gruppo di risorse usando le existing parole chiave e scope . Nell'esempio seguente il file Bicep viene distribuito in un gruppo di risorse denominato Rete. Il valore per il parametro del modulo mySecret è definito in un insieme di credenziali delle chiavi denominato contosonetworkingsecrets che si trova nel gruppo di risorse Segreti :

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

Usare un insieme di credenziali delle chiavi in un file con estensione bicepparam

Quando si usa il .bicepparam formato di file, è possibile fornire valori sicuri ai parametri usando la getSecret funzione .

Fare riferimento all'insieme di credenziali delle chiavi specificando l'ID sottoscrizione, il nome del gruppo di risorse e il nome dell'insieme di credenziali delle chiavi. È possibile ottenere il valore del segreto specificando il nome del segreto. Facoltativamente, è possibile specificare la versione del segreto. Se non si specifica la versione privata, viene usata la versione più recente.

using './main.bicep'

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

Usare i segreti nelle pipeline

Quando si distribuiscono le risorse di Azure usando una pipeline, è necessario occuparsi di gestire i segreti in modo appropriato.

  • Evitare di archiviare segreti nel repository di codice. Ad esempio, non aggiungere segreti ai file di parametri o ai file YAML di definizione della pipeline.
  • In GitHub Actions usare i segreti crittografati per archiviare i dati protetti. Usare l'analisi dei segreti per rilevare eventuali commit accidentali dei segreti.
  • In Azure Pipelines usare le variabili segrete per archiviare dati sicuri.