Search code examples
amazon-web-servicesterraformterraform-provider-awsaws-security-group

Conditional Expression not working in aws_security_group resource egress block terraform


for resource aws_security_group , i want to add egress block to run only if ingress rules are created. Below i have applied condition for the egress block using count then tried with for_each , but I am getting error : An argument named "count" or "for_each" is not expected here respectively. Can someone please help how can i achieve this

code

  egress {
    #for_each             = (length(split(",", var.ingress_ports_udp)) != 0 && length(split(",", var.ingress_ports_udp)) != 0) ? ["1"] : []
    from_port         = 0
    to_port           = 0
    protocol          = "-1"
    cidr_blocks       = ["0.0.0.0/0"]
  }

Solution

  • You're looking for the dynamic block. It would look something like this:

    resource "aws_security_group" "mygroup" {
      name        = "mygroup"
      vpc_id      = aws_vpc.main.id
    
      dynamic "egress" {
        for_each = (condition) ? [1] : []
        content {
          from_port         = 0
          to_port           = 0
          protocol          = "-1"
          cidr_blocks       = ["0.0.0.0/0"]
        }
      }
    }
    

    Your condition looks quite odd. First off, you're checking exactly the same condition twice (length(split(",", var.ingress_ports_udp)) != 0 appears to be duplicated), and second, split will never return a list of length 0 anyways (if an empty string is given, it will return a list with one element, which is itself an empty string). You can see this on the split documentation page, third example:

    > split(",", "")
    [
      "",
    ]
    

    So your condition will never be false, no matter what the value of var.ingress_ports_udp is. You can use compact(split(",", var.ingress_ports_udp)) to deal with this (compact will remove any list elements that are empty strings).

    I'd recommend passing var.ingress_ports_udp in as a list of numbers, instead of as a string that you split within the module. Then you can simply use length(var.ingress_ports_udp) > 0 ? [1] : [].