I am currently creating a number AWS ALBs by feeding it a nested map. In this nested map I am defining a number of backends to create the target groups, listener rules and target group attachments per ALB. When defning more than 1 ALB, for the sake of this example a private and public one, the backends of the public are trying to be attached to the private one, and vice-versa.
I think it’s because of the way I’m using flatten but this is where I’m struggling to find a different solution.
The following is the map being fed into my ALB module
lb_params = {
private = {
load_balancer_type = var.load_balancer_type
internal = true
listener_port = 443
ingress_from_port = 443
ingress_to_port = 443
endpoint_permitted_ips = local.private_alb_permitted_cidrs
subnets = [local.subnet_ids["private_a"], local.subnet_ids["private_b"]]
backends = [
{
name = "keycloak-private"
port = "8080"
path = ["/auth/*"]
health_check_enabled = false
health_check_interval = var.health_check_interval
health_check_port = 8080
health_check_path = "/"
count_vm = module.int-app-auth.auth_count_scale
count_index = module.int-app-auth.auth_count_index
enable_stickiness = true
type_stickiness = var.type_stickiness
}
]
},
public = {
load_balancer_type = var.load_balancer_type
internal = false
listener_port = 443
ingress_from_port = 443
ingress_to_port = 443
endpoint_permitted_ips = local.public_alb_permitted_cidrs
subnets = [local.subnet_ids["public_a"], local.subnet_ids["public_b"]]
backends = [
{
name = "keycloak-public"
port = "8080"
path = ["/auth/realms/sgdigital/*", "/auth/resources/*"]
health_check_enabled = false
health_check_interval = var.health_check_interval
health_check_port = 8080
health_check_path = "/"
count_vm = module.int-app-auth.auth_count_scale
count_index = module.int-app-auth.auth_count_index
enable_stickiness = true
type_stickiness = var.type_stickiness
}
]
}
}
}
P.S. I have defined the backends as both a list of maps and nested maps.
Creating the ALBs is fine as follows;
resource "aws_lb" "lb" {
for_each = var.lb_params
name = "${each.key}-${var.env_name}"
internal = each.value.internal
load_balancer_type = each.value.load_balancer_type
security_groups = [aws_security_group.lb_security_group[each.key].id]
subnets = each.value.subnets
enable_deletion_protection = false
access_logs {
bucket = var.full_env_name
prefix = "loadbalancer"
enabled = true
}
tags = var.common_tags
}
Then I used a flatten to create the backend stuff
locals {
lb_backends = flatten([
for backend_key, lb_backend in var.lb_params : [
for backend in lb_backend.backends : {
backend_key = backend_key
name = backend.name
port = backend.port
path = backend.path
health_check_path = backend.health_check_path
health_check_port = backend.health_check_port
health_check_enabled = backend.health_check_enabled
health_check_interval = backend.health_check_interval
count_vm = backend.count_vm
count_index = backend.count_index
enable_stickiness = backend.enable_stickiness
type_stickiness = backend.type_stickiness
}
]
])
}
One of the backend resources, the listener
resource "aws_lb_listener_rule" "listener_rule" {
for_each = {
for ab in local.lb_backends : "${ab.backend_key}.${ab.name}" => ab
}
listener_arn = var.lb_listener_arn
action {
type = "forward"
target_group_arn = aws_lb_target_group.target_group[each.key].arn
}
condition {
path_pattern {
values = each.value.path
}
}
}
The following is the plan:
module.lb.module.backend["public"].aws_lb_listener_rule.listener_rule["private.keycloak-private"] will be created
+ resource "aws_lb_listener_rule" "listener_rule" {
+ arn = (known after apply)
+ id = (known after apply)
+ listener_arn = (known after apply)
+ priority = (known after apply)
+ tags_all = (known after apply)
+ action {
+ order = (known after apply)
+ target_group_arn = (known after apply)
+ type = "forward"
}
+ condition {
+ path_pattern {
+ values = [
+ "/auth/*",
]
}
}
}
# module.lb.module.backend["public"].aws_lb_listener_rule.listener_rule["public.keycloak-public"] will be created
+ resource "aws_lb_listener_rule" "listener_rule" {
+ arn = (known after apply)
+ id = (known after apply)
+ listener_arn = (known after apply)
+ priority = (known after apply)
+ tags_all = (known after apply)
+ action {
+ order = (known after apply)
+ target_group_arn = (known after apply)
+ type = "forward"
}
+ condition {
+ path_pattern {
+ values = [
+ "/auth/realms/sgdigital/*",
+ "/auth/resources/*",
]
}
}
}
# module.lb.module.backend["private"].aws_lb_listener_rule.listener_rule["private.keycloak-private"] will be created
+ resource "aws_lb_listener_rule" "listener_rule" {
+ arn = (known after apply)
+ id = (known after apply)
+ listener_arn = (known after apply)
+ priority = (known after apply)
+ tags_all = (known after apply)
+ action {
+ order = (known after apply)
+ target_group_arn = (known after apply)
+ type = "forward"
}
+ condition {
+ path_pattern {
+ values = [
+ "/auth/*",
]
}
}
}
# module.lb.module.backend["private"].aws_lb_listener_rule.listener_rule["public.keycloak-public"] will be created
+ resource "aws_lb_listener_rule" "listener_rule" {
+ arn = (known after apply)
+ id = (known after apply)
+ listener_arn = (known after apply)
+ priority = (known after apply)
+ tags_all = (known after apply)
+ action {
+ order = (known after apply)
+ target_group_arn = (known after apply)
+ type = "forward"
}
+ condition {
+ path_pattern {
+ values = [
+ "/auth/realms/sgdigital/*",
+ "/auth/resources/*",
]
}
}
}