How to Build a Terraform CI/CD Pipeline with GitHub Actions

Setting up a Terraform CI/CD pipeline with GitHub Actions is one of the most effective ways to automate your AWS infrastructure deployments. In this guide, you’ll learn how to build a complete Terraform CI/CD pipeline with GitHub Actions — from configuring OIDC authentication and IAM roles to running plan and apply jobs automatically on every pull request and merge.

Key Takeaways for Your Terraform Workflow

  • Here’s a comprehensive guide on automating the creation of AWS S3 buckets using Terraform and GitHub Actions.
  • Readers will learn how to establish a seamless Continuous Integration and Continuous Deployment (CI/CD) workflow. This workflow automatically creates an S3 bucket whenever code is pushed to GitHub.
  • The article covers the entire process. It includes writing Terraform code and configuring GitHub Secrets for secure credential management. The article provides clear instructions for setting up the necessary components.
  • By the end of the post, you will have a fully functioning automation pipeline. This pipeline ensures efficient resource management. It also secures resource management in AWS.
Terraform CI/CD pipeline GitHub Actions workflow chart

✅ Overview of the Terraform Workflow

This setup consists of a Terraform project and a GitHub Actions workflow. It automates the creation of an S3 bucket in AWS.

What this project achieves:

  • Automated Creation: An S3 bucket is automatically created when the code is pushed.
  • Secure Authentication: Uses GitHub Secrets to manage AWS login details.
  • CI/CD Integration: No manual intervention is required.

🟦 Terraform Code: AWS Resource Definition for the Automation

The main files involved in this process are:

  • main.tf
  • variables.tf
  • outputs.tf

What Does This Terraform Code Create?

  • One AWS S3 bucket with specified tags (Environment=dev, Project=terraform-ci-cd) and a name provided from variables.

🟧 GitHub Actions Workflow for Terraform Automation

The workflow defined in .github/workflows/terraform.yml triggers automatically when you push code to the main branch or create a pull request.

Pipeline Steps in the GitHub Actions Workflow

  1. Checkout Code: Pulls the latest code from the GitHub repository.
  2. Setup Terraform: Installs Terraform on the GitHub server.
  3. terraform init: Initializes Terraform modules and provider plugins.
  4. terraform fmt: Checks the formatting of Terraform files.
  5. terraform validate: Validates the Terraform configuration syntax.
  6. terraform plan: Shows the changes Terraform intends to make.
  7. terraform apply: Creates the AWS S3 bucket on main branch push.

🟩 Using GitHub Secrets for AWS Credentials

The pipeline retrieves AWS credentials from GitHub Secrets:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_REGION

This approach ensures that credentials are not exposed in the code.

🟫 When Does the Automation Run?

The pipeline is triggered by:

  • A push to the main branch
  • A pull request to the main branch

Output of the Terraform Workflow Execution

After running the pipeline, Terraform will output:

Example output:

bucket_name = "my-demo-s3-bucket"
bucket_arn = "arn:aws:s3:::my-demo-s3-bucket"

🎯 Summary of the Terraform Automation

Components and Their Purpose in the Workflow

ComponentPurpose
Terraform filesDefine an AWS resource (S3 bucket)
GitHub Actions pipelineAutomates validation, planning, and creation
AWS SecretsSecure authentication
CI/CDEliminates manual terraform apply

In Simple Terms: How the Terraform Workflow Runs

“This project automatically creates an S3 bucket in AWS whenever you push code to GitHub.”

✅ Terraform Files Used in This Setup

1. main.tf (Example: Create an S3 Bucket with Terraform)

terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
resource "aws_s3_bucket" "demo_bucket" {
bucket = var.bucket_name
tags = {
Environment = "dev"
Project = "terraform-ci-cd"
}
}

2. variables.tf for the Terraform Project

variable "aws_region" {
type = string
description = "AWS region to create resources"
default = "ap-south-1"
}
variable "bucket_name" {
type = string
description = "S3 bucket name"
}

3. outputs.tf in the Terraform Setup

output "bucket_name" {
value = aws_s3_bucket.demo_bucket.bucket
}
output "bucket_arn" {
value = aws_s3_bucket.demo_bucket.arn
}

4. GitHub Actions Pipeline for Terraform Automation

Create a folder .github/workflows/ and add the following YAML:

name: Terraform CI/CD
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
jobs:
terraform:
name: Terraform Apply Pipeline
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Checkout source code
uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
- name: Terraform Init
run: terraform init
- name: Terraform Format
run: terraform fmt -check
- name: Terraform Validate
run: terraform validate
- name: Terraform Plan
run: terraform plan -input=false
- name: Terraform Apply
if: github.ref == 'refs/heads/main'
run: terraform apply -auto-approve
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}

📌 Required GitHub Secrets for This Workflow

Navigate to:

GitHub → Repo → Settings → Secrets → Actions

Add the following secrets:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_REGION

🌟 Folder Structure for the Terraform Project

Your project folder should look like this:

terraform-demo/
│
├── main.tf
├── variables.tf
├── outputs.tf
│
└── .github/
└── workflows/
└── terraform.yml

🎉 Deploy the Project to GitHub

To deploy the project, run the following commands:

git add .
git commit -m "Initial Terraform CI/CD pipeline"
git push

Upon pushing, GitHub Actions will automatically:

  • Init
  • Validate
  • Plan
  • Apply