feat: add Azure AKS deployment infrastructure with Terraform
Build and Deploy to Synology NAS / test (push) Failing after 15m0s
Build and Deploy to Synology NAS / build (push) Has been cancelled
Build and Deploy to Synology NAS / deploy (push) Has been cancelled
Build and Deploy to Synology NAS / notify (push) Has been cancelled
Build and Deploy to Synology NAS / test (push) Failing after 15m0s
Build and Deploy to Synology NAS / build (push) Has been cancelled
Build and Deploy to Synology NAS / deploy (push) Has been cancelled
Build and Deploy to Synology NAS / notify (push) Has been cancelled
- Add Terraform configuration for AKS cluster deployment - Add Kubernetes manifests for Laravel app (deployment, services, secrets) - Add PostgreSQL on Kubernetes with multi-schema support - Add Nginx Ingress Controller configuration - Add GitHub Actions workflow for Azure deployment - Add HTTP Basic Authentication for production - Add database restore functionality via Kubernetes jobs - Update Dockerfile and nginx config for production - Update database.php for multi-schema connections - Add deployment documentation and quickstart guides Deployed version: 1.0.7 at http://72.144.113.194/ Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,410 @@
|
||||
# GitHub Actions CI/CD Setup
|
||||
|
||||
Diese Anleitung zeigt, wie du die automatische Deployment-Pipeline mit GitHub Actions einrichtest.
|
||||
|
||||
## 📋 Übersicht
|
||||
|
||||
Die Pipeline führt automatisch folgende Schritte aus:
|
||||
|
||||
1. **Build & Push**: Docker Image bauen und zu Azure Container Registry pushen
|
||||
2. **Terraform Deploy**: Infrastruktur mit Terraform deployen
|
||||
3. **Smoke Tests**: Basis-Tests nach Deployment ausführen
|
||||
4. **Notifications**: Status-Benachrichtigungen
|
||||
|
||||
## 🔐 Erforderliche GitHub Secrets
|
||||
|
||||
Gehe zu deinem GitHub Repository → Settings → Secrets and variables → Actions → New repository secret
|
||||
|
||||
### Azure Credentials
|
||||
|
||||
```bash
|
||||
# Azure Service Principal erstellen
|
||||
az ad sp create-for-rbac \
|
||||
--name "github-actions-laravel-app" \
|
||||
--role contributor \
|
||||
--scopes /subscriptions/77677a80-2dea-493d-9867-f1c961b80fb3/resourceGroups/trusted_ai_demo_rg \
|
||||
--sdk-auth
|
||||
|
||||
# Output sieht so aus:
|
||||
{
|
||||
"clientId": "xxx",
|
||||
"clientSecret": "xxx",
|
||||
"subscriptionId": "77677a80-2dea-493d-9867-f1c961b80fb3",
|
||||
"tenantId": "xxx",
|
||||
"activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
|
||||
"resourceManagerEndpointUrl": "https://management.azure.com/",
|
||||
"activeDirectoryGraphResourceId": "https://graph.windows.net/",
|
||||
"sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
|
||||
"galleryEndpointUrl": "https://gallery.azure.com/",
|
||||
"managementEndpointUrl": "https://management.core.windows.net/"
|
||||
}
|
||||
```
|
||||
|
||||
**Secret Name**: `AZURE_CREDENTIALS`
|
||||
**Secret Value**: Der gesamte JSON Output von oben
|
||||
|
||||
### Azure Container Registry
|
||||
|
||||
```bash
|
||||
# ACR Credentials abrufen
|
||||
az acr credential show --name mylaravelregistry
|
||||
|
||||
# Output:
|
||||
{
|
||||
"passwords": [
|
||||
{
|
||||
"name": "password",
|
||||
"value": "xxx"
|
||||
},
|
||||
{
|
||||
"name": "password2",
|
||||
"value": "yyy"
|
||||
}
|
||||
],
|
||||
"username": "mylaravelregistry"
|
||||
}
|
||||
```
|
||||
|
||||
**Secret Name**: `ACR_USERNAME`
|
||||
**Secret Value**: `mylaravelregistry`
|
||||
|
||||
**Secret Name**: `ACR_PASSWORD`
|
||||
**Secret Value**: Der Wert von `password` (oder `password2`)
|
||||
|
||||
### Azure Subscription
|
||||
|
||||
**Secret Name**: `AZURE_SUBSCRIPTION_ID`
|
||||
**Secret Value**: `77677a80-2dea-493d-9867-f1c961b80fb3`
|
||||
|
||||
### Laravel Application
|
||||
|
||||
**Secret Name**: `LARAVEL_APP_KEY`
|
||||
**Secret Value**: Generiere mit `php artisan key:generate --show`
|
||||
**Beispiel**: `base64:abcdefgh12345...`
|
||||
|
||||
### PostgreSQL Database
|
||||
|
||||
**Secret Name**: `POSTGRESQL_ADMIN_USERNAME`
|
||||
**Secret Value**: `pgadmin`
|
||||
|
||||
**Secret Name**: `POSTGRESQL_ADMIN_PASSWORD`
|
||||
**Secret Value**: Dein sicheres PostgreSQL Passwort
|
||||
|
||||
### Ingress & SSL
|
||||
|
||||
**Secret Name**: `INGRESS_HOST`
|
||||
**Secret Value**: Deine Domain (z.B. `app.yourdomain.com`) oder leer lassen für IP-Zugriff
|
||||
|
||||
**Secret Name**: `SSL_ISSUER_EMAIL`
|
||||
**Secret Value**: Email für Let's Encrypt (z.B. `admin@yourdomain.com`)
|
||||
|
||||
### Monitoring
|
||||
|
||||
**Secret Name**: `ALERT_EMAIL`
|
||||
**Secret Value**: Email für Azure Alerts
|
||||
|
||||
## 📝 Secrets Checkliste
|
||||
|
||||
- [ ] `AZURE_CREDENTIALS` (JSON von Service Principal)
|
||||
- [ ] `ACR_USERNAME` (mylaravelregistry)
|
||||
- [ ] `ACR_PASSWORD` (ACR password)
|
||||
- [ ] `AZURE_SUBSCRIPTION_ID` (77677a80-2dea-493d-9867-f1c961b80fb3)
|
||||
- [ ] `LARAVEL_APP_KEY` (base64:...)
|
||||
- [ ] `POSTGRESQL_ADMIN_USERNAME` (pgadmin)
|
||||
- [ ] `POSTGRESQL_ADMIN_PASSWORD` (sicheres Passwort)
|
||||
- [ ] `INGRESS_HOST` (optional: deine Domain)
|
||||
- [ ] `SSL_ISSUER_EMAIL` (optional: für SSL)
|
||||
- [ ] `ALERT_EMAIL` (deine Email)
|
||||
|
||||
## 🚀 Workflow Trigger
|
||||
|
||||
### Automatisch bei Push
|
||||
|
||||
Die Pipeline wird automatisch ausgeführt bei Push auf:
|
||||
- `main` Branch (Staging Deployment)
|
||||
- `production` Branch (Production Deployment)
|
||||
|
||||
```bash
|
||||
# Code ändern und committen
|
||||
git add .
|
||||
git commit -m "Update feature"
|
||||
|
||||
# Push zu main für Staging
|
||||
git push origin main
|
||||
|
||||
# Push zu production für Production
|
||||
git push origin production
|
||||
```
|
||||
|
||||
### Manuell über GitHub UI
|
||||
|
||||
1. Gehe zu deinem Repository auf GitHub
|
||||
2. Klicke auf "Actions" Tab
|
||||
3. Wähle "Deploy to Azure AKS" Workflow
|
||||
4. Klicke auf "Run workflow"
|
||||
5. Wähle Environment (staging/production)
|
||||
6. Klicke auf "Run workflow"
|
||||
|
||||
### Manuell über GitHub CLI
|
||||
|
||||
```bash
|
||||
# Installiere gh CLI (falls noch nicht vorhanden)
|
||||
brew install gh # macOS
|
||||
# oder: https://cli.github.com/
|
||||
|
||||
# Login
|
||||
gh auth login
|
||||
|
||||
# Workflow manuell triggern
|
||||
gh workflow run deploy-azure.yml \
|
||||
--ref main \
|
||||
--field environment=staging
|
||||
|
||||
# Workflow Status prüfen
|
||||
gh run list --workflow=deploy-azure.yml
|
||||
|
||||
# Logs anzeigen
|
||||
gh run view --log
|
||||
```
|
||||
|
||||
## 🔧 Workflow Konfiguration anpassen
|
||||
|
||||
Die Workflow-Datei liegt in [.github/workflows/deploy-azure.yml](../.github/workflows/deploy-azure.yml).
|
||||
|
||||
### Environment-spezifische Settings
|
||||
|
||||
Im Workflow werden verschiedene Settings basierend auf dem Environment gesetzt:
|
||||
|
||||
**Staging:**
|
||||
- `app_debug = true`
|
||||
- `app_replicas = 2`
|
||||
- `postgresql_sku_name = "B_Standard_B1ms"` (Basic)
|
||||
- `postgresql_storage_mb = 32768` (32 GB)
|
||||
- `ssl_enabled = false`
|
||||
|
||||
**Production:**
|
||||
- `app_debug = false`
|
||||
- `app_replicas = 3`
|
||||
- `postgresql_sku_name = "GP_Standard_D2s_v3"` (General Purpose)
|
||||
- `postgresql_storage_mb = 131072` (128 GB)
|
||||
- `ssl_enabled = true`
|
||||
|
||||
### Weitere Trigger hinzufügen
|
||||
|
||||
```yaml
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- production
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
schedule:
|
||||
- cron: '0 2 * * 0' # Jeden Sonntag um 2 Uhr
|
||||
workflow_dispatch:
|
||||
# ... existing inputs
|
||||
```
|
||||
|
||||
## 📊 Workflow Monitoring
|
||||
|
||||
### In GitHub UI
|
||||
|
||||
1. Gehe zu "Actions" Tab in deinem Repository
|
||||
2. Siehst alle Workflow-Runs
|
||||
3. Klicke auf einen Run für Details
|
||||
4. Siehst Logs für jeden Job/Step
|
||||
|
||||
### Via GitHub CLI
|
||||
|
||||
```bash
|
||||
# Aktuelle Runs anzeigen
|
||||
gh run list --workflow=deploy-azure.yml
|
||||
|
||||
# Spezifischen Run anzeigen
|
||||
gh run view <run-id>
|
||||
|
||||
# Logs anzeigen
|
||||
gh run view <run-id> --log
|
||||
|
||||
# Run erneut starten
|
||||
gh run rerun <run-id>
|
||||
|
||||
# Run abbrechen
|
||||
gh run cancel <run-id>
|
||||
```
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Pipeline schlägt bei "Build and Push" fehl
|
||||
|
||||
**Problem**: ACR Authentication fehlgeschlagen
|
||||
|
||||
**Lösung**:
|
||||
```bash
|
||||
# Prüfe ACR Credentials
|
||||
az acr credential show --name mylaravelregistry
|
||||
|
||||
# Update GitHub Secrets mit neuen Credentials
|
||||
```
|
||||
|
||||
### Pipeline schlägt bei "Terraform Deploy" fehl
|
||||
|
||||
**Problem**: Azure Credentials ungültig
|
||||
|
||||
**Lösung**:
|
||||
```bash
|
||||
# Service Principal neu erstellen
|
||||
az ad sp create-for-rbac \
|
||||
--name "github-actions-laravel-app" \
|
||||
--role contributor \
|
||||
--scopes /subscriptions/77677a80-2dea-493d-9867-f1c961b80fb3/resourceGroups/trusted_ai_demo_rg \
|
||||
--sdk-auth
|
||||
|
||||
# AZURE_CREDENTIALS Secret updaten
|
||||
```
|
||||
|
||||
**Problem**: Terraform State Lock
|
||||
|
||||
**Lösung**:
|
||||
```bash
|
||||
# State Lock manuell entfernen
|
||||
cd terraform
|
||||
terraform force-unlock <lock-id>
|
||||
```
|
||||
|
||||
### Pipeline schlägt bei "Smoke Tests" fehl
|
||||
|
||||
**Problem**: Pods nicht ready
|
||||
|
||||
**Lösung**:
|
||||
```bash
|
||||
# kubectl credentials abrufen
|
||||
az aks get-credentials \
|
||||
--resource-group trusted_ai_demo_rg \
|
||||
--name trai_k8s_cluster
|
||||
|
||||
# Pod Status prüfen
|
||||
kubectl get pods -n laravel-app
|
||||
kubectl describe pod <pod-name> -n laravel-app
|
||||
kubectl logs <pod-name> -n laravel-app
|
||||
```
|
||||
|
||||
## 🔒 Sicherheit
|
||||
|
||||
### Service Principal Permissions
|
||||
|
||||
Der Service Principal benötigt folgende Berechtigungen:
|
||||
- Contributor auf Resource Group
|
||||
- AcrPush auf Container Registry (optional, wenn über ACR credentials)
|
||||
|
||||
```bash
|
||||
# Berechtigungen prüfen
|
||||
az role assignment list \
|
||||
--assignee <service-principal-client-id> \
|
||||
--resource-group trusted_ai_demo_rg
|
||||
```
|
||||
|
||||
### Secrets Rotation
|
||||
|
||||
Rotiere Secrets regelmäßig:
|
||||
|
||||
```bash
|
||||
# Neues ACR Password generieren
|
||||
az acr credential renew \
|
||||
--name mylaravelregistry \
|
||||
--password-name password
|
||||
|
||||
# Service Principal Secret erneuern
|
||||
az ad sp credential reset \
|
||||
--id <service-principal-object-id>
|
||||
```
|
||||
|
||||
## 🚦 Branch Protection Rules
|
||||
|
||||
Empfohlene Branch Protection Rules für `main` und `production`:
|
||||
|
||||
1. Gehe zu Repository → Settings → Branches
|
||||
2. Füge Branch Protection Rule hinzu für `main` und `production`
|
||||
3. Aktiviere:
|
||||
- ✅ Require status checks to pass before merging
|
||||
- ✅ Require branches to be up to date before merging
|
||||
- ✅ Require deployments to succeed before merging
|
||||
- ✅ Require conversation resolution before merging
|
||||
- ✅ Include administrators
|
||||
|
||||
## 📈 Deployment Environments
|
||||
|
||||
GitHub Environments für bessere Kontrolle:
|
||||
|
||||
1. Gehe zu Repository → Settings → Environments
|
||||
2. Erstelle zwei Environments: `staging` und `production`
|
||||
3. Für `production`:
|
||||
- ✅ Required reviewers: Füge Reviewer hinzu
|
||||
- ✅ Wait timer: 5 minutes
|
||||
- ✅ Deployment branches: Only `production` branch
|
||||
|
||||
## 🔄 CI/CD Best Practices
|
||||
|
||||
### 1. Feature Branch Workflow
|
||||
|
||||
```bash
|
||||
# Feature branch erstellen
|
||||
git checkout -b feature/new-feature
|
||||
|
||||
# Änderungen committen
|
||||
git add .
|
||||
git commit -m "Add new feature"
|
||||
|
||||
# Push und Pull Request erstellen
|
||||
git push origin feature/new-feature
|
||||
|
||||
# Nach Review: Merge in main (automatisches Staging Deployment)
|
||||
# Dann: Merge in production (automatisches Production Deployment)
|
||||
```
|
||||
|
||||
### 2. Semantic Versioning
|
||||
|
||||
Verwende Git Tags für Releases:
|
||||
|
||||
```bash
|
||||
# Tag erstellen
|
||||
git tag -a v1.0.0 -m "Release version 1.0.0"
|
||||
git push origin v1.0.0
|
||||
|
||||
# Workflow wird Docker Image mit diesem Tag bauen
|
||||
```
|
||||
|
||||
### 3. Rollback Strategy
|
||||
|
||||
```bash
|
||||
# Bei Problemen: Zu vorheriger Version zurück
|
||||
gh workflow run deploy-azure.yml \
|
||||
--ref <previous-commit-sha> \
|
||||
--field environment=production
|
||||
|
||||
# Oder: Kubernetes Rollback
|
||||
kubectl rollout undo deployment/laravel-app -n laravel-app
|
||||
```
|
||||
|
||||
## 📚 Weitere Ressourcen
|
||||
|
||||
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
|
||||
- [Azure DevOps Documentation](https://docs.microsoft.com/en-us/azure/devops/)
|
||||
- [Terraform Cloud](https://www.terraform.io/cloud) - Alternative für Terraform State Management
|
||||
|
||||
## 🎯 Nächste Schritte
|
||||
|
||||
Nach Setup der CI/CD Pipeline:
|
||||
|
||||
1. [ ] Teste Pipeline mit Dummy-Commit
|
||||
2. [ ] Erstelle Feature Branch und PR
|
||||
3. [ ] Richte Branch Protection Rules ein
|
||||
4. [ ] Konfiguriere GitHub Environments
|
||||
5. [ ] Dokumentiere Team-Workflow
|
||||
6. [ ] Teste Rollback-Prozess
|
||||
7. [ ] Richte Slack/Teams Notifications ein (optional)
|
||||
|
||||
---
|
||||
|
||||
**Support**: Bei Problemen prüfe GitHub Actions Logs und Terraform State
|
||||
Reference in New Issue
Block a user