I'm loosely following this example to create a multiple ECS services under one cluster: https://github.com/shashimal/terraform-ecs/blob/master/main.tf
The problem I have is that only some of the services will require a load balancer in front of the service.
I have tried adding a flag (alb_enabled) into the service_config variable like so:
service_config = {
"test-service-efs" = {
auto_scaling = {
scale_in = {
max_capacity = 1
min_capacity = 1
schedule = "00 16 * * ? 2199"
}
scale_out = {
max_capacity = 1
min_capacity = 1
schedule = "00 16 * * ? 2199"
}
}
desired_count = 1
is_public = false
name = "test-service-efs"
alb_enabled = false
}
}
resource "aws_ecs_service" "ecs_service" {
for_each = var.service_config
name = "${each.value.name}-service"
cluster = aws_ecs_cluster.ecs_cluster.id
task_definition = aws_ecs_task_definition.ecs_task_definition[each.key].arn
launch_type = "FARGATE"
desired_count = each.value.desired_count
network_configuration {
subnets = var.private_subnets
assign_public_ip = each.value.is_public
security_groups = var.security_groups
}
load_balancer {
target_group_arn = aws_alb_target_group.alb_target_group[each.key].arn
container_name = each.value.name
container_port = 3000
}
lifecycle {
ignore_changes = [task_definition,
tags,
desired_count
]
}
tags = var.tags
}
#Dynamically create the alb target groups for app services
resource "aws_alb_target_group" "alb_target_group" {
for_each = { for k, v in var.service_config : k => v if v.alb_enabled }
name = "${each.value.name}-tg"
port = 3000
protocol = "HTTP"
target_type = "ip"
vpc_id = "vpc-xxxxxxxxxxxx"
}
This works fine when the flag is enabled. However when I disable this flag, due to the target group not existing, the ecs_service load balancer fails
Error: Invalid index
on modules\ecs\main.tf line 79, in resource "aws_ecs_service" "ecs_service":
79: target_group_arn = aws_alb_target_group.alb_target_group[each.key].arn
aws_alb_target_group.alb_target_group is object with no attributes
each.key is "test-service-efs"
The given key does not identify an element in this collection value
I completely understand why this is failing, but I'm struggling to figure out a workaround for it. I was thinking of having two separate ecs modules which create services with and without a load balancer but this could get messy when trying to pass in the various rules to the ALB as variables. There doesn't seem to be a way to set the conditional within the load_balancer section in aws_ecs_service but was wondering does anybody have any creative workarounds for this?
You have to use dynamic blocks to create your block optionally:
dynamic "load_balancer" {
for_each = var.service_config[each.key] == true ? [1]: []
content {
target_group_arn = aws_alb_target_group.alb_target_group[each.key].arn
container_name = each.value.name
container_port = 3000
}
}