Freigeben über


Verwalten von Geheimnissen mit Bicep

Bereitstellungen erfordern häufig, dass Geheimnisse gespeichert und in der gesamten Azure-Umgebung sicher verteilt werden. Bicep und Azure bieten zahlreiche Funktionen, die Ihnen bei der Verwaltung von Geheimnissen in ihrer Bereitstellung der virtuellen Maschine helfen.

Vermeiden Sie Geheimnisse, wo Sie können

In vielen Fällen ist es möglich, die Verwendung von Geheimnissen komplett zu vermeiden. Viele Azure-Ressourcen unterstützen verwaltete Identitäten, die es ihnen ermöglichen, sich zu authentifizieren und berechtigt zu sein, auf andere Ressourcen in Azure zu zugreifen, ohne Anmeldeinformationen verwenden oder verwalten zu müssen. Darüber hinaus können einige Azure-Dienste https-Zertifikate automatisch generieren, was die Verwendung von Zertifikaten und privaten Schlüsseln erspart. Verwenden Sie wo möglich verwaltete Identitäten und vom Dienst verwaltete Zertifikate.

Nutzen Sie sichere Parameter

Wenn Sie Geheimnisse Ihrer Bicep-Bereitstellungen als Parameter zur Verfügung stellen müssen, verwenden Sie den @secure() Decorator. Wenn Sie einen Parameter als sicher markieren, verhindert Azure Resource Manager die Protokollierung oder Anzeige des Werts im Azure-Portal, in Azure CLI oder Azure PowerShell.

Vermeiden von Geheimnis-Ausgaben

Verwenden Sie keine Bicep-Ausgaben für sichere Daten. Ausgaben werden im Bereitstellungsverlauf protokolliert und jeder Benutzer mit Zugriff auf die Bereitstellung kann die Werte der Ausgaben einer Bereitstellung ansehen.

Wenn Sie ein Geheimes in einer Bicep-Bereitstellung generieren und für die aufrufende Funktion oder andere Ressourcen verfügbar machen müssen, sollten Sie einen der folgenden Ansätze in Betracht ziehen.

Dynamisches Abrufen von Geheimnissen

Manchmal müssen Sie auf einen Geheimnis einer Ressource zugreifen, um eine andere Ressource zu konfigurieren.

Zum Beispiel haben Sie möglicherweise in einer anderen Bereitstellung ein Speicherkonto erstellt und müssen auf den Primärschlüssel zugreifen, um eine Azure Functions-App zu konfigurieren. Sie können das existing Schlüsselwort verwenden, um einen stark typierten Verweis auf das vorab erstellte Speicherkonto zu erhalten, und dann die listKeys()-Methode des Speicherkontos verwenden, um eine Verbindungszeichenfolge mit dem Primärschlüssel zu erstellen:

Das folgende Beispiel ist Teil eines umfassenderen Beispiels. Eine Bicep-Datei, die Sie bereitstellen können, finden Sie in der vollständigen Datei.

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

Bei diesem Ansatz vermeiden Sie die Weitergabe von Geheimnissen in oder aus Ihrer Bicep-Datei.

Sie können diese Methode auch verwenden, um geheime Daten in einem Schlüsseltresor zu speichern.

Verwenden des Key Vaults

Azure Key Vault ist zum Speichern und Verwalten sicherer Daten konzipiert. Verwenden Sie einen Schlüsseltresor um Ihre geheimen Daten, Zertifikate, Schlüssel und andere Daten zu verwalten, die geschützt und geteilt werden müssen.

Sie können Tresore und Geheimnisse mithilfe von Bicep erstellen und verwalten. Definieren Sie Ihre Tresore, indem Sie eine Ressource mit dem Typ Microsoft.KeyVault/vaults erstellen.

Wenn Sie einen Tresor erstellen, müssen Sie bestimmen, wer und was auf die darin enthaltenen Daten zugreifen kann. Wenn Sie die Geheimnisse des Tresors aus einer Bicep-Datei lesen möchten, legen Sie die Eigenschaft enabledForTemplateDeployment auf true fest.

Hinzufügen von Geheimnissen zu einem Schlüsseltresor

Geheimnisse sind eine untergeordnete Ressource und können mit dem Typ erstellt werden Microsoft.KeyVault/vaults/secrets. Das folgende Beispiel zeigt, wie ein Tresor und ein Geheimnis erstellt wird:

Das folgende Beispiel ist Teil eines umfassenderen Beispiels. Eine Bicep-Datei, die Sie bereitstellen können, finden Sie in der vollständigen Datei.

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

Tipp

Wenn Sie automatisierte Bereitstellungspipelines verwenden, kann es manchmal schwierig sein festzustellen, wie Sie wichtige Tresor-Geheimnisse für Ihre Bereitstellungen bootstrapen. Wenn Ihnen beispielsweise ein API-Schlüssel zur Kommunikation mit einer externen API zur Verfügung gestellt wurde, muss der geheime Schlüssel einem Tresor hinzugefügt werden, bevor er in Ihren Bereitstellungen verwendet werden kann.

Wenn Sie mit Geheimnissen arbeiten, die von einem Drittanbieter stammen, müssen Sie sie möglicherweise manuell zu Ihrem Tresor hinzufügen, und dann können Sie für alle nachfolgenden Verwendungen auf das Geheimnis verweisen.

Verwenden eines Schlüsseltresor mit Modulen

Wenn Sie Bicep-Module verwenden, können Sie mithilfe der getSecret Funktion sichere Parameter bereitstellen.

Sie können auch auf einen Schlüsseltresor verweisen, der in einer anderen Ressourcengruppe definiert ist, indem Sie die Schlüsselwörter existing und scope zusammen verwenden. Im folgenden Beispiel wird die Bicep-Datei bereitgestellt für eine Ressourcengruppe mit dem Namen Netzwerk. Der Wert des Modul Parameters mySecret wird definiert in einem Schlüsseltresor namens contosonetworkingsecrets, der sich in der Ressourcengruppe Geheimnisse befindet:

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

Verwenden eines Schlüsseltresors in einer .bicepparam-Datei

Wenn Sie das Dateiformat .bicepparam verwenden, können Sie mithilfe der getSecret-Funktion sichere Werte für Parameter angeben.

Verweisen Sie auf den Schlüsseltresor, indem Sie die Abonnement-ID, den Ressourcengruppennamen und den Namen des Schlüsseltresors angeben. Sie können den Wert des Geheimnisses abrufen, indem Sie den Geheimnisnamen angeben. Optional können Sie auch die Geheimnisversion angeben. Wenn Sie die Geheimnisversion nicht angeben, wird die neueste Version verwendet.

using './main.bicep'

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

Arbeiten mit Geheimnissen in Pipelines

Wenn Sie Ihre Azure-Ressourcen mithilfe einer Pipeline bereitstellen, müssen Sie sich um die angemessene Behandlung Ihrer geheimen Daten kümmern.

  • Speichern Sie keine Geheimnisse in Ihrem Coderepository. Fügen Sie z. B. keine Geheimnisse zu Parameterdateien oder YAML-Dateien für die Pipelinedefinition hinzu.
  • In GitHub Actions verwenden Sie Verschlüsselte Geheimnisse, um sichere Daten zu speichern. Verwenden Sie Geheimnis Scan, um versehentliche Commits von Geheimnissen zu erkennen.
  • Verwenden Sie in Azure Pipelines Geheimnis Variablen, um sichere Daten zu speichern.