AWS-Terraform-3tier-WebApp

Deploying a 3-Tier Web App on AWS Using Terraform & GitLab CI/CD

A step-by-step guide for automating AWS infrastructure deployment using Infrastructure as Code and CI/CD pipelines.


๐Ÿงญ Introduction

As part of my cloud journey, I recently built a 3-tier web application architecture on AWS using Terraform for Infrastructure as Code and GitLab CI/CD for automation. This project demonstrates how to deploy scalable, production-ready infrastructure including:

  • VPC with subnets

  • EC2 instances behind an Application Load Balancer (ALB)

  • RDS MySQL for data storage

  • Automation using GitLab CI/CD pipelines

In this blog, Iโ€™ll walk you through each phase of the deployment, share Terraform code snippets, and explain the DevOps workflows. Screenshots and links to the GitHub repo are included.


๐Ÿ—๏ธ Architecture Overview

The goal was to design and deploy the following:

            +---------------+
            |  Load Balancer|
            +------+--------+
                   |
        +----------+----------+
        |                     |
    +---+---+             +---+---+
    | EC2-1 |             | EC2-2 |   <- App Layer (Autoscaled EC2)
    +-------+             +-------+
        |                     |
        +----------+----------+
                   |
            +------+--------+
            |   RDS MySQL    |    <- Database Layer
            +---------------+

This structure supports high availability and can be further extended with monitoring, S3, and DNS integrations.


๐ŸŽฏ Project Goals

  • Automate infrastructure setup using Terraform modules

  • Use GitLab CI/CD to validate, plan, and apply changes

  • Provision EC2 instances with NGINX using cloud-init

  • Ensure secure RDS deployment within private subnets

  • Keep infrastructure reproducible and scalable


๐Ÿ“ Project Repository

GitHub Repo: aws-terraform-3tier

Technologies used:

  • Terraform

  • AWS (EC2, ALB, RDS, VPC)

  • GitLab CI/CD

  • Bash / cloud-init

  • Linux/Ubuntu


๐Ÿš€ Phase 1: Setting Up Terraform Structure

I organized my Terraform code into separate modules:

  • vpc.tf โ€“ Creates VPC, subnets, route tables

  • ec2.tf โ€“ Launch template and Auto Scaling group

  • alb.tf โ€“ Application Load Balancer and listener

  • rds.tf โ€“ RDS MySQL setup

  • variables.tf, outputs.tf, main.tf โ€“ Configuration and outputs

Screenshot: Terraform directory structure

Terraform Directory Structure

To validate and deploy:

terraform init
terraform plan
terraform apply

๐ŸŒ Phase 2: AWS Infrastructure Deployment

Once the Terraform files were in place, the AWS infrastructure was created. Here's how the major components worked:

โœ… VPC and Subnets

resource "aws_vpc" "main" {
  cidr_block = var.vpc_cidr
}

โœ… EC2 Instances with Auto Scaling

resource "aws_autoscaling_group" "web_asg" {
  desired_capacity = 2
  launch_template {
    id = aws_launch_template.web.id
    version = "$Latest"
  }
}

Screenshot: EC2 instances running in the AWS Console

EC2 Instances Running

โœ… RDS MySQL

resource "aws_db_instance" "default" {
  engine = "mysql"
  instance_class = "db.t3.micro"
}

Screenshot: RDS MySQL instance

RDS Instance Screenshot


๐Ÿ” Phase 3: Provisioning EC2 with NGINX

To automate provisioning, I used a cloud-init script (user_data.sh) to install and configure NGINX:

#!/bin/bash
apt update -y
apt install -y nginx
echo "<h1>Deployed via Terraform</h1>" > /var/www/html/index.html

Screenshot: App page deployed on EC2

Deployed NGINX App


โš™๏ธ Phase 4: CI/CD with GitLab

To enable continuous integration and deployment, I set up a GitLab pipeline defined in .gitlab-ci.yml. It runs three stages:

๐Ÿ”ง Pipeline Stages:

stages:
  - validate
  - plan
  - apply

๐Ÿ” Environment Variables in GitLab:

Add these in GitLab CI/CD settings:

  • AWS_ACCESS_KEY_ID

  • AWS_SECRET_ACCESS_KEY

๐Ÿงช Validate Stage

Runs basic Terraform checks.

validate:
  stage: validate
  script:
    - terraform init
    - terraform fmt -check
    - terraform validate

๐Ÿ“ Plan Stage

Generates the execution plan.

plan:
  stage: plan
  script:
    - terraform plan -out=tfplan

๐Ÿš€ Apply Stage

Applies infrastructure changes.

apply:
  stage: apply
  when: manual
  script:
    - terraform apply -auto-approve tfplan

Screenshot: GitLab CI/CD pipeline run

GitLab Pipeline


๐Ÿงช Phase 5: Testing and Final Output

After deployment, I tested the final setup:

  • Load Balancer DNS opened the web app deployed via EC2

  • RDS MySQL was accessible within the VPC (via security groups)

Screenshot: App output via ALB URL

Final App Output


๐Ÿง  Lessons Learned

  • Terraform modules make infrastructure reusable and clean.

  • GitLab CI/CD integrates smoothly with AWS workflows.

  • IAM permissions and network settings require attention to detail.


๐Ÿš€ Next Steps

  • Add HTTPS via ACM + Route 53

  • Integrate CloudWatch for monitoring

  • Use S3 backend for Terraform state


๐Ÿ”— Resources


๐Ÿ™Œ Conclusion

This project strengthened my skills in cloud architecture, automation, and DevOps practices. Iโ€™m excited to keep exploring and refining my infrastructure workflows!

If you found this helpful or have questions, feel free to connect on LinkedIn or comment on the GitHub repo!


0
Subscribe to my newsletter

Read articles from pradeep mahadevaiah directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

pradeep mahadevaiah
pradeep mahadevaiah