GitHub Actions Tutorial — Deploy to Azure
Deploy to Azure
Azure provides first-party GitHub Actions for deploying to App Service, Container Apps, Functions, and AKS. Authentication uses OIDC with Azure AD workload identity — no secrets to rotate.
Authentication — OIDC with Azure AD
1. Create a Service Principal and Federated Credential
# Create the app registration
az ad app create --display-name "github-actions-deploy"
# Create a service principal
az ad sp create --id <app-id>
# Add federated credential for GitHub
az ad app federated-credential create --id <app-id> \
--parameters '{
"name": "github-main",
"issuer": "https://token.actions.githubusercontent.com",
"subject": "repo:my-org/my-repo:ref:refs/heads/main",
"audiences": ["api://AzureADTokenExchange"]
}'
2. Use in Workflow
permissions:
id-token: write
contents: read
steps:
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
Deploy to Azure App Service
name: Deploy to App Service
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci && npm run build
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- uses: azure/webapps-deploy@v3
with:
app-name: my-web-app
package: .
Deploy to Azure Container Apps
name: Deploy to Container Apps
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- uses: azure/container-apps-deploy-action@v2
with:
containerAppName: my-container-app
resourceGroup: my-rg
imageToDeploy: ghcr.io/my-org/my-app:${{ github.sha }}
Deploy Azure Functions
name: Deploy Azure Function
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install -r requirements.txt
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- uses: azure/functions-action@v2
with:
app-name: my-function-app
package: .
Common Mistakes
| Mistake | Fix |
|---|---|
| Federated credential subject mismatch | Subject must match exactly: repo:org/repo:ref:refs/heads/main |
Missing id-token: write |
Required for OIDC token generation |
| Wrong subscription scope | Grant the service principal access to the target subscription |
azure/login version outdated |
Use @v2 for OIDC support |
Quick Reference
| Target | Key Action |
|---|---|
| Auth (OIDC) | azure/login@v2 |
| App Service | azure/webapps-deploy@v3 |
| Container Apps | azure/container-apps-deploy-action@v2 |
| Functions | azure/functions-action@v2 |
| AKS | azure/aks-set-context@v4 + kubectl apply |
← Previous: Deploy to AWS
Next: Deploy to Kubernetes →