AWS Infrastructure with Terraform and GitLab CI/CD
terraform fmt -check -recursive
The full learning guide is on this page. Open the repository files only when a step asks you to inspect code, fork the project, or download raw assets.
Project Guide
Section titled “Project Guide”Before starting, ensure you have a basic understanding of:
-
Basic Terraform Knowledge
-
Understanding of CI/CD
-
GitLab CI Knowledge
🛡️ 2026 DevSecOps Enhancements (What You Will Learn)
Section titled “🛡️ 2026 DevSecOps Enhancements (What You Will Learn)”This project’s Terraform architecture and GitLab CI/CD pipeline have been hardened to comply with 2026 DevSecOps IaC standards:
- Infrastructure Security Scanning: A new
tfsecstage has been injected into the.gitlab-ci.yml. The pipeline will now actively fail if Terraform configurations violate AWS security baselines (such as missing encryption or open security groups) before deployment. - Zero Trust EC2 Ingress: The
aws_security_groupconfiguration has been remediated. It no longer allows generalized global ingress (0.0.0.0/0) on sensitive ports like SSH (port 22). It enforces strict IP whitelisting or Systems Manager Session Manager access instead. - OpenTofu Compatibility: The pipeline is fully validated for drop-in compatibility with OpenTofu (the open-source fork of Terraform), ensuring vendor neutrality and licensing freedom.
📝 Prerequisites
Section titled “📝 Prerequisites”-
AWS Account Creation
- Check out the official site to create an AWS account here.
-
GitLab Account
-
Login to GitLab.
-
Sign in via GitHub/Gmail.
-
Verify email and phone.
-
Fill up the questionnaires.
-
Provide group name & project name as per your choice.
-
-
Terraform Installed
-
Check out the official website to install Terraform here.

-
-
AWS CLI Installed
-
Navigate to the IAM dashboard on AWS, then select “Users.”
-
Enter the username and proceed to the next step.

-
Assign permissions by attaching policies directly, opting for “Administrator access,” and then create the user.


-
Locate “Create access key” in user settings, and choose the command line interface (CLI) option to generate an access key.

-
View or download the access key and secret access key either from the console or via CSV download.

Terminal window sudo apt install unzipcurl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"unzip awscliv2.zipsudo ./aws/installaws configure (input created access key id and secret access key)cat ~/.aws/configcat ~/.aws/credentialsaws iam list-users (to list all IAM users in an AWS account) -
-
Code Editor (VS Code)
- Download it from here.
📂 Project Structure
Section titled “📂 Project Structure”The project is divided into two parts:
-
Manual Setup: Write Terraform code, run Terraform commands, and create infrastructure manually.

-
Automation: Create a CI/CD pipeline script on GitLab to automate Terraform resource creation.

Part 1: Manual Setup
Section titled “Part 1: Manual Setup”-
Create a new folder named “cicdtf” and open it in VS Code to start writing the code.

-
Write Terraform code in the “cicdtf” folder:

-
Create a file called
provider.tfto define a provider. -
Deploy a VPC, a security group, a subnet, and an EC2 instance.
-
Folder Structure
Section titled “Folder Structure”1. VPC Module (vpc folder)
Section titled “1. VPC Module (vpc folder)”-
Files:
-
main.tf: Defines resources like VPC, subnets, and security groups. -
variables.tf: Declares input variables for customization. -
outputs.tf: Specifies outputs like VPC ID, subnet IDs, etc.
-
2. EC2 Module (web folder)
Section titled “2. EC2 Module (web folder)”-
Files:
-
main.tf: Configures EC2 instance details, including AMI, instance type, and security groups. -
variables.tf: Defines variables needed for EC2 instance customization. -
outputs.tf: Outputs instance details like public IP, instance ID, etc.
-
-
main.tffor VPC Module
resource "aws_vpc" "main" { cidr_block = "10.0.0.0/16" enable_dns_support = true enable_dns_hostnames = true}
resource "aws_subnet" "main" { vpc_id = aws_vpc.main.id cidr_block = "10.0.1.0/24" map_public_ip_on_launch = true availability_zone = "us-east-1a"}
resource "aws_security_group" "main" { vpc_id = aws_vpc.main.id ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] }}-
Define
outputs.tfin the VPC module:output "pb_sn" {value = aws_subnet.main.id}output "sg" {value = aws_security_group.main.id} -
Define
variables.tfin the EC2 module:variable "subnet_id" {}variable "security_group_id" {}
- Initialize and Validate Terraform:
terraform initterraform validateterraform planterraform apply -auto-approve- Backend Configuration:
- Set up a backend using S3 and DynamoDB.
terraform { backend "s3" { bucket = "my-terraform-state" key = "terraform/state" region = "us-east-1" dynamodb_table = "terraform-lock" }}- Push Code to GitLab:
-
Initialize the GitLab repository and create a
.gitignorefile. -
Create a branch named “dev” and push the code.
git remote add origin https://gitlab.com/your-repo.gitgit checkout -b devgit add .git commit -m "initial commit"git push -u origin dev





Part 2: CI/CD Pipeline
Section titled “Part 2: CI/CD Pipeline”-
Create a GitLab CI/CD pipeline:

-
Write a
.gitlab-ci.ymlfile to automate Terraform commands.
-
Store access keys and secret access keys in GitLab CI/CD variables.


image: hashicorp/terraform:1.9
variables: TF_LOG: DEBUG TF_IN_AUTOMATION: true
cache: paths: - .terraform/
stages: - validate - plan - apply - destroy
validate: script: - terraform init - terraform validate
plan: script: - terraform plan -out=planfile artifacts: paths: - planfile
apply: script: - terraform apply "planfile" when: manual
destroy: script: - terraform destroy -auto-approve when: manual
-
Logs and Execution:

-
Validate stage:
terraform initandterraform validate -
Plan stage:
terraform plan

-
Apply stage:
terraform apply

-
Destroy stage:
terraform destroy


🌟 Final Notes
Section titled “🌟 Final Notes”-
The pipeline performs the following steps:
-
Initializes Terraform with the specified backend configuration.
-
Applies the Terraform plan to create infrastructure resources (VPC, Subnet, Security Group, and EC2 instance).
-
Saves
.terraformdirectory to cache for future use. -
Cleans up the environment after the job is completed.
-
Author by:
Section titled “Author by:”
[!Note] Join Our Telegram Community // Follow me for more DevOps & Cloud content.