Continuous Delivery mit Azure Pipelines

Verwenden Sie Azure Pipelines für automatisches Bereitstellen in Azure Functions. Mit Azure Pipelines können Sie mithilfe von Azure DevOps mit Continuous Integration (CI) und Continuous Delivery (CD) Lösungen erstellen, testen und bereitstellen.

YAML-Pipelines werden mithilfe einer YAML-Datei in Ihrem Repository definiert. Ein Schritt ist der kleinste Baustein einer Pipeline und kann ein Skript oder ein Task (vorgefertigtes Skript) sein. Erfahren Sie mehr über die wichtigsten Konzepte und Komponenten einer Pipeline.

Sie verwenden den AzureFunctionApp-Task, um eine Bereitstellung in Azure Functions vorzunehmen. Es gibt jetzt zwei Versionen des AzureFunctionApp-Tasks (AzureFunctionApp@1 und AzureFunctionApp@2). AzureFunctionApp@2 enthält verbesserte Validierungsunterstützung, die es weniger wahrscheinlich macht, dass Pipelines aufgrund von Fehlern fehlschlagen.

Wählen Sie oben im Artikel Ihre Taskversion aus. YAML-Pipelines sind für Azure DevOps 2019 und früher nicht verfügbar.

Hinweis

Die AzureFunctionApp@2 wird dringend empfohlen. Die Bereitstellung in einer App im Flex-Verbrauchsplan wird nur in Version 2 unterstützt.

Voraussetzungen

Erstellen der App

  1. Melden Sie sich bei Ihrer Azure DevOps-Organisation an, und navigieren Sie zu Ihrem Projekt.
  2. Navigieren Sie in Ihrem Projekt zur Seite Pipelines. Wählen Sie dann Neue Pipeline aus.
  3. Wählen Sie eine der folgenden Optionen für Wo befindet sich Ihr Code?:
    • GitHub:Möglicherweise werden Sie zu GitHub weitergeleitet, um sich anzumelden. Geben Sie in diesem Fall Ihre Anmeldeinformationen für GitHub ein. Wenn dies Ihre erste Verbindung mit GitHub ist, führt der Assistent Sie auch durch den Prozess der Verbindung von DevOps mit Ihren GitHub-Konten.
    • Azure Repos Git: Sie können sofort ein Repository in Ihrem aktuellen DevOps-Projekt auswählen.
  4. Wenn die Liste der Repositorys angezeigt wird, wählen Sie Ihr Beispiel-App-Repository aus.
  5. Azure Pipelines analysiert Ihr Repository und stellt in Pipeline konfigurieren eine Liste potenzieller Vorlagen bereit. Wählen Sie die entsprechende Funktions-App-Vorlage für Ihre Sprache aus. Wenn die richtige Vorlage nicht angezeigt wird, wählen Sie Mehr anzeigen aus.
  6. Klicken Sie auf Speichern und ausführen, wählen Sie Direkten Commit an Mainbranch ausführen aus, und klicken Sie dann erneut auf Speichern und ausführen.
  7. Eine neue Ausführung wird gestartet. Warten Sie, bis die Ausführung beendet ist.

Beispiel-YAML-Buildpipelines

Die folgenden sprachspezifischen Pipelines können zum Erstellen von Apps verwendet werden.

Sie können das folgende Beispiel verwenden, um eine YAML-Datei zum Erstellen einer .NET-App zu erstellen.

Wenn beim Erstellen Ihrer App Fehler angezeigt werden, überprüfen Sie, ob die verwendete .NET-Version mit Ihrer Azure Functions-Version übereinstimmt. Weitere Informationen finden Sie unter Einstellen von Runtimeversionen von Azure Functions als Ziel.

pool:
  vmImage: 'windows-latest'
steps:
- script: |
    dotnet restore
    dotnet build --configuration Release
- task: DotNetCoreCLI@2
  inputs:
    command: publish
    arguments: '--configuration Release --output publish_output'
    projects: '*.csproj'
    publishWebProjects: false
    modifyOutputPath: false
    zipAfterPublish: false
- task: ArchiveFiles@2
  displayName: "Archive files"
  inputs:
    rootFolderOrFile: "$(System.DefaultWorkingDirectory)/publish_output"
    includeRootFolder: false
    archiveFile: "$(System.DefaultWorkingDirectory)/build$(Build.BuildId).zip"
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(System.DefaultWorkingDirectory)/build$(Build.BuildId).zip'
    artifactName: 'drop'

Bereitstellen Ihrer App

Ihre Bereitstellung erfolgt mit der Aufgabe Azure-Funktions-App-Bereitstellung. Diese Aufgabe erfordert eine Azure-Dienstverbindung als Eingabe. Eine Azure-Dienstverbindung speichert die Anmeldeinformationen für die Verbindung von Azure Pipelines mit Azure.

Fügen Sie zum Bereitstellen in Azure Functions den folgenden Codeausschnitt am Ende Ihrer azure-pipelines.yml-Datei hinzu. Der Standardwert appType ist „Windows“. Sie können „Linux“ angeben, indem Sie appType auf functionAppLinux festlegen. Die Bereitstellung in einer Flex-Verbrauchs-App wird mit @v1 der AzureFunctionApp-Aufgabe nicht unterstützt.

trigger:
- main

variables:
  # Azure service connection established during pipeline creation
  azureSubscription: <Name of your Azure subscription>
  appName: <Name of the function app>
  # Agent VM image name
  vmImageName: 'ubuntu-latest'

- task: AzureFunctionApp@1 # Add this at the end of your file
  inputs:
    azureSubscription: <Azure service connection>
    appType: functionAppLinux # default is functionApp
    appName: $(appName)
    package: $(System.ArtifactsDirectory)/**/*.zip
    #Uncomment the next lines to deploy to a deployment slot
    #Note that deployment slots is not supported for Linux Dynamic SKU
    #deployToSlotOrASE: true
    #resourceGroupName: '<Resource Group Name>'
    #slotName: '<Slot name>'

Im Codeausschnitt wird davon ausgegangen, dass die Buildschritte in Ihrer YAML-Datei das ZIP-Archiv im $(System.ArtifactsDirectory)-Ordner auf Ihrem Agent erzeugen.

Bereitstellen eines Containers

Sie können Ihren Code nach jedem erfolgreichen Build automatisch als containerisierte Funktions-App bereitstellen. Weitere Informationen zu Containern finden Sie unter Arbeiten mit Containern und Azure Functions.

Die einfachste Möglichkeit zum Bereitstellen in einem Container ist die Verwendung der Aufgabe Azure-Funktions-App-in-Container-Bereitstellung.

Fügen Sie zum Bereitstellen den folgenden Codeausschnitt am Ende Ihrer YAML-Datei hinzu:

trigger:
- main

variables:
  # Container registry service connection established during pipeline creation
  dockerRegistryServiceConnection: <Docker registry service connection>
  imageRepository: <Name of your image repository>
  containerRegistry: <Name of the Azure container registry>
  dockerfilePath: '$(Build.SourcesDirectory)/Dockerfile'
  tag: '$(Build.BuildId)'

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

- task: AzureFunctionAppContainer@1 # Add this at the end of your file
  inputs:
    azureSubscription: '<Azure service connection>'
    appName: '<Name of the function app>'
    imageName: $(containerRegistry)/$(imageRepository):$(tag)

Mit dem Codeausschnitt wird das Docker-Image an Ihre Azure Container Registry gepusht. Die Aufgabe Azure-Funktions-App-in-Container-Bereitstellung pullt das entsprechende Docker-Image, das BuildId entspricht, aus dem angegebenen Repository und stellt das Image dann bereit.

Ein vollständiges End-to-End-Pipelinebeispiel, einschließlich der Erstellung des Containers und der Veröffentlichung in der Containerregistrierung, finden Sie in diesem Azure Pipelines-Containerbereitstellungsbeispiel.

Bereitstellen in einem Slot

Sie können Ihre Funktions-App so konfigurieren, dass sie mehrere Slots hat. Mit Slots können Sie Ihre App sicher bereitstellen und testen, bevor Sie sie Ihren Kunden zur Verfügung stellen.

Der folgende YAML-Codeausschnitt zeigt, wie in einem Stagingslot bereitgestellt und dann zu einem Produktionsslot getauscht wird:

- task: AzureFunctionApp@1
  inputs:
    azureSubscription: <Azure service connection>
    appType: functionAppLinux
    appName: <Name of the Function app>
    package: $(System.ArtifactsDirectory)/**/*.zip
    deployToSlotOrASE: true
    resourceGroupName: <Name of the resource group>
    slotName: staging

- task: AzureAppServiceManage@0
  inputs:
    azureSubscription: <Azure service connection>
    WebAppName: <name of the Function app>
    ResourceGroupName: <name of resource group>
    SourceSlot: staging
    SwapWithProduction: true

Erstellen einer Pipeline mit Azure CLI

Verwenden Sie den Befehl az functionapp devops-pipeline create, um in Azure eine Buildpipeline zu erstellen. Die Buildpipeline wird erstellt, um alle Codeänderungen zu erstellen und freizugeben, die in Ihrem Repository vorgenommen werden. Der Befehl generiert eine neue YAML-Datei, die die Build- und Releasepipeline definiert und dann an Ihr Repository committet. Die Voraussetzungen für diesen Befehl hängen vom Speicherort des Codes ab.

  • Code in GitHub:

    • Sie müssen die Berechtigung Schreiben für Ihr Abonnement besitzen.

    • Sie müssen der Projektadministrator in Azure DevOps sein.

    • Sie müssen die Berechtigung zum Erstellen eines persönlichen GitHub-Zugriffstokens (PAT) mit ausreichenden Berechtigungen besitzen. Weitere Informationen finden Sie unter GitHub-PAT-Berechtigungsanforderungen.

    • Sie müssen die Berechtigung zum Committen des Hauptbranches in Ihrem GitHub-Repository besitzen, um die automatisch generierte YAML-Datei zu committen.

  • Code in Azure Repos:

    • Sie müssen die Berechtigung Schreiben für Ihr Abonnement besitzen.

    • Sie müssen der Projektadministrator in Azure DevOps sein.

Erstellen der App

  1. Melden Sie sich bei Ihrer Azure DevOps-Organisation an, und navigieren Sie zu Ihrem Projekt.
  2. Navigieren Sie in Ihrem Projekt zur Seite Pipelines. Wählen Sie dann die Aktion zum Erstellen einer neuen Pipeline aus.
  3. Führen Sie die Schritte des Assistenten aus. Wählen Sie zuerst GitHub als Speicherort Ihres Quellcodes aus.
  4. Möglicherweise werden Sie zu GitHub weitergeleitet, um sich anzumelden. Geben Sie in diesem Fall Ihre Anmeldeinformationen für GitHub ein.
  5. Wenn die Liste der Repositorys angezeigt wird, wählen Sie Ihr Beispiel-App-Repository aus.
  6. Azure Pipelines analysiert Ihr Repository und empfiehlt eine Vorlage. Klicken Sie auf Speichern und ausführen, wählen Sie Direkten Commit an Mainbranch ausführen aus, und klicken Sie dann erneut auf Speichern und ausführen.
  7. Eine neue Ausführung wird gestartet. Warten Sie, bis die Ausführung beendet ist.

Beispiel-YAML-Buildpipelines

Die folgenden sprachspezifischen Pipelines können zum Erstellen von Apps verwendet werden.

Sie können die YAML-Datei zum Erstellen einer .NET-App mithilfe des folgenden Beispiels erstellen:

pool:
  vmImage: 'windows-latest'
steps:
- script: |
    dotnet restore
    dotnet build --configuration Release
- task: DotNetCoreCLI@2
  inputs:
    command: publish
    arguments: '--configuration Release --output publish_output'
    projects: '*.csproj'
    publishWebProjects: false
    modifyOutputPath: false
    zipAfterPublish: false
- task: ArchiveFiles@2
  displayName: "Archive files"
  inputs:
    rootFolderOrFile: "$(System.DefaultWorkingDirectory)/publish_output"
    includeRootFolder: false
    archiveFile: "$(System.DefaultWorkingDirectory)/build$(Build.BuildId).zip"
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(System.DefaultWorkingDirectory)/build$(Build.BuildId).zip'
    artifactName: 'drop'

Bereitstellen Ihrer App

Ihre Bereitstellung erfolgt mit dem Task Azure-Funktions-App-Bereitstellung v2. Diese Aufgabe erfordert eine Azure-Dienstverbindung als Eingabe. Eine Azure-Dienstverbindung speichert die Anmeldeinformationen für die Verbindung von Azure Pipelines mit Azure. Sie sollten eine Verbindung erstellen, die den Workload-Identitätsverbund verwendet.

Die v2-Version des Tasks umfasst Unterstützung für neuere Anwendungsstapel für .NET, Python und Node. Die Aufgabe umfasst Prüfungen der Netzwerkvorabbereitstellung. Wenn Probleme bei der Vorabbereitstellung auftreten, wird die Bereitstellung beendet.

Fügen Sie zum Bereitstellen in Azure Functions den folgenden Codeausschnitt am Ende Ihrer azure-pipelines.yml-Datei hinzu. Der Standardwert appType ist „Windows“. Sie können „Linux“ angeben, indem Sie appType auf functionAppLinux festlegen. Für die Bereitstellung in einer Flex-Verbrauchs-App müssen Sie sowohl appType: functionAppLinux als auch isFlexConsumption: true festlegen.

trigger:
- main

variables:
  # Azure service connection established during pipeline creation
  azureSubscription: <SUBSCRIPTION_NAME>
  appName: <APP_NAME>
  # Agent VM image name
  vmImageName: 'windows-latest'

- task: AzureFunctionApp@2 # Add this at the end of your file
  inputs:
    azureSubscription: <AZURE_SERVICE_CONNECTION>
    appType: functionApp # this specifies a Windows-based function app
    appName: $(appName)
    package: $(System.ArtifactsDirectory)/**/*.zip
    deploymentMethod: 'auto' # 'auto' | 'zipDeploy' | 'runFromPackage'. Required. Deployment method. Default: auto.
    #Uncomment the next lines to deploy to a deployment slot
    #Note that deployment slots is not supported for Linux Dynamic SKU
    #deployToSlotOrASE: true
    #resourceGroupName: '<RESOURCE_GROUP>'
    #slotName: '<SLOT_NAME>'

Nächste Schritte