DEV Community

Terrateam for Terrateam

Posted on

Building a CI/CD Pipeline for Terraform with GitHub Actions (Step-by-Step Guide)

Manual Terraform operations are slow and create bottlenecks. Each deployment requires careful coordination and multiple operations. Automating these operations through a CI/CD pipeline streamlines this tedious process. Research from HashiCorp shows that organizations using automated Terraform workflows deploy infrastructure changes 89% faster than those relying on manual processes.

This guide shows you how to build a CI/CD pipeline using GitHub Actions to automate your Terraform operations. You'll learn how to set up secure authentication with AWS using OpenID Connect (OIDC), manage remote state, and create workflows that automatically validate and apply infrastructure changes. By the end, you'll have a production-ready pipeline that runs format checks and plans on pull requests, then applies changes automatically when code merges to main.

Setting Up the Foundation

Before building your pipeline, you need a GitHub repository for your Terraform configurations and an AWS account for deploying resources. Your repository should follow infrastructure-as-code best practices with clear documentation and structured Terraform files.

Remote State Management

Teams need a reliable system to store and manage Terraform state files. AWS S3 provides remote state storage and locking to prevent concurrent modifications. Configure your system in your Terraform configuration:

terraform {
  backend "s3" {
    bucket         = "your-terraform-state-bucket"
    key            = "terraform.tfstate"
    region         = "us-west-2"
    use_lockfile   = true
    encrypt        = true
  }
}
Enter fullscreen mode Exit fullscreen mode

Secure AWS Authentication

OpenID Connect (OIDC) eliminates the need for storing long-lived AWS credentials in GitHub. GitHub Actions generates short-lived tokens to assume AWS roles, reducing security risks and simplifying credential management.

To set up OIDC:

  1. Create an OIDC provider in AWS IAM using the address https://token.actions.githubusercontent.com.
  2. Create an IAM role with this trust policy:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::ACCOUNT-ID:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringLike": {
                    "token.actions.githubusercontent.com:sub": "repo:organization/repository:*"
                }
            }
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Creating GitHub Actions Workflows

GitHub Actions uses YAML files in the .github/workflows directory to define CI/CD pipelines. Two workflows are going to be created: one for pull request validation and another for applying changes to production.

Pull Request Validation

Create terraform-plan.yml to run whenever a pull request is created or updated:

name: 'Terraform Plan'
on:
  pull_request:

jobs:
  terraform:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
      id-token: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: us-west-2

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

      - name: Terraform Init
        run: terraform init

      - name: Terraform Format
        run: terraform fmt -check

      - name: Terraform Plan
        run: terraform plan -out=tfplan

      - name: Add Plan Comment
        uses: actions/github-script@v6
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const output = `#### Terraform Plan Output
            \`\`\`
            ${process.env.PLAN_OUTPUT}
            \`\`\`
            `;
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: output
            })
Enter fullscreen mode Exit fullscreen mode

Production Deployment

Create terraform-apply.yml to run when changes merge to main:

name: 'Terraform Apply'
on:
  push:
    branches:
      - main

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

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: us-west-2

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

      - name: Terraform Init
        run: terraform init

      - name: Terraform Apply
        run: terraform apply -auto-approve
Enter fullscreen mode Exit fullscreen mode

Improving the Pipeline

Add these features to improve your pipeline's functionality and visibility:

Status Badges

Add this badge to your README.md to show pipeline status:

![Terraform CI](https://github.com/{owner}/{repo}/actions/workflows/{workflow-name}/badge.svg)
Enter fullscreen mode Exit fullscreen mode

Plan Output Comments

The workflow automatically posts Terraform plan outputs as comments on pull requests. This helps reviewers understand proposed changes without leaving the PR interface. The plan output uses formatted code blocks for readability and includes resource changes, additions, and deletions.

Automating with Confidence

A well-configured Terraform pipeline with GitHub Actions transforms infrastructure deployment from a manual process into a streamlined workflow. GitHub Actions' features enable teams to test across multiple environments and use specialized runners for complex deployments. The combination of OIDC authentication, remote state management, and automated plan reviews creates a secure and efficient process that reduces deployment time while maintaining high standards for infrastructure changes.

In addition, integrating open-source solutions like Terrateam can further improve your Terraform and GitHub workflows. Terrateam offers automated deployments, customized workflows, and features that strengthen security and compliance, making infrastructure management even more effective.

Top comments (0)