When using a ${...} pattern in the default value of a terraform variable, terraform complains the default value cannot contain interpolation:
variable "name" {
default = "${index}"
}
Error: variable "name": default may not contain interpolations
Which is nice in my case, I want to have the default value containing ${index} verbatim without interpolation. So I just write instead:
variable "name" {
default = "$${index}"
}
I get no error, but then instead of containing ${index}, my variable contains $${index} which is not what I want. Of course, the following will not work either:
variable "name" {
default = "${"$"}{index}"
}
Either terraform should error when there is interpolation-like syntax in default value of terraform variables and apply escape sequence to that string ($$ gets transformed in $). Or terraform shouldn't error out on it and just do not apply interpolations.
I wrote a terraform module to configure a cluster of machines. Each machine might have a name in the form ${role}-${index} (app-0, app-1, ...). I also want the users of the module to be able to configure something else than indices for specific machines such as app-monitoring or ap-io0, app-io1 (for IO optimized machines).
The solution I found was to provide a variable name in my module which would default to ${index} but could be overriden to contain monitoring or io${index} to implement the examples above. I then generate the name using a template data source like this:
data "template_file" "name" {
count = "${var.instance_count}"
template = "${var.name}"
vars {
index = "${count.index}"
num = "${count.index + 1}"
}
}
`${index} gets interpolated within the template. It was never meant to be interpolated by terraform.
Thanks for reporting this, @mildred!
This should be fixed in the next major release, when we'll switch to an improved config language implementation.
Hi @apparentlymart - when is the new major version going to happen?
We don't have a firm release date @Xtigyro, but we will communicate as widely as possible, and you can keep up-to-date by watching the 0.12 blog post - it gets updated whenever we post about 0.12.
I was going to file a new issue, but I found this to be the same. Here is a simple reproduce/use-case:
variable "services_mssql_conn_template" {
default = "Data Source=$${data_source};user=root;password=$${password};MultipleActiveResultSets=true;Initial Catalog=$${catalog}"
}
data "template_file" "mssql_connection_string1" {
template = "${var.services_mssql_conn_template}"
vars {
data_source = "db.url.com"
password = "password"
catalog = "catalog"
}
}
data "template_file" "mssql_connection_string2" {
template = "Data Source=$${data_source};user=root;password=$${password};MultipleActiveResultSets=true;Initial Catalog=$${catalog}"
vars {
data_source = "db.url.com"
password = "password"
catalog = "catalog"
}
}
output "var1" {
value = "${var.services_mssql_conn_template}"
}
output "rendered1" {
value = "${data.template_file.mssql_connection_string1.rendered}"
}
output "rendered2" {
value = "${data.template_file.mssql_connection_string2.rendered}"
}
Output is:
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
rendered1 = Data Source=${data_source};user=root;password=${password};MultipleActiveResultSets=true;Initial Catalog=${catalog}
rendered2 = Data Source=db.url.com;user=root;password=password;MultipleActiveResultSets=true;Initial Catalog=catalog
var1 = Data Source=$${data_source};user=root;password=$${password};MultipleActiveResultSets=true;Initial Catalog=$${catalog}
Vars {} values would come from all kinds of other terraform resources, of course.
I can't put the template string directly in the template_file declaration, because I want to have dozens of them and don't want it copied everywhere.
The work-around is either to put the template string into a file for template_file to use, or insert a dummy template in the middle, like that:
variable "services_mssql_conn_template" {
default = "Data Source=$${data_source};user=root;password=$${password};MultipleActiveResultSets=true;Initial Catalog=$${catalog}"
}
data "template_file" "dummy1" {
template = "${var.services_mssql_conn_template}"
//template = "Data Source=$$$${data_source};user=root;password=$$$${password};MultipleActiveResultSets=true;Initial Catalog=$$$${catalog}"
}
data "template_file" "mssql_connection_string3" {
template = "${data.template_file.dummy1.rendered}"
vars {
data_source = "db.url.com"
password = "password"
catalog = "catalog"
}
}
rendered3 = Data Source=db.url.com;user=root;password=password;MultipleActiveResultSets=true;Initial Catalog=catalog
The dummy works with either template definition.
Another silly workaround is to just leave your defaults with $$s and then rather than using directly do a
template = "${replace(var.storage_account_container_readonly_template, "$$$$", "$")}"
Hi all!
I've just verified this behavior on the v0.12.0-alpha1 prerelease build using @mildred's original example. As before, it produces an error, now slightly different because of the new language parser implementation.

But then escaping the sequence with a double $ now _does_ work:
variable "name" {
default = "$${index}"
}
output "name" {
value = var.name
}
$ terraform apply
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
name = ${index}
This fix is merged in master and ready to be included in the forthcoming v0.12.0 release, so I'm going to close this out. Thanks for reporting this, and thanks for your patience while we laid the groundwork to get this done.
@apparentlymart Is this change included in https://releases.hashicorp.com/terraform/0.12.0-alpha4/terraform_0.12.0-alpha4_terraform_0.12.0-alpha4_linux_amd64.zip.
Because I tried escaping but getting following error.
Error launching source instance: InvalidParameterValue: Value (10.0.${clustercount}.20) for parameter privateIpAddress is invalid. Not a valid IP address
If anyone hits this and can't upgrade to 0.12, you can also use locals {} as a work around for this issue.
locals {
key = {
index = "${count.index}"
}
}
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 all!
I've just verified this behavior on the v0.12.0-alpha1 prerelease build using @mildred's original example. As before, it produces an error, now slightly different because of the new language parser implementation.
But then escaping the sequence with a double
$now _does_ work:This fix is merged in master and ready to be included in the forthcoming v0.12.0 release, so I'm going to close this out. Thanks for reporting this, and thanks for your patience while we laid the groundwork to get this done.