Deploying a Highly Available Web App on AWS Using Terraform

Meriem Terki
4 min readAug 22, 2024

--

We are moving forward in this 30 day terraform challenge and this is day 4.

In today’s blog we’re going to Deploy a web application with high availability involves setting up multiple AWS resources in a reliable and scalable architecture. This guide will walk you through deploying a simple web application on AWS using Terraform, step by step.

Let’s start !

Architecture Diagram

Set Up Steps

Step 1: Setting Up the Terraform Files

main.tf and variables.tf Files:

These files contain the configuration for your AWS resources and the variables that you can customize. Let’s break down each component:

  1. Provider Configuration: The provider block in main.tf configures AWS as the cloud provider and sets the region:
provider "aws" {
region = var.aws_region
}

2. VPC Configuration: A Virtual Private Cloud (VPC) is created to contain your network infrastructure:

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

tags = {
Name = "main-vpc"
}
}

3. Subnets: You create both public and private subnets across multiple availability zones for high availability:

resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index)
availability_zone = element(var.availability_zones, count.index)
map_public_ip_on_launch = true

tags = {
Name = "public-subnet-${count.index}"
}
}

4. Internet Gateway and Route Table: The Internet Gateway provides internet access, and the Route Table routes traffic between subnets:

resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id

tags = {
Name = "main-igw"
}
}

5. Security Groups: Security groups define the firewall rules for the EC2 instances:

resource "aws_security_group" "web_sg" {
vpc_id = aws_vpc.main.id

ingress {
from_port = 80
to_port = 80
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"]
}

tags = {
Name = "web-sg"
}
}

6. EC2 Instances: Two EC2 instances are created in the private subnets:

resource "aws_instance" "web" {
count = 2
ami = var.ami_id
instance_type = var.instance_type
subnet_id = element(aws_subnet.private.*.id, count.index)
security_groups = [aws_security_group.web_sg.name]

user_data = <<-EOF
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "Hello World from $(hostname -f)" > /var/www/html/index.html
EOF

tags = {
Name = "WebServer-${count.index}"
}
}

7. Elastic Load Balancer (ELB): The ELB distributes incoming traffic across the two EC2 instances:

resource "aws_elb" "web_elb" {
name = "web-elb"
availability_zones = var.availability_zones

listener {
instance_port = 80
instance_protocol = "HTTP"
lb_port = 80
lb_protocol = "HTTP"
}

health_check {
target = "HTTP:80/"
interval = 30
timeout = 5
healthy_threshold = 2
unhealthy_threshold = 2
}

instances = aws_instance.web.*.id

tags = {
Name = "WebApp-ELB"
}
}

8. Outputs: Finally, we output the DNS name of the ELB:

output "elb_dns_name" {
value = aws_elb.web_elb.dns_name
}

Variables File (variables.tf): The variables file allows you to define reusable configurations:

variable "aws_region" {
description = "The AWS region to deploy resources in."
default = "us-east-1"
}

variable "vpc_cidr" {
description = "The CIDR block for the VPC."
default = "10.0.0.0/16"
}

variable "availability_zones" {
description = "List of availability zones to use for the subnets."
type = list(string)
default = ["us-east-1a", "us-east-1b"]
}

variable "ami_id" {
description = "AMI ID to use for the EC2 instances."
default = "ami-0230bd60aa48260c6" # Amazon Linux 2 AMI
}

variable "instance_type" {
description = "Instance type for the EC2 instances."
default = "t2.micro"
}

Step 2: Running Terraform Commands

  1. Initialize Terraform:
  • Run terraform init to download the necessary plugins.

2. Plan the Deployment:

  • Execute terraform plan to see what resources will be created.

3. Apply the Configuration:

  • Run terraform apply to create the resources in AWS. Confirm the prompt with "yes."

4. Access the Web Application:

  • Once the deployment is complete, Terraform will output the DNS name of the ELB. You can access your web app using this DNS name.

Note : you have to configure your AWS credentials in the terminal before running the terraform commands by running the command : aws configure

and That’s it !

If you feel that you need an explanation of the code wrote before make sure to check my Notes and the Flashcards I am building you can find them here and it’s going to be updated as long as I move forward in the challenge : https://shadowed-bubble-139.notion.site/30-Day-Terraform-Challenge-dec28b59677845218d72dd4163751c87?pvs=4

And that’s it !

Resources used :

That’s all I have for today folks. Thank you for reading and/or following along! I hope this blog was helpful and worth your while. Stay tuned for my next project on this journey into the cloud.

Let’s connect on LinkedIn! 👉 https://www.linkedin.com/in/meriemterki/

--

--

Meriem Terki
Meriem Terki

Written by Meriem Terki

Data, Cloud & AI enthusiast| Follow me on my journey

No responses yet