← Back to Blog
DevOps2026-05-0412 min read

How to Set Up a CI/CD Pipeline on AWS Using GitHub Actions and Terraform

Learn how to automate deployments on AWS with GitHub Actions and Terraform, including repository setup, S3 backend configuration, ECS deployment, and safe rollback strategy.

The challenge: Manual deployments cause errors, inconsistent environments create bugs, and teams waste time on repetitive tasks. Infrastructure as Code (IaC) with CI/CD pipelines solve all three.

Why Automate Deployment?

Deploying manually takes hours and requires someone to remember the steps. One missed step, and your production environment drifts from the expected state. IaC and CI/CD eliminate human error.

"Our team spent entire days deployments. Now it's automatic and takes 5 minutes. We deploy multiple times per day with confidence." — DevOps Lead

Step 1: Repository Setup

Create a clean folder structure in your GitHub repo:

infra/
  main.tf
  variables.tf
  outputs.tf
app/
  src/
  .github/workflows/
    deploy.yml

Store secrets in GitHub Actions secrets, never in version control. Use AWS IAM roles with least privilege—each deployment job only has permissions it needs.

Step 2: GitHub Actions Workflow

Define a workflow that triggers on push to main:

name: CI/CD
on:
  push:
    branches: [main]
jobs:
  plan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v2
      - run: terraform init
      - run: terraform plan
  apply:
    needs: plan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v2
      - run: terraform apply -auto-approve

Step 3: S3 Backend for State Management

Terraform state must be stored centrally so multiple team members can collaborate safely:

terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "prod/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-lock"
  }
}

DynamoDB locks the state during operations, preventing concurrent modifications that cause corruption.

Step 4: Deploy to ECS or EC2

For ECS: Terraform creates the service and task definition. GitHub Actions builds the Docker image, pushes it to ECR, and GitHub Actions updates the ECS service.

For EC2: Terraform creates instances and security groups. GitHub Actions can then SSH into instances or use CodeDeploy for automatic deployments.

Step 5: Rollback Strategy

Keep the previous task definition revision or AMI available for instant rollback. Use GitHub Actions to revert to the previous state:

# Rollback to previous ECS task definition
aws ecs update-service   --cluster my-cluster   --service my-service   --task-definition my-service:PREVIOUS_REVISION

Technologies Used

GitHub Actions • Terraform • AWS S3 • AWS DynamoDB • AWS ECS • AWS EC2 • Docker • ECR • AWS CodeDeploy

Results & Impact

  • Deployment time reduced from 4 hours to 8 minutes
  • Rollback time improved to 2 minutes vs. manual recovery of 3+ hours
  • Infrastructure state is now version-controlled and auditable
  • Eliminates configuration drift between environments
  • Teams deploy multiple times daily with confidence

Key Learnings

Use separate AWS accounts for prod: If your prod state file is compromised, a bad actor can destroy your entire infrastructure. Separate accounts with cross-account roles are safer.

State file backups are critical: If the S3 bucket is accidentally deleted, you lose your infrastructure. Enable versioning on the state bucket.

Plan before apply: Always review the terraform plan before applying. Automation should never skip human approval for production changes.

Why This Matters

Infrastructure as Code is no longer optional for modern teams. It enables fast iteration, disaster recovery, and audit trails that business teams depend on for compliance.

Build Your CI/CD Pipeline

Related posts

Enterprise Cloud Application with Automated Deployment and Blue-Green Releases

An enterprise cloud application delivery strategy using automated deployments, blue-green releases, and monitoring to maintain reliability for production users.

Read more