1
votes

I have some shared terraform modules that are currently used by a number of terraform 0.11 based projects. I want to gradually migrate the projects to 0.12 and try to retain the module's compatibility with both 0.11 and 0.12. I am having trouble with list attributes, which have changed from having a bracket syntax.

In terraform 0.11 brackets were required around a single expression in order to hint to the language interpreter that a list interpretation was desired:

# Example for older versions of Terraform; not valid for v0.12
example = ["${var.any_list}"]

In terraform 0.12 an expression like the above will now produce a list of lists and thus produce a type checking error for any argument that was expecting a list of some other type.

# Example for Terraform v0.12
example = var.any_list

Is it possible to set the list attribute in a way that is compatible with both 0.11 and 0.12?

2
Sorry that it is almost impossible. not only list, but almost hcl syntax has been changed. If you use git for the module I think it is better that you modify the module for 0.12 and make new version tag. like v1.x supports terraform 0.11 and v2.x supports terraform 0.12.RyanKim
@RyanKim I am using S3 to host the modules so will have to create terraform 0.12 compatible versions separately in the bucket. This is the only thing I have found so far that is not hcl1 compatible.Glen Thomas

2 Answers

2
votes

In principle, writing it without the redundant brackets should work in both Terraform 0.11 and 0.12, like this:

example = "${var.any_list}"

Unfortunately, due to a Terraform 0.11 limitation, this will fail if var.any_list contains any values that are not known at plan time, because Terraform 0.11 does not consider an unknown value to be a valid list. The redundant extra brackets are a common workaround for that limitation, but are not an intentional feature: that bug aside, the redundant list brackets have not been needed since Terraform 0.7 and were supported only for backward-compatibility with Terraform 0.6 and earlier.

With that said, if your list does contain unknown values then there is unfortunately no way to write this that is compatible with both versions. The closest thing is to use a form like the above, with the interpolation syntax but without the brackets, and then use -target on the first apply to force Terraform to create whatever resources the var.any_list depends on first, and then on subsequent applies there should be no unknown values in that list and thus it should be able to complete successfully. This is the same principle as when unknown values appear in count, which is not allowed even in Terraform 0.12.

0
votes

This tricky way will be worked for both 0.11 and 0.12,

example = "${flatten(var.any_list)}"

I tested with cidr_blocks in aws_security_group for terraform v0.11.14 and v0.12.4

variable  "test" {
  default = ["10.10.0.0/16", "10.20.0.0/16"]
}

resource "aws_security_group" "test" {
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "TCP"

    cidr_blocks = "${flatten(var.test)}"
  }
}