Deploy Your Terraform IaC with GitHub Actions
Deploying Terraform infrastructure can be streamlined with GitHub Actions, saving you time and reducing manual errors. Below, I propose a basic workflow that you can customize to fit your specific needs. This workflow assumes you already have a Terraform project set up and want to automate its deployment to your AWS account.
The Workflow File
Create a new file in your repository at .github/workflows/deploy.yml and paste this YAML workflow.
name: Terraform Deploy
on:
push:
branches: [ main ]
env:
AWS_REGION: us-east-1
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Set up Terraform
uses: hashicorp/setup-terraform@v3
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::<ACCOUNT_ID>:role/GithubActionsRole
aws-region: ${{ env.AWS_REGION }}
- name: Terraform Init
run: terraform init
- name: Terraform Plan
run: terraform plan
- name: Terraform Apply
run: terraform apply -auto-approve
<ACCOUNT_ID> have to be replaced by your AWS account ID.OIDC Authentication
This workflow uses OpenID Connect (OIDC) to securely authenticate with AWS, eliminating the need for long-lived credentials. If you’re new to OIDC or need help setting it up, I’ve written a dedicated post explaining how to configure the OIDC connection between GitHub and your AWS account.
The IAM Role Permissions
OIDC controls who can assume the GithubActionsRole, but the role still needs an IAM policy describing what it can do once assumed. For Terraform, that policy boils down to two things:
- Resource permissions: access to every AWS service your Terraform code manages (S3, VPC, RDS, and so on) so it can create, update, and delete those resources.
- Backend permissions: if you store state remotely, read/write access to the S3 bucket holding the state file and, when using state locking, to the DynamoDB lock table.
AdministratorAccess is tempting to get moving, but a scoped policy keeps a leaked token from reaching the rest of your account.Testing
The provided workflow does not include any testing steps. For a robust CI/CD pipeline, consider adding unit and integration tests before the deployment job. This ensures your infrastructure changes are validated before being applied.
Production Best Practices
For production environments, it’s recommended to:
- Pin all versions: Freeze the versions of Terraform and GitHub Actions to avoid unexpected updates.
- Use approvals: For critical stacks, require manual approval before deployment.
- Environment separation: Deploy to different AWS accounts for staging and production.