Behandeln von Unterschieden zwischen Umgebungen mithilfe von Bicep-Parametern

Abgeschlossen

Sie haben bereits Informationen zu Bicep-Parametern erhalten. Sie helfen Ihnen, Werte anzugeben, die sich zwischen Bereitstellungen Ihrer Bicep-Dateien ändern können.

Parameter werden häufig verwendet, um die Unterschiede zwischen Ihren Umgebungen zu unterstützen. Beispielsweise möchten Sie in Ihren Nicht-Produktionsumgebungen häufig kostengünstige SKUs Ihrer Azure-Ressourcen bereitstellen. In der Produktion möchten Sie SKUs bereitstellen, die eine bessere Leistung aufweisen. Möglicherweise möchten Sie in jeder Umgebung unterschiedliche Namen für Ressourcen verwenden.

Wenn Sie Ihre Bicep-Datei bereitstellen, geben Sie Werte für jeden Parameter an. Es gibt mehrere Optionen, wie Sie die Werte für jeden Parameter aus Ihrer Pipeline angeben und wie Sie separate Werte für jede Umgebung angeben. In dieser Lerneinheit erfahren Sie mehr über die Ansätze zum Angeben von Bicep-Parameterwerten in einer Bereitstellungspipeline.

Parameterdateien

Eine Parameterdatei ist eine Datei im JSON-Format, die die Parameterwerte auflistet, die Sie für jede Umgebung verwenden möchten. Sie übermitteln die Parameterdatei an Azure Resource Manager, wenn Sie die Bereitstellung übermitteln.

Hier sehen Sie eine Beispielparameterdatei:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "reviewApiUrl": {
      "value": "https://sandbox.contoso.com/reviews"
    }
  }
}

Parameterdateien können zusammen mit Ihrer Bicep-Datei in Ihr Git-Repository übertragen werden. Sie können dann auf die Parameterdatei in Ihrer Pipelinevorlage verweisen, in der Sie die Bereitstellung ausführen.

Es empfiehlt sich, eine konsistente Umgebungsbenennungsstrategie für Parameterdateien einzurichten. Beispielsweise könnten Sie Ihre Parameterdateien parameters.ENVIRONMENT_NAME.json benennen, wie parameters.Production.json. Anschließend können Sie einen Pipelinevorlagenparameter verwenden, um automatisch die richtige Parameterdatei auszuwählen.

parameters: 
- name: environmentType
  type: string
- name: serviceConnectionName
  type: string
- name: resourceGroupName
  type: string

- stage: Deploy
  jobs:
  - deployment: DeployWebsite
    displayName: Deploy Website
    environment: Website
    strategy:
      runOnce:
        deploy:
          steps:
            - checkout: self
            - task: AzureCLI@2
              name: DeployBicepFile
              displayName: Deploy Bicep file
              inputs:
                azureSubscription: ${{parameters.serviceConnectionName}}
                scriptType: 'bash'
                scriptLocation: 'inlineScript'
                inlineScript: |
                  az deployment group create \
                    --resource-group ${{parameters.resourceGroupName}} \
                    --template-file deploy/main.bicep \
                    --parameters deploy/azuredeploy.parameters.${{parameters.environmentType}}.json

Wenn Sie Parameterdateien verwenden, müssen Ihre YAML-Pipelinedateien keine Liste von Parametern enthalten, die einzeln an Ihre Bereitstellungsschritte übergeben werden müssen. Dies ist hilfreich, wenn Sie über eine große Anzahl von Parametern verfügen.

Eine Parameterdatei hält die Parameterwerte in einer einzelnen JSON-Datei zusammen. Die Parameterdateien sind auch Teil Ihres Git-Repositorys, sodass sie auf die gleiche Weise wie der gesamte andere Code versioniert werden können.

Wichtig

Parameterdateien sollten nicht für sichere Werte verwendet werden. Es gibt keine Möglichkeit, die Werte der Geheimnisse in den Parameterdateien zu schützen, und Sie sollten niemals Geheimnisse in Ihr Git-Repository committen.

Pipelinevariablen

Mit Azure Pipelines können Sie Pipelinevariablen speichern, die für Werte nützlich sind, die sich zwischen Umgebungen unterscheiden können. Sie sind auch für Werte nützlich, die Sie nur einmal definieren und dann in der gesamten Pipeline wiederverwenden möchten. Azure Pipelines unterstützt mehrere Möglichkeiten zum Definieren von Variablen.

In einer YAML-Datei definierte Variablen

Sie können in einer YAML-Datei Variablen definieren und deren Werte festlegen. Dies ist nützlich, wenn Sie denselben Wert mehrmals wiederverwenden müssen. Wie Bicep-Parameterdateien eignen sich YAML-Dateien jedoch nicht für Geheimnisse.

In der Webschnittstelle definierte Variablen

Sie können Variablen mithilfe der Azure DevOps-Webschnittstelle definieren. Sie können die Variablenwerte jederzeit ändern, und die Pipeline liest die aktualisierten Werte bei der nächsten Ausführung.

Variablen, die über die Webschnittstelle definiert werden, können als Geheimnis markiert werden, wodurch Azure Pipelines angewiesen wird, zu versuchen, die Werte der Variablen in den Pipelineprotokollen auszublenden. Dies bedeutet, dass Sie Werte speichern können, die Ihre Bicep-Datei dann als Parameter mit dem Decorator @secure() akzeptiert.

Warnung

Azure Pipelines verschleiert standardmäßig Variablenwerte mit Geheimnissen in Pipelineprotokollen, trotzdem sollten Sie darüber hinaus bewährte Methoden befolgen. Ihre Pipelineschritte haben Zugriff auf alle Variablenwerte, einschließlich Geheimnissen. Wenn Ihre Pipeline einen Schritt enthält, bei dem eine sichere Variable nicht sicher verarbeitet wird, besteht die Möglichkeit, dass die Variable mit dem Geheimnis in den Pipelineprotokollen enthalten ist.

Variablengruppen

Sie können auch Variablengruppen definieren, bei denen es sich um Variablensätze handelt. Wie Variablen definieren Sie diese Gruppen mithilfe der Azure DevOps-Webschnittstelle. Sie können auch Variablengruppen verwenden, um Geheimnisse sicher zu speichern. Variablengruppen können sogar in mehreren Pipelines im gleichen Azure DevOps-Projekt wiederverwendet werden.

Im Gegensatz zu anderen Variablen müssen Sie eine Variablengruppe explizit in eine Pipeline importieren, indem Sie das Schlüsselwort group in einem variables-Abschnitt wie folgt verwenden:

variables:
- group: MyVariableGroup

Wenn Sie mit Pipelinevorlagen arbeiten, können Sie Ihre Variablengruppen benennen, sodass Sie sie problemlos mithilfe eines Vorlagenparameters laden können. Angenommen, Ihre Pipeline wird in zwei Umgebungen bereitgestellt, und Sie müssen einen Reihe von Variablen für jede Umgebung definieren. Sie können Ihre Variablengruppen mit den enthaltenen Umgebungsnamen wie folgt benennen:

Umgebungsname Variablengruppenname
Test ToyWebsiteTest
Bereitstellung ToyWebsiteProduction

In jeder dieser Variablengruppen fügen Sie Variablen mit den gleichen Namen, aber mit unterschiedlichen Werten für jede Umgebung hinzu.

Ihre Pipelinevorlagendatei verwendet das Makro {{ parameters.PARAMETER_NAME }}, um die richtige zu importierende Variablengruppe auszuwählen:

parameters: 
- name: environmentType
  type: string
  default: 'Test'

variables: 
- group: ToyWebsite${{ parameters.environmentType }}

Key Vault-Variablengruppen

Sie können Variablengruppen mit Azure Key Vault verknüpfen. Geheimnisse im Schlüsseltresor werden als Variablen in der Variablengruppe verfügbar gemacht. Die Geheimnisse können dann in Ihren Pipelines verwendet werden, als wären es normale Variablen.

Key Vault macht die Verwaltung Ihrer Geheimnisse sicherer. Außerdem können diese Werte von Ihrem Sicherheitsteam verwaltet werden, und der Zugriff auf Ihre Pipelines kann von den von ihm verwendeten Geheimnissen getrennt werden.

Zum Verknüpfen einer Variablengruppe mit einem Schlüsseltresor sind weitere Schritte erforderlich. Diese Schritte umfassen das Erstellen einer Dienstverbindung, die über die Berechtigung zum Lesen der Geheimnisse aus dem Schlüsseltresor verfügt. In der Zusammenfassungseinheit finden Sie einen Link zu mehr Details zum Konfigurieren von Key Vault-Variablengruppen.

Verwenden von Variablen in Ihrer Pipeline

Unabhängig davon, wie Sie eine Variable definieren, greifen Sie in Ihrer Pipeline mithilfe der $(VariableName)-Syntax auf ihren Wert zu. Wenn Sie beispielsweise eine Bicep-Bereitstellung ausführen, können Sie eine Variable verwenden, um den Wert eines Parameters anzugeben:

- stage: Deploy
  jobs:
  - deployment: DeployWebsite
    displayName: Deploy Website
    environment: Website
    strategy:
      runOnce:
        deploy:
          steps:
            - checkout: self
            - task: AzureCLI@2
              name: DeployBicepFile
              displayName: Deploy Bicep file
              inputs:
                azureSubscription: MyServiceConnection
                scriptType: 'bash'
                scriptLocation: 'inlineScript'
                inlineScript: |
                  az deployment group create \
                    --resource-group $(ResourceGroupName) \
                    --template-file deploy/main.bicep \
                    --parameters environmentType=$(EnvironmentType)

Was ist der beste Ansatz?

Sie haben verschiedene Möglichkeiten kennengelernt, um die Parameter zu behandeln, die Ihre Bicep-Datei für Ihre Bereitstellung benötigt. Es ist hilfreich zu verstehen, wann Sie welchen Ansatz verwenden können.

Vermeiden unnötiger Parameter

Parameter helfen Ihnen dabei, Ihre Bicep-Dateien wiederverwendbar zu machen, aber es ist einfach, zu viele Parameter zu definieren. Wenn Sie eine Bicep-Datei bereitstellen, müssen Sie einen Wert für jeden Parameter angeben. Bei komplexen Bereitstellungen für mehrere Umgebungen ist es schwierig, eine große Gruppe einzelner Parameterwerte zu verwalten.

Erwägen Sie, Parameter optional zu machen, wo dies möglich ist, und verwenden Sie Standardwerte, die für die meisten Umgebungen gelten. Sie können dann vermeiden, dass Ihre Pipelines Werte für die Parameter übergeben müssen.

Beachten Sie außerdem, dass Parameter häufig in Bicep verwendet werden, wenn Ressourcen eine Verbindung mit anderen Ressourcen herstellen müssen. Wenn Sie beispielsweise über eine Website verfügen, die eine Verbindung mit einem Speicherkonto herstellen muss, müssen Sie den Namen des Speicherkontos und den Zugriffsschlüssel angeben. Schlüssel sind sichere Werte. Berücksichtigen Sie jedoch diese anderen Ansätze, wenn Sie diese Kombination von Ressourcen bereitstellen:

  • Verwenden Sie die verwaltete Identität der Website, um auf das Speicherkonto zuzugreifen. Wenn Sie eine verwaltete Identität erstellen, generiert und verwaltet Azure automatisch die zugehörigen Anmeldeinformationen. Dieser Ansatz vereinfacht die Verbindungseinstellungen. Dies bedeutet auch, dass Sie keine Geheimnisse verarbeiten müssen, daher ist dies die sicherste Option.
  • Stellen Sie das Speicherkonto und die Website zusammen in derselben Bicep-Vorlage bereit. Verwenden Sie Bicep-Module, um Website- und Speicherressourcen zusammenzuhalten. Anschließend können Sie automatisch die Werte für den Speicherkontonamen und den Schlüssel im Bicep-Code suchen, anstatt Parameter zu übergeben.
  • Fügen Sie die Details des Speicherkontos einem Schlüsseltresor als Geheimnis hinzu. Der Websitecode lädt dann den Zugriffsschlüssel direkt aus dem Tresor. Dieser Ansatz vermeidet die Notwendigkeit, den Schlüssel in der Pipeline überhaupt zu verwalten.

Verwenden von Variablengruppen für kleine Parametersätze

Wenn Sie nur über wenige Parameter für Ihre Bicep-Dateien verfügen, erwägen Sie die Verwendung einer Variablengruppe. Sie können sowohl geheime als auch nicht geheime Werte in Variablengruppen speichern.

Verwenden von Parameterdateien für große Parametersätze

Wenn Sie über einen großen Parametersatz für Ihre Bicep-Dateien verfügen, sollten Sie Parameterdateien verwenden, um die nicht sicheren Werte für jede Umgebung zusammenzuhalten. Wenn Sie dann die Werte ändern müssen, können Sie eine Parameterdatei aktualisieren und die Änderung committen.

Dieser Ansatz vereinfacht Ihre Pipelineschritte, da Sie nicht explizit den Wert für jeden Parameter festlegen müssen.

Sicheres Speichern von Geheimnissen

Verwenden Sie einen geeigneten Prozess zum Speichern und Verarbeiten von Geheimnissen. Wenn Sie nur wenige Geheimnisse verwalten müssen, sind Azure Pipelines-Variablen und -Variablengruppen häufig gut geeignet. Möglicherweise haben Sie jedoch komplexere Anforderungen, z. B. eine große Anzahl von Geheimnissen, viele verschiedene Umgebungen oder Zugriffssteuerungseinschränkungen. In diesen Situationen sollten Sie die Geheimnisse für jede Umgebung in separaten Schlüsseltresoren speichern. Verwenden Sie Variablengruppen, um die Tresore mit Ihrer Pipeline zu verknüpfen.

Denken Sie bei sicheren Parametern daran, jeden Parameter explizit an Ihre Bereitstellungsschritte zu übergeben.

Kombinieren von Ansätzen

Es ist üblich, mehrere Ansätze zu kombinieren, um Ihre Parameter zu verarbeiten. Beispielsweise können Sie die meisten Ihrer Parameterwerte in Parameterdateien speichern und dann mithilfe einer Variablengruppe sichere Werte festlegen. Die Kombination wird im folgenden Beispiel veranschaulicht.

variables:
- group: MyVariableGroup # This group imports a parameter named MySecureParameter.

stages:

- stage: Deploy
  jobs:
  - deployment: DeployWebsite
    displayName: Deploy Website
    environment: Website
    strategy:
      runOnce:
        deploy:
          steps:
            - checkout: self
            - task: AzureCLI@2
              name: DeployBicepFile
              displayName: Deploy Bicep file
              inputs:
                azureSubscription: MyServiceConnection
                scriptType: 'bash'
                scriptLocation: 'inlineScript'
                inlineScript: |
                  az deployment group create \
                    --resource-group ${{parameters.resourceGroupName}} \
                    --template-file deploy/main.bicep \
                    --parameters deploy/azuredeploy.parameters.${{parameters.environmentName}}.json \
                                 mySecureParameter=$(MySecureParameter)

Es gibt spezielle Regeln dafür, wie Dienstverbindungsnamen angegeben werden können. Diese Regeln können sich darauf auswirken, wie Sie Namen in Pipelines verwenden, die in mehreren Umgebungen bereitgestellt werden. Sie können z. B. keine Variable verwenden, die in einer Variablengruppe definiert ist, um einen Dienstverbindungsnamen anzugeben. Sie können Pipelinevorlagenparameter verwenden, um den Namen der zu verwendenden Dienstverbindung anzugeben.