DEV Community

John  Ajera
John Ajera

Posted on

GitHub Actions to AWS OIDC Integration SetuP

GitHub Actions to AWS OIDC Integration Setup

Securely deploy to AWS from GitHub Actions using OpenID Connect (OIDC), eliminating the need for long-lived AWS credentials.


✅ Step 1: Create IAM Role for GitHub (via AWS CLI)

Run the following AWS CLI commands to manually bootstrap the IAM role and OIDC provider:

aws iam create-open-id-connect-provider \
  --url https://token.actions.githubusercontent.com \
  --client-id-list sts.amazonaws.com \
  --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1

aws iam create-role \
  --role-name github-oidc-role \
  --assume-role-policy-document file://trust-policy.json

aws iam attach-role-policy \
  --role-name github-oidc-role \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
Enter fullscreen mode Exit fullscreen mode

Note: Replace AdministratorAccess with a least-privilege policy if possible.


✅ Step 2: Folder Structure (Bootstrap Setup)

Minimal layout for bootstrapping (no remote backend):

my-terraform-project/
├── .github/
│   └── workflows/
│       └── deploy.yml
├── main.tf
├── .gitignore
└── README.md
Enter fullscreen mode Exit fullscreen mode

Example .gitignore:

.terraform/

Note: This is a bootstrap setup and does not use a remote backend. For production, it's recommended to configure a remote backend such as an S3 bucket.


✅ Step 3: Minimal Terraform Configuration (main.tf)

This main.tf contains only a minimal resource for testing. Terraform is not responsible for creating the IAM role in this bootstrap scenario.

provider "aws" {
  region = var.aws_region
}

variable "aws_region" {
  description = "AWS region"
  default     = "ap-southeast-2"
}

variable "aws_account_id" {
  description = "AWS Account ID"
}

variable "github_owner" {
  description = "GitHub organization or username"
}

variable "repo_name" {
  description = "GitHub repository name"
}

# Minimal test resource
data "aws_caller_identity" "current" {}

resource "aws_s3_bucket" "test_bucket" {
  bucket = "test-bucket-${data.aws_caller_identity.current.account_id}"
  acl    = "private"

  tags = {
    Name = "Test Bucket"
    Env  = "Bootstrap"
  }
}
Enter fullscreen mode Exit fullscreen mode

✅ Step 4: Configure GitHub Secrets and Variables

Go to Repo → Settings → Secrets and variables → Actions, and set:

  • Secrets:
  • AWS_ACCOUNT_ID: Your 12-digit AWS account ID (e.g. 123456789012)

Variables:

  • AWS_REGION: AWS region to deploy resources (e.g. ap-southeast-2)
  • TERRAFORM_VERSION: Terraform version to use (e.g. 1.12.1)
  • OIDC_ROLE_NAME: IAM role name that GitHub Actions will assume (must match the name in main.tf, e.g. github-oidc-role)

✅ Step 5: GitHub Actions Workflows

🔹 plan.yml – for Terraform Plan (on PR)

name: Terraform Plan

permissions:
  id-token: write
  contents: read

concurrency:
  group: terraform-plan-${{ github.head_ref || github.ref }}
  cancel-in-progress: true

on:
  pull_request:
    branches: [main]

env:
  AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
  AWS_REGION: ${{ vars.AWS_REGION }}
  TERRAFORM_VERSION: ${{ vars.TERRAFORM_VERSION }}
  OIDC_ROLE_NAME: ${{ vars.OIDC_ROLE_NAME }}

jobs:
  terraform:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Configure AWS credentials via OIDC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role/${{ env.OIDC_ROLE_NAME }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: ${{ env.TERRAFORM_VERSION }}

      - name: Terraform Init
        run: terraform init

      - name: Terraform Format
        run: terraform fmt -check
        continue-on-error: true

      - name: Terraform Validate
        run: terraform validate

      - name: Terraform Plan
        run: terraform plan
Enter fullscreen mode Exit fullscreen mode

🔹 deploy.yml – for Terraform Apply

name: Terraform Apply

permissions:
  id-token: write
  contents: write

concurrency:
  group: terraform-apply-${{ github.head_ref || github.ref }}
  cancel-in-progress: true

on:
  push:
    branches: [main]

env:
  AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
  AWS_REGION: ${{ vars.AWS_REGION }}
  TERRAFORM_VERSION: ${{ vars.TERRAFORM_VERSION }}
  OIDC_ROLE_NAME: ${{ vars.OIDC_ROLE_NAME }}

jobs:
  terraform:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure AWS credentials via OIDC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role/${{ env.OIDC_ROLE_NAME }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: ${{ env.TERRAFORM_VERSION }}

      - name: Terraform Init
        run: terraform init

      - name: Terraform Format
        run: terraform fmt -check
        continue-on-error: true

      - name: Terraform Validate
        run: terraform validate

      - name: Terraform Plan
        run: terraform plan

      - name: Terraform Apply
        id: apply
        run: terraform apply -auto-approve
        continue-on-error: true

      - name: Commit and force push if changed
        if: always()
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

          if ! git diff --quiet || ! git diff --staged --quiet; then
            git add .
            git commit -m "Update terraform state and lock file"
            git push --force
          fi

      - name: Fail if Terraform Apply errored
        if: steps.apply.outcome == 'failure'
        run: exit 1
Enter fullscreen mode Exit fullscreen mode

✅ Summary

Component Status Notes
OIDC Provider One-time setup per AWS account
IAM Role Defined inline in main.tf
Policy Permissions Start with AdministratorAccess, scope down later
GitHub Workflow Uses configure-aws-credentials for OIDC login
No Secrets Required Secure, short-lived tokens – no static credentials

You’re now ready to securely run terraform apply from GitHub Actions using short-lived OIDC credentials with a minimal bootstrap setup.

Top comments (0)