I am trying to achieve setup shown in AWS doc (excluding Elastic IP because I am a bit scared to miss conditions described here to avoid possible charges in my Free Tier account) but so far I am only getting 502 Bad Gateway
and not sure what I am missing/doing wrong. Although both instance check are successful ("System reachability check passed" and "Instance reachability check passed"), related Target Groups are "Unhealthy". Any is much appreciated.
Note: I am not experienced in AWS infra setup (nor terraform) but this is best I could produce after going through resources online.
terraform {
required_version = "~> 1.4.4"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.30.0"
}
}
}
provider "aws" {
profile = "development"
region = local.region
}
# -- VARS ----------------------------------------------------------------------
locals {
project = "app"
region = "eu-west-1"
vpc_cidr = "10.0.0.0/16"
public_subnets = {
"a1" = {
az = "${local.region}a"
cidr = "10.0.10.0/24"
},
"b1" = {
az = "${local.region}b"
cidr = "10.0.20.0/24"
}
}
private_subnets = {
"a1" = {
az = "${local.region}a"
cidr = "10.0.135.0/24"
},
"b1" = {
az = "${local.region}b"
cidr = "10.0.145.0/24"
}
}
ec2_ami = "ami-0fb2f0b847d44d4f0" // Amazon Linux 2023 AMI 2023.1.20230705.0 x86_64 HVM kernel-6.1
ec2_instance_type = "t2.micro"
}
# -- VPC -----------------------------------------------------------------------
resource "aws_vpc" "vpc" {
cidr_block = local.vpc_cidr
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = local.project
}
}
# -- ROUTE TABLE ---------------------------------------------------------------
resource "aws_route_table" "public" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = "${local.project}-public"
}
}
resource "aws_route_table" "private" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = "${local.project}-private"
}
}
# -- INTERNET GATEWAY ----------------------------------------------------------
resource "aws_internet_gateway" "public" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = local.project
}
}
resource "aws_route" "public" {
destination_cidr_block = "0.0.0.0/0"
route_table_id = aws_route_table.public.id
gateway_id = aws_internet_gateway.public.id
}
# -- SUBNET --------------------------------------------------------------------
resource "aws_subnet" "public" {
for_each = local.public_subnets
vpc_id = aws_vpc.vpc.id
cidr_block = each.value.cidr
availability_zone = each.value.az
tags = {
Name = "${local.project}-public-${each.key}"
}
}
resource "aws_subnet" "private" {
for_each = local.private_subnets
vpc_id = aws_vpc.vpc.id
cidr_block = each.value.cidr
availability_zone = each.value.az
tags = {
Name = "${local.project}-private-${each.key}"
}
}
resource "aws_route_table_association" "public" {
for_each = local.public_subnets
subnet_id = aws_subnet.public[each.key].id
route_table_id = aws_route_table.public.id
}
resource "aws_route_table_association" "private" {
for_each = local.private_subnets
subnet_id = aws_subnet.private[each.key].id
route_table_id = aws_route_table.private.id
}
# -- SECURITY GROUP ------------------------------------------------------------
resource "aws_security_group" "elb" {
name = "${local.project}-elb"
vpc_id = aws_vpc.vpc.id
ingress {
description = "From Internet to ELB"
from_port = "80"
to_port = "80"
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
description = "From ELB to Internet"
from_port = "0"
to_port = "0"
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group" "ec2" {
name = "${local.project}-ec2"
vpc_id = aws_vpc.vpc.id
ingress {
description = "From ELB to EC2"
from_port = "80"
to_port = "80"
protocol = "tcp"
security_groups = [aws_security_group.elb.id]
}
egress {
description = "From EC2 to ELB"
from_port = "0"
to_port = "0"
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# -- EC2 -----------------------------------------------------------------------
resource "aws_instance" "ec2" {
for_each = local.private_subnets
ami = local.ec2_ami
instance_type = local.ec2_instance_type
subnet_id = aws_subnet.private[each.key].id
vpc_security_group_ids = [aws_security_group.ec2.id]
associate_public_ip_address = true
tags = {
Name = "${local.project}-ec2-private-subnet-${each.key}"
}
}
# -- LOAD BALANCER -------------------------------------------------------------
resource "aws_lb" "application" {
name = "${local.project}-application-load-balancer"
load_balancer_type = "application"
security_groups = [aws_security_group.elb.id]
subnets = [for sub in aws_subnet.public : sub.id]
}
resource "aws_lb_target_group" "application" {
name = "${local.project}-http-application"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.vpc.id
load_balancing_algorithm_type = "least_outstanding_requests"
health_check {
protocol = "HTTP"
port = 80
path = "/"
healthy_threshold = 2
unhealthy_threshold = 2
timeout = 10
interval = 30
matcher = 200
}
}
resource "aws_lb_target_group_attachment" "ec2" {
for_each = aws_instance.ec2
port = 80
target_id = each.value.id
target_group_arn = aws_lb_target_group.application.arn
}
resource "aws_lb_listener" "application" {
load_balancer_arn = aws_lb.application.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.application.arn
}
tags = {
Name = "${local.project}-application-load-listener"
}
}