Skip to content

AWS Infrastructure with Terraform and GitLab CI/CD

Level:Intermediate
Time:2-3 hours
Cost:medium
Works locally:No
Cloud creds:Yes
Cleanup:Yes
Reviewed:2026-05-30
Validation:terraform fmt -check -recursive

Modular AWS Terraform project with GitLab CI configuration.

Outcome Passing pipeline run plus scan/deploy evidence
Tools used Terraform, GitLab CI, AWS
Best fit Intermediate - 2-3 hours
Student workstation Repository files CI/CD pipeline AWS account Validation proof
  • Install or review: Terraform, GitLab CI, AWS.
  • Use your own cloud account credentials and keep them out of commits.
  • This project expects cloud resources, so verify budget alerts and cleanup first.
  • Open the safety guide before running commands that create infrastructure.
Cost and credential stance

Cost risk is medium. Cloud target: AWS. Cloud credentials needed: Yes. Always use your own account, never commit secrets, and confirm cleanup before creating paid infrastructure.

Use this flow before you run commands:

  1. Read the cost and credential warning above.
  2. Review the validation, troubleshooting, cleanup, and portfolio proof sections below.
  3. Follow the original project guide preserved near the bottom of this page.
  4. Return to the validation and cleanup checks before you capture portfolio evidence.

Run the project validation command before and after meaningful changes:

Terminal window
terraform fmt -check -recursive
  • Run terraform fmt -check -recursive first so local tooling issues are visible early.
  • If a command fails, check tool versions, working directory, and required environment variables.
  • For cloud failures, confirm account identity, region, quotas, and least-privilege IAM.
  • For pipeline failures, check repository secrets, runner permissions, and pinned action versions.

Cleanup is available or expected for this lab. Use the cleanup or destroy steps in the guide below, then confirm that local clusters, containers, cloud resources, buckets, state files, and CI secrets are no longer active.

  • Validation command output: terraform fmt -check -recursive
  • Screenshot or terminal proof: Passing pipeline run plus scan/deploy evidence
  • Notes explaining what changed, what failed, and how you fixed it
  • Cleanup evidence, especially for cloud or Kubernetes resources

The original README content is preserved here for lab-specific commands and context. Headings are intentionally demoted so the page outline stays focused on the standard lab flow.

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:

  1. Infrastructure Security Scanning: A new tfsec stage 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.
  2. Zero Trust EC2 Ingress: The aws_security_group configuration 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.
  3. 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.
  1. AWS Account Creation

    • Check out the official site to create an AWS account here.
  2. 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.

  3. Terraform Installed

    • Check out the official website to install Terraform here.
External image reference Source image
  1. AWS CLI Installed

    • Navigate to the IAM dashboard on AWS, then select “Users.”

    • Enter the username and proceed to the next step.

External image reference Source image
* Assign permissions by attaching policies directly, opting for "Administrator access," and then create the user.
External image reference Source image
External image reference Source image
* Locate "Create access key" in user settings, and choose the command line interface (CLI) option to generate an access key.
External image reference Source image
* View or download the access key and secret access key either from the console or via CSV download.
External image reference Source image
```bash
sudo apt install unzip
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws configure (input created access key id and secret access key)
cat ~/.aws/config
cat ~/.aws/credentials
aws iam list-users (to list all IAM users in an AWS account)
```

5. Code Editor (VS Code)

* Download it from <a href="https://code.visualstudio.com/download" target="_blank" rel="noopener noreferrer">here</a>.

The project is divided into two parts:

  1. Manual Setup: Write Terraform code, run Terraform commands, and create infrastructure manually.
External image reference Source image
  1. Automation: Create a CI/CD pipeline script on GitLab to automate Terraform resource creation.
External image reference Source image
  1. Create a new folder named “cicdtf” and open it in VS Code to start writing the code.
External image reference Source image
  1. Write Terraform code in the “cicdtf” folder:
External image reference Source image
* Create a file called `provider.tf` to define a provider.
* Deploy a VPC, a security group, a subnet, and an EC2 instance.
  • 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.

  • 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.

External image reference Source image
  • main.tf for 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.tf in the VPC module:

    output "pb_sn" {
    value = aws_subnet.main.id
    }
    output "sg" {
    value = aws_security_group.main.id
    }
  • Define variables.tf in the EC2 module:

    variable "subnet_id" {}
    variable "security_group_id" {}
  1. Initialize and Validate Terraform:
Terminal window
terraform init
terraform validate
terraform plan
terraform apply -auto-approve
  1. Backend Configuration:
  • Set up a backend using S3 and DynamoDB.
#### backend.tf
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "terraform/state"
region = "us-east-1"
dynamodb_table = "terraform-lock"
}
}
  1. Push Code to GitLab:
  • Initialize the GitLab repository and create a .gitignore file.

  • Create a branch named “dev” and push the code.

Terminal window
git remote add origin https://gitlab.com/your-repo.git
git checkout -b dev
git add .
git commit -m "initial commit"
git push -u origin dev
External image reference Source image
External image reference Source image
External image reference Source image
External image reference Source image
External image reference Source image
External image reference Source image
  1. Create a GitLab CI/CD pipeline:
External image reference Source image
  • Write a .gitlab-ci.yml file to automate Terraform commands.
External image reference Source image
  • Store access keys and secret access keys in GitLab CI/CD variables.
External image reference Source image
External image reference Source image
#### .gitlab-ci.yml
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
External image reference Source image
  1. Logs and Execution:
External image reference Source image
  • Validate stage: terraform init and terraform validate

  • Plan stage: terraform plan

External image reference Source image
External image reference Source image
  • Apply stage: terraform apply
External image reference Source image
External image reference Source image
  1. Destroy stage: terraform destroy
External image reference Source image
External image reference Source image
External image reference Source image
  • 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 .terraform directory to cache for future use.

    • Cleans up the environment after the job is completed.

External image reference Source image

[!Note] Join Our Telegram Community // Follow me for more DevOps & Cloud content.

Use the guide first.

The full learning flow stays on this page. Open GitHub only when a step asks you to inspect code, fork the lab, or download source assets.