Terraform v0.11.6
+ provider.aws v1.20.0
+ provider.template v1.0.0
output "subnets.private_ids" {
value = "${aws_subnet.private.count > 0 ? aws_subnet.private.*.id : list()}"
}
* module.03-vpc-staging.output.subnets.private_ids: At column 3, line 1: conditional operator cannot be used with list values in:
${aws_subnet.private.count > 0 ? aws_subnet.private.*.id : list()}
See crash output
This limitation is even not documented.
This is still a problem with 0.11.7.
So the following complicated interpolation is used:
records = ["${count.index < (aws_instance.proxy.count * 2) / 2 ? element(aws_instance.proxy.*.private_ip, count.index % ((aws_instance.proxy.count * 2) / 2)) : element(aws_instance.proxy.*.public_ip, count.index % ((aws_instance.proxy.count * 2) / 2))}"]
Instead of
records = ["${element(count.index < (aws_instance.proxy.count * 2) / 2 ? aws_instance.proxy.*.private_ip : aws_instance.proxy.*.private_ip, count.index % 2)}"]
Which the latter is far more readable.
@iyesin You might be able to get around that by doing a join(",", aws.private.*.id)
instead of selecting the splat as the return. Not ideal, I know.
Hi all! Sorry for the slow response here.
This issue is covering the same idea as #12453, which is now closed because the solution is merged in master ready for the forthcoming v0.12.0 release. You can see over there how I verified it against the v0.12.0-alpha1 prerelease build, along with a caveat caused by another related issue that's yet to be resolved.
That caveat unfortunately applies to this example too, but in a different way: since one of the "legs" of the conditional here was a splat expression, the way to work around it for now would be as follows:
value = "${aws_subnet.private.count > 0 ? list(aws_subnet.private.*.id...) : list()}"
That new ...
syntax means "expand the list in this argument to be the remaining arguments to this function". But since we plan to get the other issue sorted out before v0.12.0 release this shouldn't be a problem for the final release, just something to bear in mind if you want to experiment with the alpha or other later prerelease builds.
Since there's now a fix merged, I'm going to close this out. Thanks for opening this issue, and sorry again that we didn't respond sooner.
For those that'll still hit this till v0.12 is out, here's a workaround:
asg_vpc_zone_identifier = "${split(",", var.env == "production" ? join(",", local.asg_vpc_public_zone_identifier) : join(",", local.asg_vpc_private_zone_identifier))}"
Both of the local vars are lists. The asg_vpc_zone_identifier
var expects a list.
It works around the limitation of not being able to use lists with the conditional operator by first joining the lists and eventually passing the result as a list, as originally intended.
ty for the work around
It looks like Terraform 0.12 is close, but if you are still on 0.11 there was a workaround highlighted here. It is a little more verbose, but it allows you to actually get lists of more complex types beyond strings out of it. (I used this technique for beanstalk settings to consolidate a bunch of beanstalk apps into one module).
asg_vpc_zone_identifier = "${
concat(
slice(local.asg_vpc_public_zone_identifier, 0, var.env == "production" ? length(local.asg_vpc_public_zone_identifier) : 0),
slice(local.asg_vpc_private_zone_identifier, 0, var.env == "production" ? 0 :length(local.asg_vpc_private_zone_identifier))
)}"
It is significantly more verbose, but a little more flexible since it works with non-string items.
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.
Most helpful comment
For those that'll still hit this till v0.12 is out, here's a workaround:
Both of the local vars are lists. The
asg_vpc_zone_identifier
var expects a list.It works around the limitation of not being able to use lists with the conditional operator by first joining the lists and eventually passing the result as a list, as originally intended.