Reputation: 49
I am unable to reach a Fargate task behind an elb load balancer. The webpage loads super slow and eventually it says can not open the page. When I deploy the ECS task without the LoadBalancer and try to access it using it's private ip and port 8501, it seems to work though. Do I maybe need to switch the internet gateway to a nat gateway?
Can somebody maybe spot why that is the case based on my Terraform code:
Thanks a lot.
resource "aws_vpc" "seismic-project-vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "seismic-project-vpc"
}
}
resource "aws_subnet" "seismic-subnet" {
vpc_id = aws_vpc.seismic-project-vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "${var.aws_region}a"
tags = {
Name = "seismic-subnet"
}
}
resource "aws_security_group" "project_security_group" {
name_prefix = "project-security-group"
ingress {
from_port = 0
to_port = 0
protocol = "-1"
self = true
}
ingress {
from_port = 3000
to_port = 3000
protocol = "tcp"
cidr_blocks = [var.my_ip]
}
ingress {
protocol = "tcp"
from_port = 8501
to_port = 8501
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
vpc_id = aws_vpc.seismic-project-vpc.id
}
resource "aws_internet_gateway" "seismic_internet_gateway" {
vpc_id = aws_vpc.seismic-project-vpc.id
}
resource "aws_route_table" "seismic_route_table" {
vpc_id = aws_vpc.seismic-project-vpc.id
}
resource "aws_route" "route" {
route_table_id = aws_route_table.seismic_route_table.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.seismic_internet_gateway.id
}
resource "aws_route_table_association" "seismic_route_table_association" {
subnet_id = aws_subnet.seismic-subnet.id
route_table_id = aws_route_table.seismic_route_table.id
}
resource "aws_iam_role" "ecs_role" {
name = "ecs_role"
assume_role_policy = jsonencode({
Version: "2012-10-17",
Statement: [
{
Effect: "Allow",
Principal: {
Service: "ecs-tasks.amazonaws.com"
},
Action: "sts:AssumeRole"
}
]
})
}
resource "aws_iam_role_policy_attachment" "attach_db_policy" {
policy_arn = aws_iam_policy.dynamodb_policy_read_only.arn
role = aws_iam_role.ecs_role.name
}
resource "aws_iam_role" "ecs_execution_role" {
name = "MyEcsExecutionRole"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = {
Service = "ecs-tasks.amazonaws.com"
},
Action = "sts:AssumeRole"
}
]
})
}
resource "aws_iam_role_policy_attachment" "ecs_execution_attachment" {
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
role = aws_iam_role.ecs_execution_role.name
}
resource "aws_iam_role_policy_attachment" "ecs_cw_attachment" {
policy_arn = "arn:aws:iam::aws:policy/CloudWatchFullAccess"
role = aws_iam_role.ecs_execution_role.name
}
resource "aws_iam_role_policy_attachment" "ecs_sm_attachment" {
policy_arn = "arn:aws:iam::aws:policy/SecretsManagerReadWrite"
role = aws_iam_role.ecs_execution_role.name
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.seismic-project-vpc.id
cidr_block = "10.0.2.0/24"
availability_zone = "${var.aws_region}a"
map_public_ip_on_launch = true
tags = {
Name = "frontend-subnet"
}
}
resource "aws_subnet" "public2" {
vpc_id = aws_vpc.seismic-project-vpc.id
cidr_block = "10.0.3.0/24"
availability_zone = "${var.aws_region}b"
map_public_ip_on_launch = true
tags = {
Name = "frontend-subnet-2"
}
}
resource "aws_security_group" "alb" {
name = "load-balancer-sg"
vpc_id = aws_vpc.seismic-project-vpc.id
ingress {
protocol = "tcp"
from_port = 80
to_port = 80
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
egress {
protocol = "-1"
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
}
resource "aws_lb" "main" {
name = "frontend-lb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = [aws_subnet.public.id, aws_subnet.public2.id]
enable_deletion_protection = false
}
resource "aws_alb_target_group" "main" {
name = "frontend-lb-tg"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.seismic-project-vpc.id
target_type = "ip"
}
resource "aws_alb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = 80
protocol = "HTTP"
default_action {
target_group_arn = aws_alb_target_group.main.arn
type = "forward"
}
}
resource "aws_appautoscaling_target" "ecs_target" {
max_capacity = 2
min_capacity = 1
resource_id = "service/${aws_ecs_cluster.seismic_cluster.name}/${aws_ecs_service.main.name}"
scalable_dimension = "ecs:service:DesiredCount"
service_namespace = "ecs"
}
resource "aws_appautoscaling_policy" "ecs_policy_memory" {
name = "memory-autoscaling"
policy_type = "TargetTrackingScaling"
resource_id = aws_appautoscaling_target.ecs_target.resource_id
scalable_dimension = aws_appautoscaling_target.ecs_target.scalable_dimension
service_namespace = aws_appautoscaling_target.ecs_target.service_namespace
target_tracking_scaling_policy_configuration {
predefined_metric_specification {
predefined_metric_type = "ECSServiceAverageMemoryUtilization"
}
target_value = 90
}
}
resource "aws_ecs_cluster" "seismic_cluster" {
name = "seismic-ecs-cluster"
}
resource "aws_ecs_task_definition" "earthquake_frontend_task" {
family = "frontend"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = 256
memory = 512
execution_role_arn = aws_iam_role.ecs_execution_role.arn
task_role_arn = aws_iam_role.ecs_role.arn
container_definitions = jsonencode([{
name = "frontend-container"
image = "${var.account_id}.dkr.ecr.${var.aws_region}.amazonaws.com/earthquake-frontend:latest"
essential = true
network_mode = "awsvpc"
portMappings = [{
protocol = "tcp"
containerPort = 8501
hostPort = 8501
}]
}])
}
resource "aws_ecs_service" "main" {
name = "earthquake-frontend-service"
cluster = aws_ecs_cluster.seismic_cluster.id
task_definition = aws_ecs_task_definition.earthquake_frontend_task.arn
launch_type = "FARGATE"
scheduling_strategy = "REPLICA"
network_configuration {
security_groups = [aws_security_group.project_security_group.id]
subnets = [aws_subnet.seismic-subnet.id]
assign_public_ip = true
}
load_balancer {
target_group_arn = aws_alb_target_group.main.arn
container_name = "frontend-container"
container_port = 8501
}
depends_on = [
aws_alb_target_group.main
]
}
Upvotes: 0
Views: 222
Reputation: 201048
You need to change the "aws_alb_target_group" "main"
port setting to match your container's port 8501
. Your target group's health checks are almost certainly failing right now, and this change should hopefully be enough to get them passing, but if not you may need to modify the target group's health check settings as well.
Once that is resolved, you should be able to connect via the load balancer's DNS name.
As a side note, it is unclear why you are opening port 3000
in the application's security group, since it only listens on port 8501
.
Upvotes: 0