GitHub Actions Cloud Deployments
GitHub Actions connects directly to all major cloud platforms — AWS, Azure, and Google Cloud — to automate deployments. This topic shows how to authenticate securely with each cloud provider and deploy applications using GitHub Actions workflows.
Authentication: The Foundation of Cloud Deployments
Before deploying to any cloud platform, your workflow must prove its identity to that platform. Two authentication approaches exist:
Approach 1: Long-lived credentials (access keys)
Store API keys as GitHub Secrets
✓ Simple to set up
✗ Keys can expire, leak, or be misused
Approach 2: OpenID Connect (OIDC) — recommended
Cloud platform trusts GitHub directly
✓ No long-lived keys to manage
✓ Credentials expire automatically after the job
✓ More secure, industry standard
Understanding OIDC Authentication
OIDC works like a hotel keycard system. The hotel (cloud platform) trusts the keycard reader (GitHub's identity system). When you arrive (workflow runs), the reader issues a temporary keycard (short-lived token). The keycard opens doors (cloud resources) and expires when you check out (job ends).
Workflow starts
↓
GitHub issues a short-lived token (OIDC token)
↓
Cloud platform verifies token with GitHub
↓
Cloud platform grants temporary credentials
↓
Workflow deploys using those credentials
↓
Job ends → credentials expire automatically
Deploying to AWS with OIDC
First, configure an IAM identity provider and role in your AWS account that trusts GitHub. Then use the official AWS credential action:
name: Deploy to AWS
on:
push:
branches: [main]
permissions:
id-token: write ← Required for OIDC
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials via OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: us-east-1
- name: Deploy to S3
run: aws s3 sync ./dist s3://my-app-bucket --delete
- name: Invalidate CloudFront cache
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ vars.CF_DISTRIBUTION_ID }} \
--paths "/*"
Deploying to ECS (Elastic Container Service)
steps:
- name: Login to ECR
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push Docker image to ECR
uses: docker/build-push-action@v6
with:
push: true
tags: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app:${{ github.sha }}
- name: Deploy to ECS
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: task-definition.json
service: my-app-service
cluster: production-cluster
wait-for-service-stability: true
Deploying to Azure with OIDC
Configure a federated identity credential in Azure AD, then use the official Azure login action:
name: Deploy to Azure
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Log in to Azure via OIDC
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Deploy to Azure App Service
uses: azure/webapps-deploy@v3
with:
app-name: my-web-app
slot-name: production
package: ./dist
- name: Deploy to Azure Container Apps
uses: azure/container-apps-deploy-action@v1
with:
containerAppName: my-container-app
resourceGroup: my-resource-group
imageToDeploy: myregistry.azurecr.io/my-app:${{ github.sha }}
Deploying to Google Cloud with OIDC
Configure Workload Identity Federation in GCP, then use the official Google Cloud auth action:
name: Deploy to Google Cloud
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
workload_identity_provider: projects/123/locations/global/workloadIdentityPools/my-pool/providers/my-provider
service_account: deploy-sa@my-project.iam.gserviceaccount.com
- name: Set up Google Cloud SDK
uses: google-github-actions/setup-gcloud@v2
- name: Deploy to Cloud Run
run: |
gcloud run deploy my-app \
--image gcr.io/my-project/my-app:${{ github.sha }} \
--region us-central1 \
--platform managed
Deploying to Other Platforms
Heroku
- uses: akhileshns/heroku-deploy@v3.13.15
with:
heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
heroku_app_name: my-heroku-app
heroku_email: team@example.com
Vercel
- name: Deploy to Vercel
run: npx vercel --token ${{ secrets.VERCEL_TOKEN }} --prod
Netlify
- name: Deploy to Netlify
uses: netlify/actions/cli@master
with:
args: deploy --dir=dist --prod
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
Cloud Deployment Checklist
Before deploying to any cloud:
□ Set up OIDC or create minimal-permission service account
□ Store credentials as GitHub Secrets or use OIDC
□ Target the deployment job at a specific environment
□ Add required reviewers for production environments
□ Test the deployment workflow in staging first
□ Add rollback instructions to your runbook
□ Add Slack or email notifications for deployment events
