Conditionals with for_each

Not sure I have the right approach here, but I am trying to craft a conditional statement to a for_each statement to create a set of resources

For example, setting up an ALB I have two variables

create_alb = true
create_https_listener = true

Along with a variable named rule_set defining a map of rule resources

If both of these vars are true, apply a set of aws_lb_listener_rule resources defined in a the var.rule_set map to the https_listener.

If create_https_listener = false, apply the same set of rules to a http_listener

If create_alb = false, don’t create any of these resources

I can do a conditional for something like

count = var.create_alb == true ? length(var.rule_set) : 0

But I’m struggling using my map on the multiple inline blocks for the rules (eg action{} & condition {} for forward rules)

Ideally I would not use count, but use for_each to define the number of rules to create

Something like

for_each =

I see examples of using something like

for_each = {for key, value in var.rule_set:
key => lower(value)
if var.create_alb == true
}

Is there a way to just use the for_each with an if statement? As my map has different data types in it, I can’t use a simple function to do something innocuous

for_each = {var.rule_set: if var.create_alb == true}

I feel like there is something simple I’m just not grasping

Hey,
I am stuck in the same boat. Were you able to get this going?
I am basically using for_each = var. to create a bunch of target groups and then for_each = target groups to create a bunch of listeners.

now i need to associate a listener rule for each listener.

I did this below. but what this is doing is creating a bunch of header check rules. which is good. but for each listener rule it is creating a bunch on actions.

However i do need to reference the target groups somewhere since i need the TG arn to be supplied while creating the action.

resource “aws_lb_listener_rule” “Host-Header-Check” {
for_each = aws_lb_listener.xyz
listener_arn = each.value.arn
dynamic “action” {

  • for_each = aws_lb_target_group.xyz*
  • type = “forward”*
  • target_group_arn = each.value.arn*
    }
    condition {
    host_header {
    values = [var.header]
    }
    }
    }

Not sure if this will be helpful but this is what I settled on

resource “aws_lb_listener_rule” “this” {
for_each = var.create_alb ? var.rule_set : {}

listener_arn = var.create_https_listener == true ? local.aws_https_lb_listener_arn : local.aws_http_lb_listener_arn

action {
type = lookup(each.value, “type”, “forward”)
target_group_arn = lookup(each.value, “target_group”, null)
}

condition {
field = lookup(each.value, “field”, “host-header”)
values = lookup(each.value, “values”, null)
}

lifecycle {
ignore_changes = [action.0.target_group_arn]
}
}

The rule set being passed in is a map

rule_set = {
“host” = {
target_group = module.ec2_alb.all_target_groups[“name_of_target_group”]
field = “host-header”
values = [“fully.qualified.hostname.com”]
}
“host2” = {
target_group = module.ec2_alb.all_target_groups[“name_of_target_group”]
field = “host-header”
values = [“fully_qualified_hostname.com”]
}
}

Certainly not ideal as it makes assumptions that every rule is a forward, but it works for my use case