Skip to content
Welcome To Charanjit Cheema Blog

Welcome To Charanjit Cheema Blog

An Open Source and Cloud Blog

Menu
  • Home
  • About Me!
  • Way to my Technical Blog
  • Contact me
  • Privacy Policy
Menu

Automating AWS Infrastructure Provisioning in Your CI/CD Pipeline with Terraform and GitHub Actions

Posted on July 7, 2024February 11, 2025 by Charanjit Singh

In this article, I will guide you with the steps on how to provision an instance (VM) in AWS Cloud by using Terraform code and a CICD pipeline that is GitHub Action. But before proceeding further, let me give you a brief overview of Terraform and GitHub Action.

 

Terraform

Terraform is an open-source Infrastructure as Code (IaC) tool developed by HashiCorp. It allows users to define and provision infrastructure using a high-level configuration language. Key features of Terraform include:

  • Declarative Configuration: Users define what the infrastructure should look like, and Terraform handles the provisioning.
  • Provider Plugins: Supports various providers (AWS, Azure, Google Cloud, etc.), enabling management of a wide range of services.
  • State Management: Maintains the state of the infrastructure to track resource changes over time.
  • Execution Plans: Creates execution plans to preview changes before applying them, ensuring infrastructure consistency.
  • Resource Graph: Constructs a dependency graph to determine the correct order for resource creation, modification, or destruction.

GitHub Actions

GitHub Actions is a CI/CD (Continuous Integration and Continuous Deployment) platform that allows users to automate their software development workflows directly from their GitHub repositories. Key features of GitHub Actions include:

  • Workflow Automation: Automates tasks like code testing, building, and deployment.
  • Customizable Workflows: Users can create custom workflows using YAML configuration files.
  • Triggers: Workflows can be triggered by events such as push, pull requests, and issues.
  • Integration with GitHub: Deep integration with GitHub, providing seamless interaction with repositories.
  • Marketplace: Access to a wide range of pre-built actions in the GitHub Marketplace to extend and enhance workflows.
  • Matrix Builds: Supports running jobs in parallel on different environments and configurations.

GitHub Actions is a free and easy to integrate CI/CD solution for GitHub users, it offer simplicity and cost-effectiveness compared to more complex, infrastructure heavy solutions like Jenkins and Azure DevOps, which require additional setup, maintenance, and potential costs for scaling.

Together, Terraform and GitHub Actions can be used to automate the provisioning and management of infrastructure, ensuring consistent and repeatable deployments. By combining Terraform’s powerful IaC capabilities with GitHub Actions flexible automation workflows, teams can streamline their DevOps processes and improve overall efficiency.

 

Now no more theory Lets proceed with Setup 😊

Setting up a GitHub Actions workflow to provision a virtual machine in AWS using Terraform involves several steps. Here’s a basic outline of what you need to do:

  1. Access your AWS Console and locate the AMI ID that matches your OS and architecture on AWS
  2. Create a bucket in Amazon S3 to store the Terraform state file. To learn more, check out my blog: “No More DynamoDB! Use Native S3 Locking for Terraform State.”
  3. Create a GitHub repository for your Terraform configuration.
  4. Write your Terraform script to provision the virtual machine.
  5. Set up GitHub Actions with a workflow file.
  6. Use GitHub Secrets to keep your AWS credentials (such as AWS Access Key and AWS Secret Key) safe. If you do not have these keys, you can create them by following this AWS IAM guide link: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html
  7. Create the workflow file to execute the Terraform script.

 

Step-by-Step Guide

Step 1: Find the AMI ID of your OS and architecture on AWS

To provision the desired OS and architecture of VM in AWS using Terraform, you need to find and get the AMI ID for your choice of OS and architecture. To do this, log in to AWS Console, go to EC2 under compute services, and select AMI catalog under images:

 

Step 2: Create a GitHub Repository

Go to GitHub and create a new repository for your Terraform project.

Example Refer my GitHub link: https://github.com/cjcheema/demo-terra-aws

 

Step 3: Store Your AWS Credentials in GitHub Secrets

Go to your GitHub repository’s settings, then to Secrets and variables under Security, and under Action add the following secrets under repository secretes:

– `AWS_ACCESS_KEY_ID`

– `AWS_SECRET_ACCESS_KEY`

 

Step 4: Write Your Terraform Script

To set up Terraform for provisioning an EC2 instance in AWS, you need to create two key configuration files in your GitHub repository: backend.tf and main.tf. These files define how Terraform stores its state and provisions resources:

backend.tf:

terraform {
backend “s3” {
bucket = “cj-tf-state” # This is the name of the S3 bucket which I created
key = “demo-terra-aws/terraform.tfstate” # This is the name of the state file in the bucket. You can name it whatever you want.
region = “ap-south-1” # This is the region where the bucket is located
use_lockfile = true # This enables native S3 state locking
}
}

Note: Terraform introduced native S3 state locking (use_lockfile = true) as an experimental feature in version 1.10.0, released in November 2024. Ensure you’re using the latest Terraform version. To learn more about this feature, check out my blog.

main.tf

terraform {

required_providers {

aws = {

source = “hashicorp/aws”

version = “5.57.0” # Use the latest provider version refer: https://registry.terraform.io/providers/hashicorp/aws/latest/docs

}

}

}

 

provider “aws” {

region = “ap-south-1”  # Provide your desire AWS region here

}

 

resource “aws_instance” “demo-linux” {

ami           = “ami-01376101673c89611”  # Replace with a valid AMI ID

instance_type = “t2.micro”  # Provide the desire AWS instance type

 

tags = {

Name = “cj-demo-linux” # Provide identical instance name here

}

}

 

Step 5: Set Up GitHub Actions with a Workflow File

Create a directory .github/workflows in your repository and inside it, create a file named terraform.yml.

 

Step 6: Create the Workflow File

Here is an example of a GitHub Actions workflow file terraform.yml to run Terraform:

 

name: Terraform
on:
  push:
    branches:
      – main
  pull_request:
    branches:
      – main
jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
    – name: Checkout code
      uses: actions/checkout@v2
    – name: Setup Terraform
      uses: hashicorp/setup-terraform@v1
    – name: Terraform Init
      run: terraform init # Initialize the Terraform working directory and setup backend (S3 bucket) to store Terraform state file
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        AWS_REGION: ap-south-1 # Change to your desire region
    – name: Terraform Plan
      run: terraform plan
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    – 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 }}

Explanation:

  • Checkout code: Uses the actions/checkout action to check out the code from your repository.
  • Setup Terraform: Uses the hashicorp/setup-terraform action to set up Terraform CLI in the workflow environment.
  • Terraform Init: Initializes the working directory and configures the remote backend in Amazon S3 for state storage.
  • Terraform Plan: Creates an execution plan for Terraform.
  • Terraform Apply: Applies the Terraform plan to provision the resources, only on the main branch.

 

Final Steps

  1. Commit and push your changes to GitHub.

  1. On every push or pull request to the main branch, GitHub Actions will trigger the workflow to run Terraform and provision the VM in AWS. You can see the workflow action under your GitHub repository’s Action:

By clicking on ongoing or completed action you can see detailed information of action which is either being performed or completed:

 

  1. Once GitHub Action completes it action you can see the provisioned VM in AWS Cloud console:

 

 

Wrap up!

This setup ensures that your Terraform configuration is automatically applied whenever changes are pushed to the repository. Combining Terraform and GitHub Actions allows for efficient, automated provisioning of cloud infrastructure. Terraform’s declarative configuration and robust state management ensure consistent and repeatable deployments, while GitHub Actions automates the entire workflow from code changes to infrastructure deployment.

 

 

Loading

  • Author
  • Recent Posts
Charanjit Singh
Follow him
Charanjit Singh
Charanjit is currently working as a Cloud Architect at Mphasis, with 18 years of experience in IT infrastructure projects, implementation, and support. While his main role is as a DevOps engineer, he holds a Cloud Architect position and has strong skills in cloud technologies and automation. His expertise includes Terraform, AWS, Azure DevOps, Azure Cloud, VMware, and Linux systems.

Charanjit is passionate about automating tasks and improving processes. He uses tools like Terraform and Azure DevOps to build and manage cloud infrastructure and streamline deployment. He also enjoys using Shell scripts and Ansible playbooks to make systems run more efficiently.

In his free time, Charanjit enjoys learning about new technologies and sharing his knowledge through his blog. When he’s not working, he likes listening to music, having a cup of coffee, and relaxing in nature.

You can connect with Charanjit on Twitter, Facebook, LinkedIn, or email him at charanjit.cheema@cjcheema.com.
Charanjit Singh
Follow him
Latest posts by Charanjit Singh (see all)
  • How to Deploy Docker Containers with NGINX on AWS EC2 Using Ansible and GitHub Actions - April 26, 2025
  • No More DynamoDB! Use Native S3 locking for Terraform State - February 7, 2025
  • How to Bring and Manage Manually Created AWS Resources Under Terraform Management - January 31, 2025

Like this:

Like Loading...

Related

Leave a ReplyCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Tags

AWS Cloud Computing Dockers Networking Open Networking OpenSource RHEL-CentOS SDN Server Hardware SLES tcpdump Ubuntu WSL

Follow me @

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 2 other subscribers

Recent Posts

  • How to Deploy Docker Containers with NGINX on AWS EC2 Using Ansible and GitHub Actions
  • No More DynamoDB! Use Native S3 locking for Terraform State
  • How to Bring and Manage Manually Created AWS Resources Under Terraform Management
  • Iterating Cloud Resource Provisioning Using Terraform Count and For_Each Meta-Arguments
  • Terraform and Ansible Collaboration for AWS Cloud Deployment

Recent Comments

  1. Charanjit Singh on Terraform and Ansible Collaboration for AWS Cloud Deployment
  2. christinatodd2020aeaa798563 on Terraform and Ansible Collaboration for AWS Cloud Deployment
  3. Charanjit Singh on How to Set password policy in CentOS or RHEL system
  4. SAURABH on How to recover or rebuild initramfs in CentOS 7 Linux
  5. Sangita on How to Set password policy in CentOS or RHEL system

Archives

  • April 2025
  • February 2025
  • January 2025
  • August 2024
  • July 2024
  • June 2024
  • January 2024
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • September 2022
  • August 2022
  • July 2020
  • May 2020
  • February 2020
  • November 2019
  • June 2019
  • May 2019
  • March 2019
  • February 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • June 2018
  • May 2018
  • April 2018

Categories

  • Automation
  • Cloud Computing
  • Coding
  • CyberSecurity
  • Networking
  • OpenSource
  • RHEL-CentOS
  • Server Hardware
  • SLES
  • Technical Blog
  • Ubuntu
  • WSL

Blog Stats

  • 18,353 hits
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Cookie Policy
  • Home
  • About Me!
  • Way to my Technical Blog
  • Contact me
  • Privacy Policy
© 2025 Welcome To Charanjit Cheema Blog | Powered by Superbs Personal Blog theme
 

Loading Comments...
 

    %d