'Benefit of having Concat function in terraform

I am trying to understand the benefit of having a Concat function in the output section. as I have experiment output section with and without Concat. But I cannot see any difference.

example

resource "aws_security_group" "sg_22" {
  name = "sgx_22"
  vpc_id = var.vpc

  ingress {
    from_port = 22
    to_port  = 22
    protocol  = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_security_group" "sg_8080" {
  name = "sgx_8080"
  vpc_id = var.vpc

  ingress {
    from_port = 8080
    to_port  = 8080
    protocol  = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

output "web_security_group_ids" {
  value = concat([aws_security_group.sg_22.id, aws_security_group.sg_8080.id])
}


VS

resource "aws_security_group" "sg_22" {
  name = "sgx_22"
  vpc_id = var.vpc

  ingress {
    from_port = 22
    to_port  = 22
    protocol  = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_security_group" "sg_8080" {
  name = "sgx_8080"
  vpc_id = var.vpc

  ingress {
    from_port = 8080
    to_port  = 8080
    protocol  = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

output "web_security_group_ids" {
  value = [aws_security_group.sg_22.id, aws_security_group.sg_8080.id]
}

In both case, Terraform give the same output in the same format. Any idea?



Solution 1:[1]

That is a mistake in the learning guide. The concat function "concatenates" two different argument lists into a single list containing all the elements of each. In this case, you have a single list of two lists as an argument to the concat function. I believe that the actual function the guide should have mentioned is flatten. This function will "flatten" redundant nested lists into a single list:

output "web_security_group_ids" {
  value = flatten([aws_security_group.sg_22.id, aws_security_group.sg_8080.id])
}

However, this is still rather pointless as the only reason it is a nested list is because the two lists are arguments to a list constructor. Alternatively, the guide may actually have meant to concatenate the two lists directly:

output "web_security_group_ids" {
  value = concat(aws_security_group.sg_22.id, aws_security_group.sg_8080.id)
}

The actual best way to define this output would be to simply use the resource attribute related to the resource argument. This will then be a simple definition in the output, a single list, and guaranteed to update dynamically based on changes to your arguments.

output "web_security_group_ids" {
  value = aws_instance.web.vpc_security_group_ids
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Matt Schuchard