Last active
April 29, 2024 17:25
-
-
Save MoeAhmed11/8eece9a9cb055c5f06fc91e45fd21c1e to your computer and use it in GitHub Desktop.
ASG on AWS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#main.tf | |
# Terraform Resources | |
#Create a new VPC in AWS | |
resource "aws_vpc" "vpc" { | |
cidr_block = var.vpc_cidr | |
tags = { | |
Name = "TerraformVPC" | |
} | |
} | |
#AWS Availability Zones | |
data "aws_availability_zones" "available" { | |
state = "available" | |
} | |
# Security Group for ALB allowing requests from any IP address | |
resource "aws_security_group" "alb_security_group" { | |
name = "${var.environment}-alb-security-group" | |
description = "ALB Security Group" | |
vpc_id = aws_vpc.vpc.id | |
ingress { | |
description = "HTTP from Internet" | |
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 = "${var.environment}-alb-security-group" | |
} | |
} | |
# Security Group for ASG allowing requests only from ALB | |
resource "aws_security_group" "asg_security_group" { | |
name = "${var.environment}-asg-security-group" | |
description = "ASG Security Group" | |
vpc_id = aws_vpc.vpc.id | |
ingress { | |
description = "HTTP from ALB" | |
from_port = 80 | |
to_port = 80 | |
protocol = "tcp" | |
security_groups = [aws_security_group.alb_security_group.id] | |
} | |
egress { | |
from_port = 0 | |
to_port = 0 | |
protocol = "-1" | |
cidr_blocks = ["0.0.0.0/0"] | |
} | |
tags = { | |
Name = "${var.environment}-asg-security-group" | |
} | |
} | |
#Internet Gateway to enable internet connectivity | |
resource "aws_internet_gateway" "internet_gateway" { | |
vpc_id = aws_vpc.vpc.id | |
tags = { | |
Name = "Terraform_internet_gateway" | |
} | |
} | |
#Create 2 Public Subnets | |
resource "aws_subnet" "public_subnet" { | |
count = 2 | |
vpc_id = aws_vpc.vpc.id | |
cidr_block = var.public_subnet_cidr[count.index] | |
map_public_ip_on_launch = true | |
availability_zone = data.aws_availability_zones.available.names[count.index] | |
tags = { | |
Name = join("-", ["${var.environment}-public-subnet", data.aws_availability_zones.available.names[count.index]]) | |
} | |
} | |
#Route table for public subnets, this ensures that all instances launched in public subnet will have access to the internet | |
resource "aws_route_table" "public_route_table" { | |
vpc_id = aws_vpc.vpc.id | |
route { | |
cidr_block = "0.0.0.0/0" | |
gateway_id = aws_internet_gateway.internet_gateway.id | |
} | |
tags = { | |
Name = "${var.environment}-public-route-table" | |
} | |
} | |
#public subnet will be associated with the public route table | |
resource "aws_route_table_association" "public_rt_assoc" { | |
count = 2 | |
subnet_id = aws_subnet.public_subnet[count.index].id | |
route_table_id = aws_route_table.public_route_table.id | |
} | |
# Application Load Balancer Resources | |
resource "aws_lb" "alb" { | |
name = "${var.environment}-alb" | |
internal = false | |
load_balancer_type = "application" | |
security_groups = [aws_security_group.alb_security_group.id] | |
subnets = [for i in aws_subnet.public_subnet : i.id] | |
} | |
#creating a target group that listens on port 80 and uses the HTTP protocol. | |
resource "aws_lb_target_group" "target_group" { | |
name = "${var.environment}-TG" | |
port = 80 | |
protocol = "HTTP" | |
vpc_id = aws_vpc.vpc.id | |
health_check { | |
path = "/" | |
matcher = 200 | |
} | |
} | |
#Create a linstener for HTTP using port 80, attached to the ALB | |
resource "aws_lb_listener" "alb_listener" { | |
load_balancer_arn = aws_lb.alb.arn | |
port = "80" | |
protocol = "HTTP" | |
default_action { | |
type = "forward" | |
target_group_arn = aws_lb_target_group.target_group.arn | |
} | |
tags = { | |
Name = "${var.environment}-alb-listenter" | |
} | |
} | |
#Create an Auto Scaling Group, specifying the capacity, target group and launch template | |
resource "aws_autoscaling_group" "auto_scaling_group" { | |
name = "my-autoscaling-group" | |
desired_capacity = 1 | |
max_size = 2 | |
min_size = 1 | |
vpc_zone_identifier = flatten([ | |
aws_subnet.public_subnet.*.id, | |
]) | |
target_group_arns = [ | |
aws_lb_target_group.target_group.arn, | |
] | |
launch_template { | |
id = aws_launch_template.launch_template.id | |
version = aws_launch_template.launch_template.latest_version | |
} | |
} | |
#Data source to get the latest Amazon Linux 2 AMI | |
data "aws_ami" "app_ami" { | |
most_recent = true | |
filter { | |
name = "name" | |
values = [var.ami_filter.name] | |
} | |
filter { | |
name = "virtualization-type" | |
values = ["hvm"] | |
} | |
owners = [var.ami_filter.owner] | |
} | |
#Create a launch template to launch instances on the ASG | |
resource "aws_launch_template" "launch_template" { | |
name = "${var.environment}-launch-template" | |
image_id = data.aws_ami.app_ami.id | |
instance_type = var.instance_type | |
network_interfaces { | |
device_index = 0 | |
security_groups = [aws_security_group.asg_security_group.id] | |
} | |
tag_specifications { | |
resource_type = "instance" | |
tags = { | |
Name = "${var.environment}-asg-ec2" | |
} | |
} | |
user_data = base64encode("${var.ec2_user_data}") | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#outputs.tf | |
#Terraform Outputs | |
output "alb_public_url" { | |
description = "Public URL for Application Load Balancer" | |
value = aws_lb.alb.dns_name | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#providers.tf | |
#Terraform Providers | |
terraform { | |
required_providers { | |
aws = { | |
source = "hashicorp/aws" | |
version = "~> 5.47.0" | |
} | |
} | |
} | |
provider "aws" { | |
region = "us-east-1" | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#variables.tf | |
#Variable used to specify AMI used for instances in the ASG | |
variable "ami" { | |
description = "ami of ec2 instance" | |
type = string | |
default = "ami-04e5276ebb8451442" | |
} | |
# Launch Template and ASG Variables | |
variable "instance_type" { | |
description = "launch template EC2 instance type" | |
type = string | |
default = "t2.micro" | |
} | |
#Variable used to filter marketplace AMIs to select Amazon Linux AMI | |
variable "ami_filter" { | |
description = "Name filter and owner for AMI" | |
type = object ({ | |
name = string | |
owner = string | |
}) | |
default = { | |
name = "al2023-ami-2023.4.20240416.0-kernel-6.1-x86_64" | |
owner = "137112412989" | |
} | |
} | |
#This user data variable indicates that the script configures Apache on a server. | |
variable "ec2_user_data" { | |
description = "variable indicates that the script configures Apache on a server" | |
type = string | |
default = <<EOF | |
#!/bin/bash | |
yum update -y | |
yum install -y httpd | |
systemctl start httpd | |
systemctl enable httpd | |
echo "<h1>Hello World from $(hostname -f)</h1>" > /var/www/html/index.html | |
EOF | |
} | |
# VPC Variables | |
variable "vpc_cidr" { | |
description = "VPC cidr block" | |
type = string | |
default = "10.10.0.0/16" | |
} | |
#These Public subnets are used for resources that need to be accessible from the internet | |
variable "public_subnet_cidr" { | |
description = "Public Subnet cidr block" | |
type = list(string) | |
default = ["10.10.0.0/24", "10.10.2.0/24"] | |
} | |
#Environement variable, specifying name if the environment | |
variable "environment" { | |
description = "Environment name for deployment" | |
type = string | |
default = "ASG-Terraform" | |
} | |
#Region Variable | |
variable "aws_region" { | |
description = "AWS region name" | |
type = string | |
default = "us-east-1" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment