Terraform AWS ALB which manages multiple Fargate services problem

Viewed 23

Hi I have the following infrastructure on AWS:

  1. API gateway
  2. VPC link on NLB
  3. An ALB
  4. A target group with
target_type = "alb"
  1. A cluster ECS with 3 services (on 8083, 8084, 8085 ports). Every service with a Fargate task.
  2. Two security group: one on ALB and one for ECS task
  3. A VPC with 2 public subnet e 2 private subnet
  4. An IG
  5. A NAT (for external access from private subnets)

I made the described configuration using the AWS Console on the eu-south-1 region, and everything works. Now I would like to migrate everything to the us-east-1 region and for this reason I made some scripts with Terraform

ALB

resource "aws_lb" "alb-block-forgery" {

  name                       = "${var.name}-alb-${var.environment}"
  desync_mitigation_mode     = "defensive"
  drop_invalid_header_fields = "false"
  enable_deletion_protection = "false"
  enable_http2               = "true"
  enable_waf_fail_open       = "false"
  idle_timeout               = "60"
  internal                   = "true"
  ip_address_type            = "ipv4"
  load_balancer_type         = "application"
  preserve_host_header       = "false"
  security_groups            = var.alb_security_groups
  subnets                    = var.subnets.*.id
}

NLB

resource "aws_lb" "nlb-block-forgery" {

  name                             = "${var.name}-nlb-${var.environment}"
  enable_cross_zone_load_balancing = "true"
  enable_deletion_protection       = "false"
  internal                         = "false"
  ip_address_type                  = "ipv4"
  load_balancer_type               = "network"
  subnets                          = var.subnets.*.id
}

ALB TG

resource "aws_lb_target_group" "alb-block-forgery-tg" {
    name        = "${var.name}-alb-tg-${substr(uuid(), 0, 3)}-${var.environment}" 
    deregistration_delay = "300"

    health_check {
      enabled             = "true"
      healthy_threshold   = "5"
      interval            = "30"
      matcher             = "200"
      path                = "/"
      port                = "traffic-port"
      protocol            = "HTTP"
      timeout             = "5"
      unhealthy_threshold = "2"
    }

    load_balancing_algorithm_type = "round_robin"
    port                          = "80"
    protocol                      = "HTTP"
    protocol_version              = "HTTP1"
    slow_start                    = "0"

    stickiness {
      cookie_duration = "86400"
      enabled         = "false"
      type            = "lb_cookie"
    }

    target_type = "ip"
    vpc_id      =  var.vpc_id

  lifecycle {
    ignore_changes        = [name]
    create_before_destroy = true
  }
}

NLB TG


resource "aws_lb_target_group" "nlb-block-forgery-tg" {
  name        = "${var.name}-nlb-tg-${substr(uuid(), 0, 3)}-${var.environment}" 
  port        = 80
  protocol    = "TCP"
  target_type = "alb"
  vpc_id      =  var.vpc_id

  lifecycle {
    ignore_changes        = [name]
    create_before_destroy = true
  }
}

DEFAULT TG

resource "aws_lb_target_group" "backend-tg" {
  name        = "${var.name}-backend-tg-${var.environment}"    
  deregistration_delay = var.deregistration_delay
  vpc_id      =  var.vpc_id

  health_check {
    enabled             = "true"
    healthy_threshold   = "5"
    interval            = var.health_check_interval
    matcher             = "200"
    path                = "/api/v1/blockforgery/signUp/healthCheck"
    port                = "traffic-port"
    protocol            = "HTTP"
    timeout             = "5"
    unhealthy_threshold = "2"
  }

  load_balancing_algorithm_type = "round_robin"
  port                          = "8083"
  protocol                      = "HTTP"
  protocol_version              = "HTTP1"
  slow_start                    = "0"

  stickiness {
    cookie_duration = "86400"
    enabled         = "false"
    type            = "lb_cookie"
  }

  target_type = "ip"

  tags = {
    Name        = "${var.name}-backend-tg-${var.environment}"
    Environment = var.environment
  }
}

FARGATE SERVICE1 TG

resource "aws_lb_target_group" "venly-srv-tg" {
  name        = "venly-srv-tg-${var.environment}"    
  deregistration_delay = var.deregistration_delay
  vpc_id      =  var.vpc_id

  health_check {
    enabled             = "true"
    healthy_threshold   = "5"
    interval            = var.health_check_interval
    matcher             = "200"
    path                = "/api/v1/blockforgery/create-wallet/healthCheck"
    port                = "traffic-port"
    protocol            = "HTTP"
    timeout             = "5"
    unhealthy_threshold = "2"
  }

  load_balancing_algorithm_type = "round_robin"
  port                          = "8084"
  protocol                      = "HTTP"
  protocol_version              = "HTTP1"
  slow_start                    = "0"

  stickiness {
    cookie_duration = "86400"
    enabled         = "false"
    type            = "lb_cookie"
  }

  target_type = "ip"
  
  tags = {
    Name        = "venly-srv-tg-${var.environment}"
    Environment = var.environment
  }  
}

FARGATE SERVICE2 TG

resource "aws_lb_target_group" "blockchain-srv-tg" {
  name        = "blockchain-srv-tg-${var.environment}"    
  deregistration_delay = var.deregistration_delay
  vpc_id      =  var.vpc_id

  health_check {
    enabled             = "true"
    healthy_threshold   = "5"
    interval            = var.health_check_interval    
    matcher             = "200"
    path                = "/api/v1/blockforgery/feed/healthCheck"
    port                = "traffic-port"
    protocol            = "HTTP"
    timeout             = "5"
    unhealthy_threshold = "2"
  }

  load_balancing_algorithm_type = "round_robin"
  port                          = "8085"
  protocol                      = "HTTP"
  protocol_version              = "HTTP1"
  slow_start                    = "0"

  stickiness {
    cookie_duration = "86400"
    enabled         = "false"
    type            = "lb_cookie"
  }

  target_type = "ip"

  tags = {
    Name        = "blockchain-srv-tg-${var.environment}"
    Environment = var.environment
  }
}

ALB and NLB LISTNER

resource "aws_lb_listener" "tcp-alb" {

  default_action {
    order            = "1"
    target_group_arn = aws_lb_target_group.backend-tg.id
    type             = "forward"
  }

  load_balancer_arn = aws_lb.alb-block-forgery.arn
  port              = "80"
  protocol          = "HTTP"
}

resource "aws_lb_listener" "tcp-nlb" {

  default_action {
    target_group_arn = aws_lb_target_group.nlb-block-forgery-tg.id
    type             = "forward"
  }

  load_balancer_arn = aws_lb.nlb-block-forgery.arn
  port              = "80"
  protocol          = "TCP"
}

ALB LISTNER RULE

resource "aws_lb_listener_rule" "blockchain-srv" {

  action {
    order            = "1"
    target_group_arn = aws_lb_target_group.blockchain-srv-tg.arn
    type             = "forward"
  }

  condition {
    path_pattern {
      values = ["/api/v1/blockforgery/feed", "/api/v1/blockforgery/feed/*"]
    }
  }

  listener_arn = aws_lb_listener.tcp-alb.id
  priority     = "2"
}

resource "aws_lb_listener_rule" "venly-srv" {

  action {
    order            = "1"
    target_group_arn = aws_lb_target_group.venly-srv-tg.arn
    type             = "forward"
  }

  condition {
    path_pattern {
      values = ["/api/v1/blockforgery/create-wallet", "/api/v1/blockforgery/create-wallet/*"]
    }
  }

  listener_arn = aws_lb_listener.tcp-alb.id
  priority     = "3"
}

ECS SERVICE 1 (OK)

resource "aws_ecs_service" "backend" {
  name                               = "${var.name}-backend"
  cluster                            = aws_ecs_cluster.main.id
  task_definition                    = aws_ecs_task_definition.backend.arn
  desired_count                      = var.replicas_backend
  deployment_maximum_percent         = "200"
  deployment_minimum_healthy_percent = "100"
  enable_ecs_managed_tags            = "true"
  enable_execute_command             = "false"
  health_check_grace_period_seconds  = "25"
  launch_type                        = "FARGATE"

  load_balancer {
    container_name   = var.task_name_backend
    container_port   = var.container_blockforgery_backend_port
    target_group_arn = var.aws_alb_target_group_backend_arn
  }

  network_configuration {
    assign_public_ip = "false"
    security_groups  = var.ecs_service_security_groups
    subnets          = var.subnets.*.id
  }

  deployment_circuit_breaker {
    enable   = "false"
    rollback = "false"
  }

  deployment_controller {
    type = "ECS"
  }

  platform_version    = "LATEST"
  propagate_tags      = "TASK_DEFINITION"
  scheduling_strategy = "REPLICA"

  lifecycle {
   ignore_changes = [task_definition, desired_count]
 }
}

ECS SERVICE 2 (KO)

resource "aws_ecs_service" "venly-srv" {
  name                               = "${var.name}-venly-srv"
  cluster                            = aws_ecs_cluster.main.id
  task_definition                    = aws_ecs_task_definition.venly-srv-task.arn
  desired_count                      = var.replicas_venly_srv
  deployment_maximum_percent         = "200"
  deployment_minimum_healthy_percent = "100"
  enable_ecs_managed_tags            = "true"
  enable_execute_command             = "false"
  health_check_grace_period_seconds  = "0"
  launch_type                        = "FARGATE"

  load_balancer {
    container_name   = var.task_name_venly_srv
    container_port   = var.container_blockforgery_venly_srv_port
    target_group_arn = var.aws_alb_target_group_venly_srv_arn
  }


  network_configuration {
    assign_public_ip = "false"
    security_groups  = var.ecs_service_security_groups
    subnets          = var.subnets.*.id
  }

  deployment_circuit_breaker {
    enable   = "false"
    rollback = "false"
  }

  deployment_controller {
    type = "ECS"
  } 

  platform_version    = "LATEST"
  propagate_tags      = "TASK_DEFINITION"
  scheduling_strategy = "REPLICA"

  lifecycle {
   ignore_changes = [task_definition, desired_count]
 }
}

ECS SERVICE 3 (KO)

resource "aws_ecs_service" "blockchain-srv" {
  name                               = "${var.name}-blockchain-srv"
  cluster                            = aws_ecs_cluster.main.id
  task_definition                    = aws_ecs_task_definition.blockchain-srv-task.arn
  desired_count                      = var.replicas_blockchain_srv
  deployment_maximum_percent         = "200"
  deployment_minimum_healthy_percent = "100"
  enable_ecs_managed_tags            = "true"
  enable_execute_command             = "false"
  health_check_grace_period_seconds  = "0"
  launch_type                        = "FARGATE"
  scheduling_strategy                = "REPLICA"

  network_configuration {
    assign_public_ip = "false"
    security_groups  = var.ecs_service_security_groups
    subnets          = var.subnets.*.id
  }

  load_balancer {
    container_name   = var.task_name_blockchain_srv
    container_port   = var.container_blockforgery_blockchain_srv_port
    target_group_arn = var.aws_alb_target_group_blockchain_srv_arn
  }


  deployment_circuit_breaker {
    enable   = "false"
    rollback = "false"
  }

  deployment_controller {
    type = "ECS"
  }
  propagate_tags      = "TASK_DEFINITION"
  platform_version    = "LATEST"

}

resource "aws_appautoscaling_target" "blockchain-srv" {
  service_namespace  = "ecs"
  resource_id        = "service/${aws_ecs_cluster.main.name}/${aws_ecs_service.blockchain-srv.name}"
  scalable_dimension = "ecs:service:DesiredCount"
  max_capacity       = var.ecs_autoscale_max_instances
  min_capacity       = var.ecs_autoscale_min_instances
}

The only service reachable through the default target group works. Health check is OK, while on the two remaining targets (on which I have set path-based rules) the health check not working:

ALB should correctly route my requests reaching the remaining target groups.

Any help and suggestions will be very welcome. Thank you

0 Answers
Related