Description
Current Terraform Version
Terraform v0.13.4
+ provider registry.terraform.io/hashicorp/aws v3.10.0
+ provider registry.terraform.io/hashicorp/local v1.4.0
+ provider registry.terraform.io/hashicorp/template v2.2.0
Use-cases
I want a module to conditionally create a particular AWS Route53 entry if a zone ID is passed in. I'm using count
and checking whether the variable is null. I'd like Terraform to be able to create everything, including the zone, in one plan/apply so a CI system can do the actual plan application.
variable "public_zone_id" {
type = string
default = null
}
resource "aws_route53_record" "public_cname" {
count = var.public_zone_id != null ? 1 : 0
zone_id = var.public_zone_id
name = "${var.hostname}"
type = "CNAME"
ttl = 1800
records = [aws_instance.this.public_dns]
}
And then in the calling project, I pass in the zone ID, like so:
module "foo" {
source = "my_module"
hostname = "example"
public_zone_id = module.vpc.public_zone_id
}
But because the count depends on a value from a resource that isn't created yet, terraform plan
gives me
Error: Invalid count argument
on ../modules/ec2/main.tf line 40, in resource "aws_route53_record" "public_cname":
40: count = var.public_zone_id != null ? 1 : 0
The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.
Attempted Solutions
In the calling project, I have tried various tricks to make it impossible for the variable to ever be null regardless of whether or not the original resource exists, all with the same result as above.
public_zone_id = coalesce(module.vpc.public_zone_id, "dummy")
public_zone_id = trimsuffix("${module.vpc.public_zone_id}!", "!")
public_zone_id = module.vpc.public_zone_id != null ? module.vpc.public_zone_id : "dummy"
Proposal
Although the specific value of the zone ID is unknown here, it seems like Terraform ought to be able to tell that there will definitely be some value that will definitely not be null, and thus that the count should be 1, even if the actual value can't be filled in until later. There are a lot of attributes on a lot of resources that are required to be present if the resource creation succeeds, and since Terraform defines null
as the absence of a value, checking for != null
should only require the presence of a value.
So the proposal is that in the specific case of count = some_resource.some_attribute != null ? X : Y
where the resource will be created in the same Terraform invocation, Terraform evaluate the expression based on whether or not the attribute is guaranteed to be present, rather than based on the actual attribute value. Obviously the "guaranteed" part is important; for optional attributes the current behavior would be unavoidable and expected. But for attributes that are always exported and can never possibly be null, it should be possible to evaluate that expression statically at plan time.
References
- The "count" value depends on resource attributes that cannot be determined until apply, but resource attributes are already appliedย #26078 overlaps with this but isn't quite the same; what I'm asking for here is more narrowly focused than what people were asking for in the discussion there.