Azure API Management Deployment & Migration¶
Deployment-Strategien, Migration und Best Practices für Azure APIM Provider in GAL
Navigation: - ← Zurück zur Azure APIM Übersicht - ← Feature-Implementierungen
Inhaltsverzeichnis¶
- Deployment-Strategien
- Migration zu Azure APIM
- Best Practices
- Troubleshooting
- Beispiele
- Weiterführende Ressourcen
Deployment-Strategien¶
1. Azure CLI Deployment¶
Vollständiger Workflow:
# 1. Resource Group erstellen
az group create \
--name gal-resource-group \
--location westeurope
# 2. GAL Config → ARM Template
gal generate \
--config azure-apim.yaml \
--provider azure_apim \
--output azure-apim-template.json
# 3. ARM Template deployen
az deployment group create \
--resource-group gal-resource-group \
--template-file azure-apim-template.json \
--parameters apimServiceName=my-apim-service
Deployment Status prüfen:
# Deployment Status
az deployment group show \
--resource-group gal-resource-group \
--name <deployment-name>
# APIM Service Status
az apim show \
--resource-group gal-resource-group \
--name my-apim-service
2. Terraform Deployment¶
terraform/main.tf:
resource "azurerm_resource_group" "gal" {
name = "gal-resource-group"
location = "West Europe"
}
resource "azurerm_template_deployment" "gal_apim" {
name = "gal-apim-deployment"
resource_group_name = azurerm_resource_group.gal.name
template_body = file("azure-apim-template.json")
parameters = {
apimServiceName = "my-apim-service"
}
deployment_mode = "Incremental"
}
output "apim_gateway_url" {
value = azurerm_template_deployment.gal_apim.outputs["gatewayUrl"]
}
Deployment:
# 1. GAL Config → ARM Template
gal generate \
--config azure-apim.yaml \
--provider azure_apim \
--output terraform/azure-apim-template.json
# 2. Terraform Deployment
cd terraform
terraform init
terraform plan
terraform apply
# 3. Gateway URL anzeigen
terraform output apim_gateway_url
3. Bicep Deployment¶
Bicep ist Microsofts DSL für ARM Templates (alternative Syntax).
Konvertierung:
# ARM Template → Bicep
az bicep decompile \
--file azure-apim-template.json \
--outfile azure-apim.bicep
# Bicep → ARM Template (optional)
az bicep build \
--file azure-apim.bicep \
--outfile azure-apim-template.json
Deployment:
4. CI/CD Integration (GitHub Actions)¶
.github/workflows/deploy-apim.yml:
name: Deploy Azure APIM
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install GAL
run: pip install gal
- name: Generate ARM Template
run: |
gal generate \
--config azure-apim.yaml \
--provider azure_apim \
--output azure-apim-template.json
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Deploy to Azure
run: |
az deployment group create \
--resource-group ${{ secrets.RESOURCE_GROUP }} \
--template-file azure-apim-template.json \
--parameters apimServiceName=${{ secrets.APIM_SERVICE_NAME }}
- name: Run Integration Tests
run: |
curl -f https://${{ secrets.APIM_SERVICE_NAME }}.azure-api.net/api/health
5. Blue-Green Deployment¶
Strategie: 1. Neue APIM Revision erstellen 2. Traffic auf neue Revision umleiten 3. Alte Revision beibehalten (Rollback-Option)
GAL Config:
Azure CLI:
# 1. Revision erstellen
az apim api revision create \
--resource-group gal-resource-group \
--service-name my-apim-service \
--api-id user_api \
--api-revision 2
# 2. Revision aktivieren
az apim api release create \
--resource-group gal-resource-group \
--service-name my-apim-service \
--api-id user_api \
--api-revision 2 \
--notes "New version with breaking changes"
# 3. Rollback (falls nötig)
az apim api release create \
--resource-group gal-resource-group \
--service-name my-apim-service \
--api-id user_api \
--api-revision 1 \
--notes "Rollback to v1"
6. Multi-Environment Deployment¶
Strategie:
GAL Configs:
- azure-apim-dev.yaml → Dev APIM Service (Developer SKU)
- azure-apim-staging.yaml → Staging APIM Service (Basic SKU)
- azure-apim-prod.yaml → Production APIM Service (Premium SKU)
Beispiel: Dev Config
global:
azure_apim:
resource_group: gal-dev-rg
apim_service_name: gal-apim-dev
location: westeurope
sku: Developer # Kostengünstig, kein SLA
services:
- name: user_api
upstream:
targets:
- host: backend-dev.example.com
port: 443
azure_apim:
product_name: Dev-Product
rate_limit_calls: 6000 # 100 req/sec
Beispiel: Production Config
global:
azure_apim:
resource_group: gal-prod-rg
apim_service_name: gal-apim-prod
location: westeurope
sku: Premium # Multi-Region, 99.99% SLA
services:
- name: user_api
upstream:
targets:
- host: backend-prod.example.com
port: 443
azure_apim:
product_name: Production-Product
rate_limit_calls: 120000 # 2000 req/sec
Migration zu Azure APIM¶
Migration von anderen API Gateways¶
Unterstützte Source Provider: - Kong - Envoy - Nginx - HAProxy - APISIX - Traefik - AWS API Gateway - GCP API Gateway
Migration Workflow¶
# 1. Existierende Config importieren (z.B. Kong)
gal import \
--provider kong \
--config kong.yml \
--output gal-config.yaml
# 2. GAL Config → Azure APIM ARM Template
gal generate \
--config gal-config.yaml \
--provider azure_apim \
--output azure-apim-template.json
# 3. ARM Template deployen
az deployment group create \
--resource-group gal-resource-group \
--template-file azure-apim-template.json
Migration Checklist¶
Vor der Migration: - [ ] Alle API Endpoints dokumentieren - [ ] Rate Limits und Policies auflisten - [ ] Authentication Mechanismen prüfen (JWT, API Keys) - [ ] Backend URLs und Health Checks validieren - [ ] Monitoring und Logging Setup planen
Während der Migration: - [ ] GAL Config erstellen und testen - [ ] ARM Template generieren und validieren - [ ] Dev/Staging Environment deployen - [ ] Integration Tests durchführen - [ ] Performance Tests (Load Testing) - [ ] Subscription Keys generieren und verteilen
Nach der Migration: - [ ] DNS/Traffic auf Azure APIM umleiten - [ ] Monitoring aktivieren (Application Insights) - [ ] Alte Gateway parallel laufen lassen (Rollback) - [ ] Alerts konfigurieren - [ ] Developer Portal aktivieren
Beispiel: Kong → Azure APIM¶
Schritt 1: Kong Config analysieren
# Kong config (kong.yml)
services:
- name: user-service
url: https://backend.example.com
routes:
- name: users-route
paths:
- /api/users
methods: [GET, POST]
plugins:
- name: rate-limiting
config:
minute: 100
- name: jwt
config:
uri_param_names: ["jwt"]
Schritt 2: GAL Config erstellen
# GAL config (gal-config.yaml)
version: "1.0"
provider: azure_apim
services:
- name: user_service
type: rest
protocol: https
upstream:
targets:
- host: backend.example.com
port: 443
routes:
- path_prefix: /api/users
methods: [GET, POST]
rate_limit:
enabled: true
requests_per_second: 100
authentication:
type: jwt
jwt_config:
issuer: "https://login.microsoftonline.com/{tenant-id}/v2.0"
audience: "api://user-service"
azure_apim:
product_name: UserService-Product
product_subscription_required: false # JWT statt Subscription Keys
api_revision: "1"
Schritt 3: ARM Template generieren
Schritt 4: Deployment
az deployment group create \
--resource-group gal-resource-group \
--template-file azure-apim-template.json
Best Practices¶
1. SKU-Auswahl¶
| Umgebung | Empfohlene SKU | Begründung |
|---|---|---|
| Development | Developer | Kostengünstig, kein SLA, Feature-complete |
| Testing/Staging | Basic oder Consumption | SLA 99.95%, Production-like |
| Production (kleine APIs) | Standard | VNet Support, 99.95% SLA |
| Production (Enterprise) | Premium | Multi-Region, 99.99% SLA, unbegrenzte Units |
SKU Features:
| SKU | SLA | Max Units | VNet | Multi-Region | Preis/Monat |
|---|---|---|---|---|---|
| Developer | Kein SLA | 1 | ❌ | ❌ | ~40 EUR |
| Consumption | 99.95% | Auto-scale | ❌ | ❌ | Pay-per-Request |
| Basic | 99.95% | 2 | ❌ | ❌ | ~135 EUR |
| Standard | 99.95% | 4 | ✅ | ❌ | ~540 EUR |
| Premium | 99.99% | Unlimited | ✅ | ✅ | ~2,160 EUR |
2. Subscription Management¶
Best Practice: - Ein Product pro API Tier (Starter, Professional, Enterprise) - Subscription Keys pro Environment (Dev, Staging, Production) - Secondary Keys für Key Rotation verwenden - Subscription Expiration Dates setzen
Beispiel:
services:
- name: user_api
azure_apim:
product_name: "Professional-Tier"
product_subscription_required: true
rate_limit_calls: 120000 # 2000 req/min
Subscription Key Rotation:
# Primary Key regenerieren
az apim subscription regenerate-key \
--resource-group gal-resource-group \
--service-name my-apim-service \
--subscription-id <subscription-id> \
--key-type primary
# Secondary Key regenerieren
az apim subscription regenerate-key \
--resource-group gal-resource-group \
--service-name my-apim-service \
--subscription-id <subscription-id> \
--key-type secondary
3. Rate Limiting Strategy¶
Empfohlene Werte:
| API Tier | Requests/Second | APIM Calls | Renewal Period |
|---|---|---|---|
| Free | 10 | 600 | 60 |
| Starter | 100 | 6,000 | 60 |
| Professional | 500 | 30,000 | 60 |
| Enterprise | 2000 | 120,000 | 60 |
Best Practice: - Niedrigere Limits in Dev/Staging (Cost Optimization) - Höhere Limits in Production (Performance) - Per-Subscription Rate Limiting verwenden - Grace Period für Limit-Überschreitung (Burst)
4. Monitoring & Logging¶
Azure Monitor Integration:
# 1. Application Insights erstellen
az monitor app-insights component create \
--app gal-apim-insights \
--location westeurope \
--resource-group gal-resource-group
# 2. APIM mit Application Insights verbinden
az apim api diagnostic create \
--resource-group gal-resource-group \
--service-name my-apim-service \
--api-id user_api \
--diagnostic-id applicationinsights \
--logger-id app-insights-logger
Log Analytics Queries:
// Requests pro Minute
ApiManagementGatewayLogs
| where TimeGenerated > ago(1h)
| summarize RequestCount = count() by bin(TimeGenerated, 1m)
| render timechart
// 4xx/5xx Error Rate
ApiManagementGatewayLogs
| where ResponseCode >= 400
| summarize ErrorCount = count() by ResponseCode
| order by ErrorCount desc
// Top 10 langsame Requests
ApiManagementGatewayLogs
| where TimeGenerated > ago(1h)
| extend Duration = ResponseTime
| top 10 by Duration desc
| project TimeGenerated, Method, Url, Duration, ResponseCode
Alerts konfigurieren:
# Alert für 5xx Errors
az monitor metrics alert create \
--name "APIM-5xx-Errors" \
--resource-group gal-resource-group \
--scopes /subscriptions/.../apim-service \
--condition "count HttpResponseCode where code >= 500 > 10" \
--window-size 5m \
--evaluation-frequency 1m
5. Security Hardening¶
Empfehlungen: - ✅ HTTPS only (enforce HTTPS in policies) - ✅ Azure AD JWT Validation für interne APIs - ✅ Subscription Keys für externe APIs - ✅ Rate Limiting auf allen Endpoints - ✅ IP Whitelisting (via APIM Policies) - ✅ CORS Policies konfigurieren - ✅ Custom Domains mit TLS 1.2+ verwenden
IP Whitelisting Policy:
<ip-filter action="allow">
<address>13.66.201.169</address>
<address-range from="13.66.140.128" to="13.66.140.143" />
</ip-filter>
HTTPS Enforcement:
<choose>
<when condition="@(context.Request.Url.Scheme != "https")">
<return-response>
<set-status code="403" reason="HTTPS required" />
</return-response>
</when>
</choose>
6. Performance Optimization¶
Caching aktivieren:
routes:
- path_prefix: /api/users
cache:
enabled: true
ttl: 300 # 5 Minuten
vary_by_query_params:
- id
Connection Pooling: - Azure APIM nutzt automatisch Connection Pooling - Keine manuelle Konfiguration erforderlich
Backend Timeouts:
7. Cost Optimization¶
Tipps: - Developer SKU für Dev/Test (keine Production Workloads) - Consumption SKU für sporadische APIs (Pay-per-Request) - Basic/Standard SKU für Production (fixe Kosten) - Premium SKU nur für Multi-Region oder Enterprise
Cost Estimation:
# Azure Pricing Calculator
https://azure.microsoft.com/en-us/pricing/calculator/
# Consumption SKU Pricing
# - First 1M calls: Free
# - Next 1-10M calls: $3.50 per million
# - Over 10M calls: $0.70 per million
Troubleshooting¶
Problem: ARM Template Deployment schlägt fehl¶
Diagnose:
# Deployment Status prüfen
az deployment group show \
--resource-group gal-resource-group \
--name <deployment-name>
# Deployment Logs anzeigen
az deployment operation group list \
--resource-group gal-resource-group \
--name <deployment-name>
Häufige Fehler: - APIM Service Name bereits vergeben (global eindeutig) - SKU nicht verfügbar in Region - Quota-Limits erreicht - Fehlende Permissions (RBAC)
Lösung:
# APIM Service Name verfügbar?
az apim check-name --name <your-apim-name>
# Quota Limits prüfen
az vm list-usage --location westeurope
Problem: Subscription Keys funktionieren nicht¶
Diagnose:
# Subscription Keys anzeigen
az apim subscription show \
--resource-group gal-resource-group \
--service-name my-apim-service \
--subscription-id <subscription-id>
# Test mit cURL
curl -H "Ocp-Apim-Subscription-Key: <your-key>" \
https://my-apim-service.azure-api.net/api/users
Lösung:
# Subscription Key regenerieren
az apim subscription regenerate-key \
--resource-group gal-resource-group \
--service-name my-apim-service \
--subscription-id <subscription-id> \
--key-type primary
Problem: JWT Validation schlägt fehl¶
Diagnose:
# OIDC Discovery Document prüfen
curl https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration
# Token Claims anzeigen (mit jwt-cli)
jwt decode <your-token>
Häufige Fehler: - Falscher Issuer (tenant-id) - Falsche Audience - Required Claims fehlen im Token - Token abgelaufen (exp)
Lösung: - Issuer und Audience in Policy XML prüfen - Token mit korrekten Claims neu generieren - Clock Skew prüfen (Token exp vs. Server Zeit)
Problem: Rate Limiting greift nicht¶
Diagnose:
# Policy XML anzeigen
az apim api operation policy show \
--resource-group gal-resource-group \
--service-name my-apim-service \
--api-id user_api \
--operation-id get_users
Lösung:
- Policy XML validieren
- calls und renewal-period prüfen
- Eventuell Product-Level Policies prüfen
- Testen mit Rate Limit Test:
# 100 Requests in 10 Sekunden
for i in {1..100}; do
curl -H "Ocp-Apim-Subscription-Key: <key>" \
https://my-apim-service.azure-api.net/api/users &
done
wait
# Erwartete Response: 429 Too Many Requests
Problem: Backend Connection Timeout¶
Diagnose:
# Backend Erreichbarkeit testen
curl -v https://backend.example.com:443/api/users
# APIM Logs prüfen (Application Insights)
az monitor app-insights query \
--app gal-apim-insights \
--analytics-query "traces | where message contains 'timeout'"
Lösungen:
- Backend URL prüfen (HTTP vs HTTPS)
- Firewall Rules für APIM IP-Range
- VNet Integration prüfen (Premium SKU)
- Backend Timeout erhöhen (Policy: <forward-request timeout="120" />)
APIM Outbound IPs finden:
az apim show \
--resource-group gal-resource-group \
--name my-apim-service \
--query "publicIPAddresses" \
--output table
Problem: CORS Errors¶
Diagnose:
Lösung:
<!-- APIM Policy (Inbound) -->
<cors allow-credentials="true">
<allowed-origins>
<origin>https://example.com</origin>
<origin>https://app.example.com</origin>
</allowed-origins>
<allowed-methods>
<method>GET</method>
<method>POST</method>
<method>PUT</method>
<method>DELETE</method>
<method>OPTIONS</method>
</allowed-methods>
<allowed-headers>
<header>Content-Type</header>
<header>Authorization</header>
<header>Ocp-Apim-Subscription-Key</header>
</allowed-headers>
</cors>
Beispiele¶
1. Public API ohne Authentication¶
services:
- name: public_api
upstream:
targets:
- host: public-backend.example.com
port: 443
routes:
- path_prefix: /api/public
methods: [GET]
azure_apim:
product_name: PublicAPI-Product
product_subscription_required: false # Keine Subscription Keys
api_revision: "1"
2. API mit Subscription Keys¶
services:
- name: user_api
upstream:
targets:
- host: user-backend.example.com
port: 443
routes:
- path_prefix: /api/users
methods: [GET, POST, PUT, DELETE]
authentication:
type: api_key
api_key:
key_name: Ocp-Apim-Subscription-Key
in_location: header
rate_limit:
enabled: true
requests_per_second: 100
azure_apim:
product_name: UserAPI-Product
product_subscription_required: true
api_revision: "1"
3. API mit Azure AD JWT¶
services:
- name: admin_api
upstream:
targets:
- host: admin-backend.example.com
port: 443
routes:
- path_prefix: /api/admin
methods: [GET, POST, PUT, DELETE]
authentication:
type: jwt
jwt_config:
issuer: "https://login.microsoftonline.com/{tenant-id}/v2.0"
audience: "api://admin-api"
required_claims:
- name: "roles"
value: "admin"
azure_apim:
product_name: AdminAPI-Product
product_subscription_required: false # JWT statt Subscription Keys
api_revision: "1"
4. Multi-Region Deployment (Premium SKU)¶
global:
azure_apim:
sku: Premium
location: westeurope
# Zusätzliche Regionen via Azure Portal
services:
- name: global_api
upstream:
targets:
- host: backend-westeurope.example.com
port: 443
routes:
- path_prefix: /api/global
methods: [GET, POST]
rate_limit:
enabled: true
requests_per_second: 1000
azure_apim:
product_name: GlobalAPI-Product
product_subscription_required: true
api_revision: "1"
5. API mit Custom Headers¶
services:
- name: webhook_api
upstream:
targets:
- host: webhook-backend.example.com
port: 8080
routes:
- path_prefix: /webhooks
methods: [POST]
headers:
request_add:
X-Webhook-Source: "Azure-APIM"
X-Webhook-Version: "1.0"
X-Request-ID: "generated"
response_add:
X-Webhook-Processed: "true"
X-Response-Time: "measured"
azure_apim:
product_name: WebhookAPI-Product
api_revision: "1"
Weiterführende Ressourcen¶
Offizielle Dokumentation¶
- Azure APIM Docs: https://docs.microsoft.com/en-us/azure/api-management/
- ARM Template Reference: https://docs.microsoft.com/en-us/azure/templates/microsoft.apimanagement/
- Policy Reference: https://docs.microsoft.com/en-us/azure/api-management/api-management-policies
- Azure CLI Reference: https://docs.microsoft.com/en-us/cli/azure/apim
GAL Guides¶
- ← Zurück zur Azure APIM Übersicht
- ← Feature-Implementierungen
- Quickstart Guide
- Authentication Guide
- Rate Limiting Guide
- Provider Comparison
Beispiele¶
Version: 1.4.0 Status: ✅ Vollständig implementiert Letzte Aktualisierung: 2025-10-22