Zuxaw
Zuxaw

Reputation: 57

ALB health check failing with 502 error with my terraform config

Hi i'm beginner and i'm trying to play with VPC on AWS and Terraform and i'm stuck on ALB health check issue

enter image description here

I have 2 az with a ec2 and a webserver on each ec2 my goal is to setup the load balancer and be able to be redirected on one of my ec2, my ec2 are on a private subnet and a Nat Gatway and elastic IP

I've tried to setup a bastion host to check on the ssh if my ec2 was well link to internet and the answer is yes

this is my setup terraform : ( baybe there is an obvious error that i haven't seen )

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

provider "aws" {
  shared_credentials_file = "./aws/credentials"
  region = "us-east-1"
}

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support = true

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

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

  tags = {
    Name = "my-internet-gateway"
  }
}

resource "aws_subnet" "public_a" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "us-east-1a"
  map_public_ip_on_launch = true

  tags = {
    Name = "my-public-a-subnet"
  }
}

resource "aws_subnet" "public_b" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.2.0/24"
  availability_zone       = "us-east-1b"
  map_public_ip_on_launch = true

  tags = {
    Name = "my-public-b-subnet"
  }
}

resource "aws_subnet" "private_a" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.3.0/24"
  availability_zone       = "us-east-1a"

  tags = {
    Name = "my-private-a-subnet"
  }
}

resource "aws_subnet" "private_b" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.4.0/24"
  availability_zone       = "us-east-1b"

  tags = {
    Name = "my-private-b-subnet"
  }
}

resource "aws_nat_gateway" "main" {
  allocation_id = aws_eip.main.id
  subnet_id     = aws_subnet.public_a.id
}

resource "aws_eip" "main" {
  vpc = true
  tags = {
    Name = "my-nat-gateway-eip"
  }
}

resource "aws_security_group" "main" {
  name        = "my-security-group"
  description = "Allow HTTP and SSH access"
  vpc_id      = aws_vpc.main.id

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

  ingress {
    from_port   = 22
    to_port     = 22
    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 = "my-security-group"
  }
}

resource "aws_instance" "ec2_a" {
    ami = "ami-0c2b8ca1dad447f8a"
    instance_type = "t2.micro"
    subnet_id = aws_subnet.private_a.id
    vpc_security_group_ids = [aws_security_group.main.id]

    tags = {
      Name = "my-ec2-a"
    }

    key_name = "vockey"
    user_data = file("user_data.sh")
}

resource "aws_instance" "ec2_b" {
    ami = "ami-0c2b8ca1dad447f8a"
    instance_type = "t2.micro"
    subnet_id = aws_subnet.private_b.id
    vpc_security_group_ids = [aws_security_group.main.id]

    tags = {
      Name = "my-ec2-b"
    }

    key_name = "vockey"
    user_data = file("user_data.sh")
}

resource "aws_instance" "bastion" {
  ami = "ami-0c2b8ca1dad447f8a"
  instance_type = "t2.micro"
  subnet_id = aws_subnet.public_a.id
  vpc_security_group_ids = [aws_security_group.main.id]

  tags = {
    Name = "my-bastion"
  }

  key_name = "vockey"
  user_data = file("user_data_bastion.sh")
}

resource "aws_alb" "main" {
  name = "my-alb"
  internal = false
  security_groups = [aws_security_group.main.id]
  subnets = [aws_subnet.public_a.id, aws_subnet.public_b.id]

  tags = {
    Name = "my-alb"
  }
}

resource "aws_alb_target_group" "ec2" {
  name = "my-alb-target-group"
  port = 80
  protocol = "HTTP"
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "my-alb-target-group"
  }
}

resource "aws_route_table" "private" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_nat_gateway.main.id
  }

  tags = {
    Name = "my-private-route-table"
  }

}

resource "aws_route_table_association" "private_a" {
  subnet_id      = aws_subnet.private_a.id
  route_table_id = aws_route_table.private.id
}

resource "aws_route_table_association" "private_b" {
  subnet_id      = aws_subnet.private_b.id
  route_table_id = aws_route_table.private.id
}

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }

  tags = {
    Name = "My Public Route Table"
  }
}

resource "aws_route_table_association" "public_a" {
  subnet_id      = aws_subnet.public_a.id
  route_table_id = aws_route_table.public.id
}

resource "aws_route_table_association" "public_b" {
  subnet_id      = aws_subnet.public_b.id
  route_table_id = aws_route_table.public.id
}


resource "aws_alb_listener" "main" {
  load_balancer_arn = aws_alb.main.arn
  port = "80"
  protocol = "HTTP"

  default_action {
    target_group_arn = aws_alb_target_group.ec2.arn
    type = "forward"
  }
}

resource "aws_alb_target_group_attachment" "ec2_a" {
  target_group_arn = aws_alb_target_group.ec2.arn
  target_id = aws_instance.ec2_a.id
  port = 80
}

resource "aws_alb_target_group_attachment" "ec2_b" {
  target_group_arn = aws_alb_target_group.ec2.arn
  target_id = aws_instance.ec2_b.id
  port = 80
}

Upvotes: 0

Views: 618

Answers (1)

Ben Whaley
Ben Whaley

Reputation: 34416

It looks like you don't have a health_check block on the aws_alb_target_group resource. Try adding something like this:

resource "aws_alb_target_group" "ec2" {
  name = "my-alb-target-group"
  port = 80
  protocol = "HTTP"
  vpc_id = aws_vpc.main.id

  health_check {
    path = "/"
    matcher = "200"
  }

  tags = {
    Name = "my-alb-target-group"
  }
}

Also, make sure that the HTTP services on your EC2 instances are listening and accepting connections on port 80. You should be able to curl http://<ec2 ip address> with a 200 response.

Upvotes: 2

Related Questions