Azure DevOps

Continuous Delivery mit Azure Web App for Containers

Azure Web App for Containers machen es einfach, eine App in einem Container zu hosten und gleichzeitig die Annehmlichkeiten der Azure Web Apps zu nutzen. Um ein Image zu hosten, gibt man die Registry und das gewünschte Image und Tag im Deployment Center an. Als Registry kann entweder der Docker Hub, eine private Registry oder eine Azure Container Registry angegeben werden. In unserem Beispiel verwenden wir eine Azure Container Registry:

Azure Web App for Container Konfiguration

Wie in der offiziellen Dokumentation beschrieben, kann der Schalter “Continuous Deployment” genutzt werden, um das Image erneut zu ziehen, wenn eine aktualisierte Version verfügbar wird. Hierbei wird ein Webhook eingesetzt, den die Registry bei der erneuten Veröffentlichung aufruft, um den Pull anzustoßen. Im Fall einer Azure Container Registry wird der Webhook automatisch konfiguriert, wenn Continuous Deployment aktiviert wird; für eine andere Registry muss der Webhook dort integriert werden.

Auf diese Weise kann man bei Verwendung des latest Tags einfach und schnell sicherstellen, dass immer der letzte Stand auf der Webapp gehostet wird. Während dies in einfachen Szenarien sicherlich ein pragmatischer Weg ist, so stößt man bei komplexeren Anforderungen an die Grenzen:

  • Das Zurückkehren zu einem früheren Stand ist nur dann möglich, wenn dieser frühere Stand als latest gekennzeichnet wird. Durch den Webhook kann dann der erneute Pull ausgelöst werden.
  • Der Webhook wird direkt aufgerufen, wenn ein neues Image verfügbar wird. Wenn das Image in einem sequentiellen Prozess über mehrere Umgebungen deployed werden soll, um beispielsweise eine Freigabe einzuholen, bevor auf die Produktivumgebung deployed wird, so ist das in diesem Ansatz nur über die Vergabe geeigneter Tags möglich, weil alle Umgebungen gleichzeitig über den neuen Stand informiert werden.

Voraussetzungen

In diesem Beispiel gehen wir davon aus, dass das Image in einer Azure DevOps Pipeline erzeugt und in eine Registry gepushed wird. Hierbei wird es mit einigen Tags versehen, u.a. latest, aber auch der Build-Nummer. Letzteres dient als Aufhänger, um die passende Version zu erhalten.

Azure DevOps Release Pipelines

Besonders einfach ist die Umsetzung mit Azure DevOps Release Pipelines, die an dieser Stelle eine hervorragende Unterstützung bieten. Unter Artifacts fügen wir die oben angeführte Pipeline hinzu. Es geht uns hierbei jedoch nur darum, die Build-Nummer zu erhalten. Außerdem können wir auf diese Weise konfigurieren, dass die Release-Pipeline nach jedem erfolgreichen Build gestartet wird.

Azure DevOps Release Pipeline

Anschließend fügen wir die Stages der Release Pipeline hinzu. Im einfachsten Fall reicht an dieser Stelle je Stage ein einzelner Job mit einer einzigen Aufgabe (Task) vom Typ “Azure App Service deploy”:

Azure DevOps Release Pipeline Task

Die wesentlichen Konfigurationseinstellungen sind:

  • Connection Type: Azure Resource Manager
  • Subscription: Azure-Abonnement
  • App Service Type: Web App for Containers (Linux)
  • App Service Name: Name des App Service, auf den das Deployment erfolgen soll
  • Registry or Namespace: gibt die Registry an, von der wir das Image ziehen wollen
  • Image: Name des Image
  • Tag: hier können wir auf die Build-Nummer des Artefakts zurückgreifen, z.B. $(Release.Artifacts._myArtifactName.BuildNumber) (_myArtifactName steht für den Namen des Artefakts)

Für weitere Umgebungen fügen wir weitere Stages und den entsprechenden Task hinzu. Diese können wir beispielsweise mit einem Approval absichern, so dass das Deployment auf diese Umgebungen erst nach einem OK gestartet wird.

Nach dem Deployment ist die Web App for Containers so konfiguriert, dass sie das Image in der passenden Version übernimmt. Wollen wir später zu einem anderen Stand zurückkehren, ist dies einfach möglich, indem wir ein Release für einen früheren Build erstellen.

Fazit

Während das Anstoßen über den Webhook für einfache Szenarien ausreicht, ist bei mehrstufigen Release-Prozessen eine gute Kontrolle über das Deployment auf den einzelnen Umgebungen unabdingbar. Mit Hilfe von Azure DevOps Pipelines sind wir in der Lage, dies auf einfache Art und Weise zu erreichen.


YAML

Das äquivalente YAML des Deployment-Tasks für eine YAML-basierte Pipeline ist folgendes:

steps:
- task: AzureRmWebAppDeployment@4
  displayName: 'Azure App Service Deploy: ***'
  inputs:
    azureSubscription: '***'
    appType: webAppContainer
    WebAppName: '***'
    DockerNamespace: ***.azurecr.io
    DockerRepository: ***
    DockerImageTag: '$(Release.Artifacts.w***.BuildNumber)'
Continuous delivery Azure DevOps Azure Web App for Containers Azure DevOps Pipelines
Markus Wildgruber
Markus Wildgruber

Geschäftsführer

  • CloudArchitect
  • DeveloperCoach
  • DotNet
  • MongoDB
  • Angular