Die Nordlicht Reisen GmbH liefert ihr Buchungsportal in drei Formen aus: die Schnittstelle als Container, ein kleines Verwaltungsportal als Paket für App Service und eine Azure-SQL-Datenbank, deren Schema sich mit jedem Release ändert. Bisher hat jemand die drei Teile von Hand in der richtigen Reihenfolge angestoßen. Sie sollen daraus eine Bereitstellung machen, die ein Team nachvollziehen kann: welcher Schritt für welche Form, in welcher Reihenfolge und mit welchen Bedingungen. Das sind die Fähigkeiten dieser Lektion: Anwendungen bereitstellen (Container, Binärdateien, Skripte) und Bereitstellung mit Datenbankaufgaben.
Vorwissen: Wie sich eine Pipeline ohne Geheimnis bei Azure anmeldet, steht in K3, Lektion 3.7.5; Freigaben, Revisionen und das Zurückrollen in K3, Lektion 3.7.6. Warum eine Migration mit der vorigen Version der App verträglich sein muss und wie man ein Schema in mehreren Schritten umbaut, zeigt K3, Lektion 3.6.2. Umgebungen, Prüfungen und Genehmigungen in YAML führt Lektion 4.7 aus, die Strategien (Blau-Grün, Canary) Lektion 4.8. Diese Lektion fragt nur: Welcher Baustein bringt welche Form von Anwendung nach Azure, und wo steht die Datenbank in der Reihenfolge?
Nicht gegen Azure oder GitHub ausgeführt; aus der Referenz von Microsoft: Alle Befehle, YAML-Dateien und Menüpfade dieser Lektion stammen aus Microsofts Dokumentation und sind in diesem Kurs nicht ausgeführt worden. Namen in spitzen Klammern sind Platzhalter, die Sie ersetzen.
Container bereitstellen
Ein Container wird in zwei getrennten Schritten bereitgestellt, und die Trennung ist der Kern des Entwurfs: bauen und ablegen (ein Image entsteht und liegt in einer Registry) und ausrollen (ein Dienst zieht genau dieses Image). Was zwischen beiden steht, ist der Name des Images, und der muss eindeutig sein.
Bauen und ablegen
In Azure Pipelines baut und schiebt die Aufgabe Docker@2 ein Image in eine Registry. So zeigt es Microsofts Vorlage für Azure Container Registry:
- task: Docker@2
displayName: Build and push an image to container registry
inputs:
command: buildAndPush
repository: $(imageRepository)
dockerfile: $(dockerfilePath)
containerRegistry: $(dockerRegistryServiceConnection)
tags: |
$(tag)
containerRegistry ist der Name einer Docker-Registry-Dienstverbindung; sie hält die Anmeldung zur Registry. Die Vorlage von Microsoft legt eine Verbindung auf Basis eines Dienstprinzipals an. Dienstverbindungen im Einzelnen behandelt Lektion 5.1.
In GitHub Actions baut docker/build-push-action das Image. Microsofts Beispiel für Container Apps benutzt die Commit-ID als Tag:
- name: Build and push Docker image to Azure Container Registry
uses: docker/build-push-action@v4
with:
push: true
tags: ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}/webfrontend:${{ github.sha }}
file: ${{ env.DOCKER_FILEPATH_WEBFRONTEND }}
Beide Quellen von Microsoft warnen in derselben Weise: Wenn Sie das Image in einem eigenen Schritt bauen, nehmen Sie ein eindeutiges Tag wie die Build-ID ($(Build.BuildId)) oder die Commit-ID, kein stabiles wie latest. Microsoft begründet es für Container Apps: Ein eindeutiges Tag sorgt dafür, dass zuverlässig neue Revisionen entstehen. Ein Tag, das immer gleich heißt, verschleiert außerdem, welcher Stand eigentlich läuft.
Ausrollen auf Azure Container Apps
Azure Container Apps (das verwaltete Containerhosting aus K3, Modul 3.7) hat für beide Welten einen eigenen Baustein. Er kann drei Dinge: aus einem Dockerfile bauen und ausrollen, aus Quellcode ohne Dockerfile bauen (unterstützt: .NET, Java, Node.js, PHP, Python) oder ein vorhandenes Image ausrollen.
Azure Pipelines (Aufgabe AzureContainerApps@1, ein vorhandenes Image ausrollen):
steps:
- task: AzureContainerApps@1
inputs:
azureSubscription: 'my-subscription-service-connection'
containerAppName: 'my-container-app'
resourceGroup: 'my-container-app-rg'
imageToDeploy: 'myregistry.azurecr.io/my-container-app:$(Build.BuildId)'
GitHub Actions (Aktion azure/container-apps-deploy-action) hat dieselben Eingaben: containerAppName, resourceGroup, imageToDeploy, dazu appSourcePath und acrName zum Bauen. Die Anmeldung kommt von azure/login davor.
Wichtig ist die Frage, wer sich bei der Registry anmeldet. Microsoft trennt zwei Richtungen:
- Hochladen (push): Aufgabe oder Aktion melden sich mit der Identität an, die Sie für Azure angegeben haben (Dienstverbindung,
azure/login). Fehlt dieser Identität die RolleAcrPush, geben Sie Administratordaten der Registry mitacrUsernameundacrPasswordan. - Herunterladen (pull): Die Container App selbst holt das Image. Microsoft empfiehlt eine verwaltete Identität der App mit der Rolle
AcrPullfür die Registry; die Alternative sind Administratordaten.
Microsofts Einrichtung dazu besteht aus drei Befehlen (Azure CLI):
az containerapp identity assign --name my-container-app --resource-group my-container-app-rg --system-assigned
az role assignment create --assignee <principal-id> --role AcrPull --scope <acr-resource-id>
az containerapp registry set --name my-container-app --resource-group my-container-app-rg --server <acr-name>.azurecr.io --identity system
Ausrollen auf App Service (benutzerdefinierter Container)
Für einen eigenen Container in Azure App Service benutzt Microsoft in GitHub Actions azure/webapps-deploy. Zwei Eingaben sind für Container erforderlich: app-name (der Name der App) und images (der vollständige Name des Images, etwa myregistry.azurecr.io/nginx:latest). Optional sind slot-name (ein vorhandener Slot statt der Produktion, Lektion 4.9) und startup-command. Zur Anmeldung empfiehlt Microsoft OpenID Connect. Eine Web-App für Container hat anders als eine normale Web-App keine Startseite, solange kein Container veröffentlicht ist.