Multi-Tier Web Application Deployment Using Terraform on AWS

Task Overview

This task involves deploying a 3-tier web application architecture using Terraform on AWS. The architecture consists of:

Terraform will be used to automate infrastructure provisioning.

Architecture Diagram

Components:

Project Implementation Steps

Step 1: Define Terraform Provider

Create a provider.tf file to define AWS as the Terraform provider.

provider "aws" {
  region = "us-east-1"
}

Step 2: Create Networking Components (VPC, Subnets, Route Tables)

Define a VPC and necessary subnets in network.tf.

resource "aws_vpc" "my_vpc" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "public_subnet" {
  vpc_id                  = aws_vpc.my_vpc.id
  cidr_block              = "10.0.1.0/24"
  map_public_ip_on_launch = true
}

resource "aws_subnet" "private_subnet" {
  vpc_id     = aws_vpc.my_vpc.id
  cidr_block = "10.0.2.0/24"
}

Step 3: Create an Application Load Balancer (ALB)

Define ALB to route traffic to the app instances in alb.tf.

resource "aws_lb" "app_alb" {
  name               = "app-load-balancer"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb_sg.id]
  subnets           = [aws_subnet.public_subnet.id]
}

resource "aws_lb_target_group" "app_tg" {
  name     = "app-target-group"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.my_vpc.id
}

resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.app_alb.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app_tg.arn
  }
}

Step 4: Create an EC2 Instance for the Application

Define an EC2 instance and security group in ec2.tf.

resource "aws_security_group" "ec2_sg" {
  vpc_id = aws_vpc.my_vpc.id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "app_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.private_subnet.id
  security_groups = [aws_security_group.ec2_sg.name]

  user_data = <<-EOF
              #!/bin/bash
              yum update -y
              yum install -y httpd
              systemctl start httpd
              systemctl enable httpd
              echo "Hello from App Tier" > /var/www/html/index.html
              EOF
}

Step 5: Configure Auto Scaling for the Application Tier

Define an Auto Scaling Group (ASG) in autoscaling.tf.

resource "aws_launch_configuration" "app_lc" {
  name          = "app-launch-config"
  image_id      = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
}

resource "aws_autoscaling_group" "app_asg" {
  launch_configuration = aws_launch_configuration.app_lc.id
  vpc_zone_identifier  = [aws_subnet.private_subnet.id]
  desired_capacity     = 2
  min_size            = 1
  max_size            = 3
}

Step 6: Deploy a Database Using RDS

Define an RDS instance in rds.tf.

resource "aws_db_instance" "app_db" {
  identifier             = "app-db"
  allocated_storage      = 20
  engine                = "mysql"
  engine_version        = "8.0"
  instance_class        = "db.t2.micro"
  username             = "admin"
  password             = "mypassword"
  publicly_accessible  = false
  vpc_security_group_ids = [aws_security_group.rds_sg.id]
  db_subnet_group_name  = aws_db_subnet_group.db_subnet_group.name
}

Step 7: Configure Security Groups

Define security groups for ALB, EC2, and RDS in security.tf.

resource "aws_security_group" "alb_sg" {
  vpc_id = aws_vpc.my_vpc.id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_security_group" "rds_sg" {
  vpc_id = aws_vpc.my_vpc.id

  ingress {
    from_port   = 3306
    to_port     = 3306
    protocol    = "tcp"
    security_groups = [aws_security_group.ec2_sg.id]
  }
}

Step 8: Output Application and Database Information

Define outputs in outputs.tf.

output "alb_dns_name" {
  value = aws_lb.app_alb.dns_name
}

output "database_endpoint" {
  value = aws_db_instance.app_db.endpoint
  sensitive = true
}

Step 9: Deploy the Infrastructure

Run the following Terraform commands:

terraform init
terraform plan
terraform apply -auto-approve

Step 10: Testing the Deployment

Copy the ALB DNS name from Terraform output and open it in a browser.

You should see Hello from App Tier.

Project Summary

Future Enhancements