Learn how to securely deploy infrastructure to cloud providers like AWS using GitHub Actions, OpenID Connect (OIDC), and Terraform, without long-lived secrets or static credentials.
🔐 Why Use OIDC with GitHub Actions?
- Eliminates hardcoded secrets (no more storing cloud keys in GitHub)
- Uses short-lived credentials scoped to the workflow
- Supports least-privilege IAM and auditing
🛠️ What You’ll Need
- A GitHub repository
- Terraform code configured for your cloud provider (AWS example below)
- An IAM identity provider (OIDC) set up in your cloud account
⚙️ AWS Setup Steps
- In AWS IAM, create an OIDC identity provider:
- Provider URL:
https://token.actions.githubusercontent.com
- Audience:
sts.amazonaws.com
- Provider URL:
- Create an IAM role that trusts GitHub’s OIDC provider:
- Attach a Terraform-specific policy (e.g.,
AdministratorAccess
or scoped permissions) - Add a trust policy using
Subject
conditions (example below)
- Attach a Terraform-specific policy (e.g.,
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam:::oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:your-org/your-repo:*"
}
}
}
🚀 GitHub Actions Workflow Example
name: Deploy Terraform
on:
push:
branches: [ main ]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: arn:aws:iam:::role/github-terraform
aws-region: us-east-1
- name: Terraform Init
run: terraform init
- name: Terraform Plan
run: terraform plan
- name: Terraform Apply
run: terraform apply -auto-approve
🔒 Security Notes
- Use IAM conditions to restrict which repos or branches can assume the role
- Log and monitor
sts:AssumeRoleWithWebIdentity
usage - Don’t grant broad Terraform privileges unless needed