Terraform: format interpolation function interprets variables as strings

Created on 1 Feb 2019  ยท  2Comments  ยท  Source: hashicorp/terraform

Terraform Version

Terraform v0.11.11

Terraform Configuration Files

name ="foo-${format("%02d", var.some_number)}" # where some_number = 2

Debug Output

Crash Output

Expected Behavior


name is set as foo-02

Actual Behavior


name is set as "foo-%!d(string=2)"

Steps to Reproduce

Additional Context


So far my workaround is to add the variable to zero:

name ="foo-${format("%02d", 0 + var.some_number)}" # where some_number = 2

References

bug config

Most helpful comment

Hi @jeremygaither! Sorry for this odd behavior, and thanks for reporting it.

This strangeness results from the fact that in Terraform 0.11 and earlier the format command is just a wrapper around the Go fmt.Sprintf function, which therefore doesn't do all of the automatic type conversions we normally expect in the Terraform language.

The good news is that there's already a new implementation of format in the master branch ready for inclusion in the forthcoming Terraform v0.12.0 release, and that implementation behaves correctly because it is implemented in terms of the Terraform language's own type system, not the Go type system:

$ terraform console
> "foo-${format("%02d", "2")}"
foo-02

As usual in the Terraform language, Terraform here can see that the %d verb requires a number and so it attempts to convert the argument from string to number.

Naturally this will produce an error if the given value _cannot_ be converted to a number:

> "foo-${format("%02d", "pineapple")}"

Error: Error in function call

Call to function "format" failed: unsupported value for "%02d" at 0: a number
is required.

Since this fix is already in the master branch, I'm going to close this out now. In the mean time, the workaround you found is a reasonable one -- using the Terraform language + operator to force a conversion to number _before_ the function call -- and it'll be harmless once upgraded to Terraform 0.12, so you can remove the workaround at your leisure at some point after upgrading:

> "foo-${format("%02d", 0 + "2")}"
foo-02

Other similar workarounds would include passing the value to the floor function to force conversion to a whole number, and any other function or language operator that implies a conversion to number.

All 2 comments

Hi @jeremygaither! Sorry for this odd behavior, and thanks for reporting it.

This strangeness results from the fact that in Terraform 0.11 and earlier the format command is just a wrapper around the Go fmt.Sprintf function, which therefore doesn't do all of the automatic type conversions we normally expect in the Terraform language.

The good news is that there's already a new implementation of format in the master branch ready for inclusion in the forthcoming Terraform v0.12.0 release, and that implementation behaves correctly because it is implemented in terms of the Terraform language's own type system, not the Go type system:

$ terraform console
> "foo-${format("%02d", "2")}"
foo-02

As usual in the Terraform language, Terraform here can see that the %d verb requires a number and so it attempts to convert the argument from string to number.

Naturally this will produce an error if the given value _cannot_ be converted to a number:

> "foo-${format("%02d", "pineapple")}"

Error: Error in function call

Call to function "format" failed: unsupported value for "%02d" at 0: a number
is required.

Since this fix is already in the master branch, I'm going to close this out now. In the mean time, the workaround you found is a reasonable one -- using the Terraform language + operator to force a conversion to number _before_ the function call -- and it'll be harmless once upgraded to Terraform 0.12, so you can remove the workaround at your leisure at some point after upgrading:

> "foo-${format("%02d", 0 + "2")}"
foo-02

Other similar workarounds would include passing the value to the floor function to force conversion to a whole number, and any other function or language operator that implies a conversion to number.

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rjinski picture rjinski  ยท  3Comments

zeninfinity picture zeninfinity  ยท  3Comments

darron picture darron  ยท  3Comments

rjinski picture rjinski  ยท  3Comments

pawelsawicz picture pawelsawicz  ยท  3Comments