I have a terraform-defined ECS cluster with fargate task, service, target group and lb.
I'm trying to send requests to the fargate cluster but it's timing out. I've tried to add an attachment as follows:
resource "aws_lb_target_group_attachment" "websocket-server" {
target_group_arn = aws_lb_target_group.websocket-server.arn
target_id = aws_ecs_cluster.websocket-server-cluster.id
port = 443
}
But unfortunately this throws:
Error registering targets with target group: ValidationError: The IP address 'arn:aws:ecs:eu-west-2:xxxxxx:cluster/websocket-server-cluster' is not a valid IPv4 address
My LB/target group/ECS definitions:
resource "aws_ecs_cluster" "websocket-server-cluster" {
name = "websocket-server-cluster"
}
resource "aws_ecs_service" "websocket-server-service" {
name = "websocket-server-service"
cluster = aws_ecs_cluster.websocket-server-cluster.arn
deployment_maximum_percent = 200
deployment_minimum_healthy_percent = 0
launch_type = "FARGATE"
task_definition = aws_ecs_task_definition.websocket-server-task.arn
load_balancer {
target_group_arn = aws_lb_target_group.websocket-server.arn
container_name = "websocket-server"
container_port = 443
}
network_configuration {
assign_public_ip = true
security_groups = [aws_security_group.public.id, aws_security_group.private.id]
subnets = [aws_subnet.public.id, aws_subnet.private.id]
}
}
module "websocket-server" {
source = "git::https://github.com/cloudposse/terraform-aws-ecs-container-definition.git?ref=tags/0.58.1"
container_name = "websocket-server"
container_image = "${aws_ecr_repository.websocket-server.repository_url}:latest"
container_cpu = "256"
container_memory = "512"
port_mappings = [
{
containerPort = 443
hostPort = 443
protocol = "tcp"
}
]
environment = []
}
resource "aws_ecs_task_definition" "websocket-server-task" {
family = "websocket-server"
requires_compatibilities = ["FARGATE"]
memory = "512"
cpu = "256"
task_role_arn = aws_iam_role.ecs-container-role.arn
execution_role_arn = aws_iam_role.ecs-container-role.arn
network_mode = "awsvpc"
container_definitions = module.websocket-server.json_map_encoded_list
lifecycle {
ignore_changes = [
tags, tags_all
]
}
}
resource "aws_lb" "main" {
name = "main"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.public.id, aws_security_group.private.id]
enable_deletion_protection = false
subnets = [aws_subnet.public.id, aws_subnet.public-backup.id]
}
resource "aws_lb_target_group" "websocket-server" {
name = "websocket-server"
port = 443
protocol = "HTTPS"
vpc_id = aws_vpc.main.id
target_type = "ip"
health_check {
enabled = true
healthy_threshold = 3
unhealthy_threshold = 3
timeout = 10
protocol = "HTTPS"
path = "/apis/websocket-server/health"
interval = "100"
matcher = "200"
}
depends_on = [
aws_lb.main
]
}
resource "aws_lb_listener" "websocket-server" {
load_balancer_arn = aws_lb.main.arn
port = "443"
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2016-08"
certificate_arn = aws_acm_certificate.main.arn
default_action {
target_group_arn = aws_lb_target_group.websocket-server.arn
type = "forward"
}
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = "80"
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
resource "aws_lb_listener_certificate" "main" {
listener_arn = aws_lb_listener.websocket-server.arn
certificate_arn = aws_acm_certificate.main.arn
}
CodePudding user response:
The attachment definition is not necessary at all. Keep in mind, containers for Fargate services do not use network interfaces of the underlying EC2 instances in the cluster (you don't see the instances at all for that matter). They use AWS VPC networking mode only -- independent network interfaces in the VPC are attached to the containers.
The target group attachment happens automatically and is configured through the load_balancer
block in the aws_ecs_service
resource. As ECS starts the containers, they get registered with the target group automatically. There is no static attachment to define in the case of Fargate ECS services.
Just remove the tg attachment resource from your tf file altogether.
Check out this resource for a decent reference implementation with terraform.
As a completely separate side note, you probably also do not want assign_public_ip = true
in your service configuration. That would allow access to your containers directly without going through the load balancer which is almost never what you want when you're using a load balancer.