Search code examples
terraformaws-security-groupterraform-aws-modules

Get port value as output of security group in Terraform


I have the code to create security group in terraform

resource "aws_security_group" "eks_group1"{
description = "Valid security group"
name = "eks_group1"

  ingress {
    from_port = 443
    to_port = 443
    protocol = "tcp"
  }
}

I am trying to output the port value mentioned in "to_port"

output "allowed_ports" {
    value = aws_security_group.eks_group1.ingress
}

Generated output

allowed_ports = toset([
{
    "cidr_blocks" = tolist([])
    "description" = ""
    "from_port" = 443
    "ipv6_cidr_blocks" = tolist([])
    "prefix_list_ids" = tolist([])
    "protocol" = "tcp"
    "security_groups" = toset([])
    "self" = false
    "to_port" = 443
  },
])

I tried aws_security_group.eks_group1.ingress[0], tomap, lookup functions to access values but no luck. Any way to access value of "to_port" in output?

My end goal is to check port 443 is used in security group


Solution

  • The allowed_blocks output value includes toset([...]) in its output, which suggests that the provider has declared ingress as being represented as a set of objects data type.

    Sets do not have any particular order, so it's not meaningful to ask for "the first element" of a set. However, since your example has only one ingress block it is meaningful to ask for "the only element of the set". You can do that concisely using the one function:

    output "allowed_port" {
      value = one(aws_security_group.eks_group1.ingress).to_port
    }
    

    Your output value would then be the following:

    allowed_port = 443
    

    The above will fail with an error if there isn't exactly one ingress block. If you actually need to support any number of ingress blocks, you can instead construct a set of numbers representing the port numbers, like this:

    output "allowed_ports" {
      value = toset(aws_security_group.eks_group1.ingress[*].to_port)
    }
    

    The above uses the splat operator to derive a collection of port numbers from the collection of objects representing the ingress blocks. Then toset converts that result to also be a set, which preserves the inherent un-ordered-ness of these port numbers.

    Your output value would then be the following:

    allowed_ports = toset([
      443,
    ])