Closed Nmishin closed 5 years ago
This is interesting, it working wrong also if I provide two variables like this:
data "template_file" "serial" {
template = "$${time / cycle}"
vars {
time = "${var.timestamp}"
cycle = "${var.ttl}"
}
}
but works as expected if I do something like this:
data "template_file" "serial" {
template = "${var.timestamp / var.ttl}"
}
Hi @Nmishin,
The template provider from version 2.0.0 onwards uses the Terraform 0.12 template engine, which does not distinguish between integer and floating-point numbers: all numbers are arbitrary-precision floating point numbers.
To get an integer result, you can use the floor
function to round down or the ceil
function to round up, depending on which behavior is more appropriate. It sounds like you were previously relying on the behavior of Terraform 0.11's template engine of rounding the result down, in which case floor
should give you the same result you wanted here.
data "template_file" "number" {
template = "$${floor(time / cycle)}"
vars {
time = "${data.external.timestamp.result.seconds}"
cycle = "${var.ttl / 2}"
}
}
Hi @apparentlymart,
Thank you for the fast reply. Yes, we are moving from Terraform 0.9.4 to 0.11.7. And seems this is what do we need. Thank you.
Out of my curiosity, why this construction works as expected:
data "template_file" "serial" {
template = "${data.external.timestamp.result.seconds / var.ttl}"
}
seems because of this block work in the Terraform 0.11.7 block engine, not in the inside provider (and use Terraform 0.12 template engine) ?
Yes, correct usage is to escape the ${
so that it can be interpreted by the template provider rather than by Terraform itself. If you don't escape it, then Terraform 0.11 will be the one to evaluate that expression, and the template engine will simply see the resulting digits as its input template.
For an expression this straightforward, the template provider is a lot of extra complexity... I assume you were doing that in Terraform 0.9 because there weren't many other options for factoring out an expression to be used multiple times. In Terraform 0.11 you can use the Local Values feature instead:
locals {
serial = "${floor(data.external.timestamp.result.seconds / var.ttl)}"
}
resource "null_resource" "test" {
triggers {
serial = "${local.serial}"
}
}
In this case, this too is evaluated by Terraform directly and not a provider, so you don't technically need floor
but I would suggest adding it anyway to make it explicit to the reader that you are intending integer division and so that the configuration would work the same way if you subsequently upgrade to Terraform 0.12.
@apparentlymart thank you very much for your explanations! This is really useful. I'm closing the issue.
Terraform Version
0.11.7 provider.template >= 2.0.0
Affected Resource(s)
template_file
Terraform Configuration Files
Output
Debug Output
Panic Output
Expected Behavior
data.template_file must generate the integer number which changed every half of year, example 97, 97, 99, etc
triggers.do_upload: "99" => "99"
Actual Behavior
data.template_file getting for input two integer numbers, but when template rendered math operation processed like with float numbers, and produce float number.
Steps to Reproduce
Please list the steps required to reproduce the issue, for example:
terraform init
terraform apply
Important Factoids
This is works as expected with Terraform provider template version prior to 2.0.0.
References