Continuous Integration und Continuous Deployment (CI/CD) gehören in vielen Unternehmen bereits zum Standard. Dennoch suchen Entwicklungsteams ständig nach Wegen, um noch effizienter zu arbeiten und sicherzustellen, dass der Code in einer realitätsnahen Umgebung getestet wird, bevor er live geht. Die Möglichkeit, Pull Requests (PRs) direkt in einer „Live“-ähnlichen Umgebung zu testen, kann die Codequalität erheblich verbessern und Fehler frühzeitig erkennen lassen.
Azure Deployment Slots bieten hierfür eine elegante Lösung, indem sie isolierte Testumgebungen schaffen. In Kombination mit GitHub Actions kannst du PRs automatisch in diesen Slots deployen und testen, bevor sie in den "Main"-branch gemerged werden. In diesem Artikel zeige ich, wie du PR-spezifische Deployment Slots einrichtest und GitHub Actions für diese Automatisierung nutzt.
Was sind Azure Deployment Slots?
Azure App Service Deployment Slots sind separate Bereitstellungsumgebungen innerhalb einer App Service-Instanz. Sie ermöglichen es Ihnen, mehrere Versionen Ihrer Anwendung gleichzeitig zu hosten. Hauptvorteile:
- Zero-Downtime-Deployments: Neue Versionen können in einem Slot bereitgestellt und getestet werden, bevor sie live geschaltet werden.
- Einfaches Rollback: Bei Problemen kann einfach zum vorherigen Slot zurückgewechselt werden.
- Isolierte Umgebungen: Jeder Slot hat seine eigenen Konfigurationen und Connection-Strings.
GitHub Actions und Pull Requests
GitHub Actions ist ein Tool zur Automatisierung von Software-Workflows direkt in Ihrem GitHub-Repository. Es ermöglicht das Erstellen von CI/CD-Pipelines, die auf verschiedene Ereignisse wie Pushes, Pull Requests oder zeitbasierte Trigger reagieren können. In Kombination mit Azure können Sie so Ihren gesamten Entwicklungs- und Deployment-Prozess automatisieren.
Die Idee: Branch-spezifische Deployment Slots
Stellen Sie sich vor, jeder Pull Request erstellt automatisch einen eigenen Deployment Slot. Dies ermöglicht:
- Live-ähnliches Testing: Prüfen Sie Änderungen in einer Umgebung, die der Produktion nahekommt.
- Frühes Erkennen von Fehlern: Durch Tests im Deployment Slot können Probleme erkannt werden, bevor sie in den Hauptbranch gelangen.
- Automatisierung: Durch Integration mit GitHub Actions werden Slots automatisch erstellt und entfernt.
Schritt-für-Schritt-Anleitung
1. Workflow für Pull Requests einrichten
Um automatisch Deployment Slots für jeden Pull Request zu erstellen und zu verwalten, richten wir einen neuen GitHub Actions Workflow ein, der auf Pull Request-Ereignisse reagiert.
- Ordnerstruktur: Legen Sie im Root-Verzeichnis Ihres Repositories einen Ordner
.github/workflows
an, falls dieser nicht bereits existiert. - Workflow-Datei erstellen: Erstellen Sie eine neue Datei namens
pull_request_deployment.yml
in diesem Ordner. - Workflow konfigurieren: Nutzen Sie den folgenden YAML-Code, der Ihre bestehende Pipeline erweitert, um Deployment Slots für PRs zu verwalten.
1name: PR Deployment CI/CD
2
3on:
4 pull_request:
5 types: [opened, synchronize, reopened, closed]
6
7jobs:
8 build:
9 if: github.event.action != 'closed'
10 runs-on: windows-latest
11
12 steps:
13 - uses: actions/checkout@v4
14
15 - name: Set up .NET Core
16 uses: actions/setup-dotnet@v4
17 with:
18 dotnet-version: '8.x'
19
20 - name: Build with dotnet
21 run: dotnet build src/WebApplication/WebApplication.csproj --configuration Release
22
23 - name: dotnet publish
24 run: dotnet publish src/WebApplication/WebApplication.csproj -c Release -o ./deploy
25
26 - name: Upload artifact for deployment job
27 uses: actions/upload-artifact@v4
28 with:
29 name: .net-app
30 path: ./deploy
31
32 deploy:
33 if: github.event.action != 'closed'
34 runs-on: windows-latest
35 needs: build
36 environment:
37 name: 'PR-slot-deployment'
38 url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
39 permissions:
40 id-token: write # This is required for requesting the JWT
41
42 steps:
43 - name: Download artifact from build job
44 uses: actions/download-artifact@v4
45 with:
46 name: .net-app
47
48 - name: Login to Azure
49 uses: azure/login@v2
50 with:
51 client-id: ${{ secrets.AZURE_CLIENT_ID }}
52 client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
53 tenant-id: ${{ secrets.AZURE_TENANT_ID }}
54 subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
55
56 - name: Create Deployment Slot
57 run: |
58 $SLOT_NAME="pr-${{ github.event.number }}"
59 az webapp deployment slot create --name prdeploymentwebapp --resource-group prdeployment --slot $SLOT_NAME
60
61 - name: Deploy to Azure Web App
62 id: deploy-to-webapp
63 uses: azure/webapps-deploy@v3
64 with:
65 app-name: 'prdeploymentwebapp'
66 slot-name: 'pr-${{ github.event.number }}'
67 package: .
68
69 cleanup:
70 if: github.event.action == 'closed'
71 runs-on: windows-latest
72 environment:
73 name: 'PR-slot-deployment'
74 url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
75 permissions:
76 id-token: write # This is required for requesting the JWT
77
78 steps:
79 - name: Login to Azure
80 uses: azure/login@v2
81 with:
82 client-id: ${{ secrets.AZURE_CLIENT_ID }}
83 client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
84 tenant-id: ${{ secrets.AZURE_TENANT_ID }}
85 subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
86
87 - name: Delete Deployment Slot
88 run: |
89 $SLOT_NAME="pr-${{ github.event.number }}"
90 az webapp deployment slot delete --name prdeploymentwebapp --resource-group prdeployment --slot $SLOT_NAME
Erklärung:
- Trigger: Der Workflow wird bei Pull Request-Ereignissen wie
opened
,synchronize
,reopened
undclosed
ausgelöst. - Build Job: Baut und veröffentlicht die Anwendung, lädt das Artefakt für den Deploy-Job hoch.
- Deploy Job: Erstellt einen Deployment Slot mit dem Namen
pr-<PR-Nummer>
, deployt die Anwendung in diesen Slot und stellt die URL der Live-Umgebung bereit. - Cleanup Job: Wird nur ausgelöst, wenn der Pull Request geschlossen wird (gemerged oder abgelehnt). Löscht den entsprechenden Deployment Slot.
2. Pull Request erstellen
Die Pipeline wird automatisiert starten, sobald der Pull Request erstellt wurde.
3. Tests in der "Live"-Umgebung durchführen
Nachdem die Anwendung in den Deployment Slot deployt wurde, können Sie sowohl manuelle als auch automatisierte Tests in dieser Umgebung durchführen. Die URL des Slots lautet in der Regel:
https://prdeploymentwebapp-pr-12.azurewebsites.net
Manuelle Tests:
Öffnen Sie die obige URL in Ihrem Browser und führen Sie die notwendigen Tests durch.
4. Clean up der Deployment slots
Nach dem Schließen eines Pull Requests, wird der Slot automatisch entfernt. Dadurch wird sichergestellt, dass keine Altlasten unnötig lange verfügbar bleiben.
Best Practices und Fallstricke
Anzahl der Deployment Slots
- Kostenkontrolle: Jeder Slot verbraucht Ressourcen. Begrenzen Sie die Anzahl der gleichzeitigen Slots, insbesondere in großen Projekten mit vielen parallelen Pull Requests.
- Aufräumen: Stellen Sie sicher, dass temporäre Slots nach Gebrauch gelöscht werden, um unnötige Ressourcen zu vermeiden.
Umgang mit vielen Pull Requests
- Limits in Azure: Azure hat Grenzwerte für die Anzahl der Slots pro App Service Plan (Standardmäßig bis zu 20 Slots). Planen Sie entsprechend, um Engpässe zu vermeiden.
- Skalierung: Bei hohem PR-Aufkommen könnten Ressourcen knapp werden. Überlegen Sie, den App Service Plan zu skalieren oder automatisierte Slot-Löschungen zu optimieren.
Optimierung des Workflows
- Parallele Jobs: Nutzen Sie die Parallelität von GitHub Actions, um Workflows zu beschleunigen.
- Schnelle Bereitstellungen: Minimieren Sie die Anzahl der Schritte und optimieren Sie die Build-Prozesse, um die Bereitstellungszeiten zu verkürzen.
- Automatisierte Tests: Durch die automatisierte Bereitstellung der Anwendung können ebenfalls E2E-Tests mit z.B. Cypress durchgeführt werden.
Rollback-Strategien
- Automatisches Rollback: Implementieren Sie Mechanismen, um bei fehlschlagenden Deployments automatisch zum vorherigen Slot zurückzuwechseln.
- Monitoring und Alerts: Überwachen Sie die Deployments und richten Sie Alerts ein, um schnell auf Probleme reagieren zu können.
Fazit
Mit diesen Anpassungen Ihrer GitHub Actions Pipeline nutzen Sie Azure Deployment Slots effektiv, um Pull Requests in isolierten, live-ähnlichen Umgebungen zu testen. Dies erhöht die Qualität Ihres Codes und reduziert das Risiko von Fehlern in der Produktionsumgebung erheblich.
Zusammenfassung der Anpassungen:
- PR-spezifische Slots: Jeder Pull Request erhält einen eigenen Deployment Slot, der nach Abschluss des PRs automatisch entfernt wird.
- Automatisierte Slot-Verwaltung: Erstellung und Löschung von Slots automatisiert durch GitHub Actions.
Diese Maßnahmen tragen dazu bei, den Deployment-Prozess zu optimieren, die Effizienz zu steigern und die Zuverlässigkeit Ihrer Anwendungen zu erhöhen.