Terraform: concat() function does not support lists for inputs as documented

Created on 13 May 2016  ยท  9Comments  ยท  Source: hashicorp/terraform

Hi there,

Terraform Version

Terraform v0.6.15

Affected Resource(s)

  • core

    Terraform Configuration Files

resource "tls_private_key" "api-key" {
  algorithm = "RSA"
}

resource "tls_cert_request" "api-server-key-csr" {
  key_algorithm = "RSA"
  private_key_pem = "${tls_private_key.api-key.private_key_pem}"
  subject {
    common_name = "api"
  }
  ip_addresses = ["${concat(["1.2.3.4"],["5.6.7.8]")}"]
}

Expected Behavior

According to interpolation syntax docs the concat() function should take two lists as arguments and join them and return the resulting list.

Actual Behavior

However, I noticed that in practice this is not the case, and instead the concat() function only works on string typed inputs, effectively concatenating them, as it's name implies.
I'm not sure if the documentation is misinforming and joining lists was never the intended feature or if the feature should actually work but it doesn't.

Steps to Reproduce

Using the above configuration snipped, do a plan:

  1. terraform plan

And you should see an error like:

Error loading config: Error loading /Users/alex/workspace/terraform-test/tls.tf: Error reading config for tls_cert_request[api-server-key-csr]: parse error: syntax error

Now, switch the arguments to concat() to plain strings, like:

ip_addresses = ["${concat("1.2.3.4","5.6.7.8")}"]

And the terraform plan should go through and produce:

+ tls_cert_request.api-server-key-csr
    cert_request_pem:      "" => "<computed>"
    ip_addresses.#:        "" => "1"
    ip_addresses.0:        "" => "1.2.3.45.6.7.8"
    key_algorithm:         "" => "RSA"
    private_key_pem:       "" => "37935e2f61ac06c349d43e6ed5512a640cd6c9f8"
    subject.#:             "" => "1"
    subject.0.common_name: "" => "api"

+ tls_private_key.api-key
    algorithm:          "" => "RSA"
    ecdsa_curve:        "" => "P224"
    private_key_pem:    "" => "<computed>"
    public_key_openssh: "" => "<computed>"
    public_key_pem:     "" => "<computed>"
    rsa_bits:           "" => "2048"

Notice how the ip_addresses.0: value is the result of joining the two input strings.

core question

Most helpful comment

@jen20 @alexsomesan Can't you just do this?
["${concat(list("1.2.3.4"), list("5.6.7.8"))}"]

All 9 comments

Looks like more of a syntax issue, I don't think you can declare lists with the example you provided:

ip_addresses = ["${concat(["1.2.3.4"],["5.6.7.8]")}"]

Once you're inside the outer []'s, I don't believe terraform supports declaring an 'inner list'.

On the other hand, if the variables refer to lists, it should still work, e.g. (pseudo):

ip_addresses = ["${concat(aws_instance.web_cluster.*.private_ip, aws_instance.data_cluster.*.private_ip)}"]

Hi @alexsomesan! As @eedwardsdisco points out the issue is that there is no syntax for list literals in HIL. We may change this in 0.7 to add support, but for now you need to use concat, or a resource field which results in a list as input to concat. Please feel free to reopen this if you have further questions.

Was it implemented? @jen20

@jen20 @alexsomesan Can't you just do this?
["${concat(list("1.2.3.4"), list("5.6.7.8"))}"]

Maybe it's a bit late but I had a similar problem (which was my own mistake..) and so I came here and saw this... tested it like:

output "prod_instance_ids" {
  value = "${concat(aws_instance.prod01.*.id,aws_instance.prod02.*.id)}"
}

Worked.

concat with inner lists does not work, I just use join with empty delimter

this was what I want to do
concat(list(var.string0), list(var.string1))
it did not work,

I replaced it like this
join("", list(var.string1, var,string2)

I was looking for the solution to concat two lists and found the solution using in below format -

locals {
  a_identifiers = [
    "arn:aws:iam::hhhhjjjjj:role/account_dev",
    "arn:aws:iam::hhhhjjjjj:role/account_stage",
  ]
}
locals {
  b_identifiers = [
    "arn:aws:iam::hhhhjjjjj:role/account_qa",
    "arn:aws:iam::hhhhjjjjj:role/account_prod",
  ]
}
locals {
  combo_identifiers = "${concat(a_identifiers,b_identifiers)}"
}

this is how I can use it after this -

data "aws_iam_policy_document" "access_policy" {
  statement {
    effect = "Allow"

    principals {
      type = "AWS"

      identifiers = ["${local.combined_identifiers}"]
    }

    actions = [
      "ec2:*",
    ]

    resources = [
      "*",
    ]
  }
}

Hope someone will find it useful

Update2: I was blind and made a copy-n-paste mistake. I copied list() to the wrong place. So list() can be used to pass a string to concat(). I'm removing the message to not confuse others.

Working example for the situation I had:

route_table_id = "${element(
    concat(
      module.abc.private_route_table_ids,
      list(module.abc.public_route_table_id)
    ),
    count.index
  )}"

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings