Skip to content

Terraform automation with Github

Step 1. Create repository

In this example I am creating repo called github-action-aws-tf

Step 2. S3 bucket to store state file

In S3 create a new bucket with versioning enabled

Step 3. Configure OIDC

  • In IAM -> Identity providers -> add provider
  • Select OpenIDConnect
  • Provider URL token.actions.githubusercontent.com
  • Audience sts.amazonaws.com
  • Add provider

Step 3. IAM role with permission

Create a new IAM roles - Select Custom Policy and paste below trust policy by updating repo name and account ID - Create custom policy allowing write access terraform state bucket and attach it. - Add any additional permissions required like ec2, LoadBalancer etc.

trustpolicy.json

{
    "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:aud": "sts.amazonaws.com"
                },
                "ForAnyValue:StringLike": {
                    "token.actions.githubusercontent.com:sub": "repo:<NAME>/<REPONAME>:*"
                }
            }
        }
    ]
}

Now you are ready to create Github actions and execute.

Step 4. Simple github action

Here is a very simple github action that will trigger plan up on pull request creation, and apply when merged to main.

```yaml name: "Terraform Build" on: push: branches: - main pull_request: permissions: contents: read pull-requests: write # id-token: write env: TF_LOG: INFO

jobs: terraforms-build: runs-on: ubuntu-latest steps: - name: Git checkout uses: actions/checkout@v4

  - name: Configure AWS Credentials
    uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: arn:aws:iam::<ACCOUNTID>:role/<ROLE NAME>
      role-session-name: githubaction-session
      aws-region: eu-west-1

  - name: Setup Terraform
    uses: hashicorp/setup-terraform@v3

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

  - name: Terraform Init
    id: init
    run: terraform init

  - name: Terraform Validate
    id: validate
    run: terraform validate -no-color

  - name: Terraform Plan
    id: plan
    run: terraform plan -no-color
    if: (github.event_name == 'pull_request') || (github.event_name == 'push' && github.ref == 'refs/heads/main')
    continue-on-error: true

  - name: Terraform Apply
    id: apply  
    if: github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.plan.conclusion == 'success'
    run: terraform apply -auto-approve -input=false

  - name: Terraform Apply Status
    if: steps.apply.outcome == 'failure'
    run: exit

```