1. Home
  2. Automation
  3. Deploying Infrastructure Securely with GitHub Actions, OIDC, and Terraform

Deploying Infrastructure Securely with GitHub Actions, OIDC, and Terraform

Hardcoded secrets are out. Secure, federated identity-based workflows are in.

This guide walks you through how to deploy infrastructure using GitHub Actions and Terraform, authenticating into AWS (or other cloud providers) using OpenID Connect (OIDC), no long-lived credentials required.


Why This Matters

  • No secrets in CI/CD: You don’t need to store AWS keys in GitHub.
  • Short-lived credentials: OIDC issues scoped, temporary access tokens.
  • Auditability and traceability: Requests are tied to GitHub job identity.
  • Least privilege friendly: You can tightly scope what each workflow can do.

Architecture Overview

  1. GitHub Actions uses the OIDC standard to request a signed identity token.
  2. AWS IAM Role trusts GitHub’s OIDC provider and validates claims (e.g., repo name).
  3. The workflow assumes a role with sts:AssumeRoleWithWebIdentity.
  4. Terraform deploys using the temporary credentials.

Diagram: GitHub Actions → OIDC → AWS Role → Terraform Apply


Step-by-Step Guide

1. Configure IAM Role in AWS

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:sub": "repo:your-org/your-repo:ref:refs/heads/main"
        }
      }
    }
  ]
}

2. Create the Role with Least Privilege

Assign only the Terraform actions needed (e.g., manage S3, EC2, IAM).

3. Enable OIDC in GitHub

  • Go to your repository → Settings → Security → OIDC
  • Click “Add Provider” if not enabled

4. Reference the Role in Your Workflow

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: arn:aws:iam::ACCOUNT_ID:role/YourOIDCRole
          aws-region: us-east-1

      - name: Terraform Init & Apply
        run: |
          terraform init
          terraform apply -auto-approve

Best Practices

  • Use repo/environment scoping: Lock the IAM role to specific GitHub repos or branches.
  • Don’t grant * permissions: Always follow least privilege for the assumed role.
  • Use Terraform backends like S3 + DynamoDB: For proper state locking and durability.
  • Enable CloudTrail: Track who assumed what role and when.

Common Pitfalls

  • OIDC claims don’t match the IAM trust policy
  • GitHub job permissions missing id-token: write
  • Forgetting to enable the OIDC provider in AWS

Resources

StackProof uses this pattern across multiple environments, production, staging, even ephemeral preview deployments.

Updated on May 8, 2025
Was this article helpful?

Related Articles

Leave a Comment