$ terraform -v
Terraform v0.11.7
+ provider.aws v1.22.0
test_module/main.tf:
variable "create" {
default = true
}
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_instance" "web" {
count = "${var.create}"
ami = "${data.aws_ami.ubuntu.id}"
instance_type = "t2.micro"
tags {
Name = "HelloWorld"
}
}
main.tf:
provider "aws" {
region = "eu-west-1"
}
module "test_conditional" {
source = "./test_module"
create = "${true ? true : false}"
}
module "test_true" {
source = "./test_module"
create = true
}
module "test_false" {
source = "./test_module"
create = false
}
https://gist.github.com/jordiclariana/aa7642f10df48f978fc86b7524610c87
2 instances should be created
It throws this error:
```$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
data.aws_ami.ubuntu: Refreshing state...
data.aws_ami.ubuntu: Refreshing state...
data.aws_ami.ubuntu: Refreshing state...
Error: Error running plan: 1 error(s) occurred:
terraform initterraform planIt seems like count builtin parameter can accept booleans, where true turns internally into 1 and false into 0. I don't know if this is intentional, but some official modules use it
If I run terraform plan -target=module.test_true -target=module.test_false I got no errors, everything is fine. But the problem comes when the count value comes from an evaluated ternary, then count needs to be integer and boolean is not accepted anymore. Whether this is expected behavior or not is up to the mantainers, but it looks to me like there is some inconsistency. Either count can accept booleans always or not. Also, there is the possibility that the ternary is returning a string instead of a boolean...
Also, I posted here the example I was trying and how I found the error (using a module), but this same error happen without a module, having a direct resource with a count like this: count = "${true ? true : false}"
Hi @jordiclariana! Thanks for pointing out this strange behavior.
Unfortunately I think what's going on here is a little more subtle and tricky than it first appears. The module you linked to is using var.create as the value of count, and in Terraform 0.11 and earlier variables are always either strings, lists of strings, or maps of strings. Therefore although that variable has default = true, it's really a string value derived from that boolean value.
The next major release of Terraform will introduce a more complete type system and allow variables to be of any of the supported types. At that point, count will be required to always be a whole number, and so a boolean value will never work directly, with it being required to use a conditional expression in that case in order to be explicit about the conversion.
Hi again, @jordiclariana! Sorry for the long silence here.
I just ran your configuration through the v0.12.0-alpha2 prerelease build and confirmed that, as expected, it now returns an error for all of these cases explaining that a number is required.
I then rewrote the count expression like this:
count = "${var.create ? 1 : 0}"
...and was able to plan the configuration as expected.
Since the behavior of it allowing boolean values here before was not intended in the first place, this consistent error message is what we're considering to be the correct behavior here, since we believe it improves readability to be explicit about how each state of the boolean maps to a count value; one of the goals of Terraform is that where possible someone who is not a Terraform expert should be able to read a configuration and guess correctly how it will behave, and so the hidden automatic conversion to number here was not intentional.
Since this is now behaving as expected in master, I'm going to close it out. This change will be included in the forthcoming v0.12.0 release, and the potential compatibility implication will be mentioned in the upgrade guide that we'll prepare closer to final release.
Thanks again for reporting this!
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
Hi @jordiclariana! Thanks for pointing out this strange behavior.
Unfortunately I think what's going on here is a little more subtle and tricky than it first appears. The module you linked to is using
var.createas the value ofcount, and in Terraform 0.11 and earlier variables are always either strings, lists of strings, or maps of strings. Therefore although that variable hasdefault = true, it's really a string value derived from that boolean value.The next major release of Terraform will introduce a more complete type system and allow variables to be of any of the supported types. At that point,
countwill be required to always be a whole number, and so a boolean value will never work directly, with it being required to use a conditional expression in that case in order to be explicit about the conversion.