Pattern for creating list based on dynamic blocks

I am trying to figure out how to create a list based on conditions within a dynamic block. My specific use case is using the aws_proxy_protocol_policy for an ELB only when the listener is using TCP. I have the following dynamic listener block

dynamic "listener" {
    for_each = [for i in "${var.dynamic_listener}" : {
      instance_port      = i.instance_port
      instance_protocol  = i.instance_protocol
      lb_port            = i.lb_port
      lb_protocol        = i.lb_protocol
      ssl_certificate_id = i.ssl_certificate_id
    }]

    content {
      instance_port      = listener.value.instance_port
      instance_protocol  = listener.value.instance_protocol
      lb_port            = listener.value.lb_port
      lb_protocol        = listener.value.lb_protocol
      ssl_certificate_id = listener.value.ssl_certificate_id
    }
  }

and would like to build a list of instance_ports based on ONLY listeners with instance_protocols of ‘TCP’

resource "aws_proxy_protocol_policy" "proxy_protocol" {
  count          = "${(lower(var.proxy_protocol_enabled) == "true") ? 1 : 0 }"
  load_balancer  = "${aws_elb.elb}"
  instance_ports = ?????
}

I tried something like

instance_ports = [for i in "${var.dynamic_listener}" : {
    instance_ports = flatten([i.instance_protocol == "TCP" ? i.instance_port : null])}]

But am not having much success. Any thoughts?

Hi @jmgreg31,

I’m afraid I’m not familiar enough with the specific AWS provider resources you’re using here to show a complete example, because I’m not sure I followed exactly what result you need, but I think the important feature for this is the if clause for a for expression:

    for_each = [
      for i in var.dynamic_listener : {
        instance_port      = i.instance_port
        instance_protocol  = i.instance_protocol
        lb_port            = i.lb_port
        lb_protocol        = i.lb_protocol
        ssl_certificate_id = i.ssl_certificate_id
      }
      if i.instance_protocol == "TCP"
    ]

When you use the if clause, the resulting list will include only elements where the condition produced true.

Thanks for the super fast response @apparentlymart. That got me headed in the right direction.

To summarize, I was trying to create a list of instance ports to use in the aws_proxy_protocol_policy resource based on a dynamic block of ELB listeners where the instance protocol was TCP. This is the solution that worked for me.

resource "aws_proxy_protocol_policy" "proxy_protocol" {
  count          = "${(lower(var.proxy_protocol_enabled) == "true") ? 1 : 0 }"
  load_balancer  = "${aws_elb.elb.name}"
  instance_ports = [for i in var.dynamic_listener : i.instance_port if i.instance_protocol == "TCP"]
}
1 Like