Deploying a Highly Available Web App on AWS Using Terraform
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:
- Provider Configuration: The
provider
block inmain.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
- 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/