data.template_file unknown variable accessed Error

1,147 views
Skip to first unread message

je...@anyperk.com

unread,
Nov 14, 2016, 5:37:44 PM11/14/16
to Terraform
I'm getting the following error during my terraform apply (but it doesn't show up during terraform plan):

Error applying plan:

2016/11/14 14:10:49 [DEBUG] plugin: waiting for all plugin processes to complete...
1 error(s) occurred:

* data.template_file.chef-environment: failed to render : 2:15: unknown variable accessed: name

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

Pertinent debug output here: https://gist.github.com/jcderose/ded36006a6368346b32ad9ea77926b74

The "app1_db_host" variable declaration (below) is the only line I changed in data.template_file.chef-environment. (That variable used to receive the value of a local variable instead, and worked that way.)

data "template_file" "chef-environment" {
  template = "path/to/template"

  vars {
  ...   
    app1_db_host = "${coalesce(module.app1.db_fqdn, module.app0.db_fqdn)}"

  }
}

We have some new use cases where app1 does not have its own standalone DB host, so the output of "module.app1.db_fqdn" is nonexistent. (In those cases, the variable app1_db_host should be module.app0.db_fqdn, which is always created/declared.)

(1) Am I correct that the error message above could stem from an issue like this?
(2) What can I do to resolve this issue? I already looked into setting a default blank string for the output variable (module.app1.db_fqdn) or setting the output variable module.app1.db_fqdn equal to "${element(aws_route53_record.db_master.*.fqdn, 0)}". Neither of those worked.

je...@anyperk.com

unread,
Nov 14, 2016, 5:50:58 PM11/14/16
to Terraform
I forgot to mention, I'm running Terraform 0.7.5.

Lowe Schmidt

unread,
Nov 16, 2016, 9:54:19 AM11/16/16
to terrafo...@googlegroups.com
So where is that variable "name" ?

--
Lowe Schmidt | +46 723 867 157

--
This mailing list is governed under the HashiCorp Community Guidelines - https://www.hashicorp.com/community-guidelines.html. Behavior in violation of those guidelines may result in your removal from this mailing list.
 
GitHub Issues: https://github.com/hashicorp/terraform/issues
IRC: #terraform-tool on Freenode
---
You received this message because you are subscribed to the Google Groups "Terraform" group.
To unsubscribe from this group and stop receiving emails from it, send an email to terraform-tool+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/terraform-tool/8d1b6561-0f2e-4d12-a3d1-41c28b91a859%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

je...@anyperk.com

unread,
Nov 16, 2016, 10:43:59 AM11/16/16
to Terraform
The variable "name" is at the top of the template file referenced by the template_file resource:

{
 
"template_file_name": "${name}",
 
"app1_db_host": "${app1_db_host}"
}
To unsubscribe from this group and stop receiving emails from it, send an email to terraform-too...@googlegroups.com.

Lowe Schmidt

unread,
Nov 16, 2016, 7:46:11 PM11/16/16
to terrafo...@googlegroups.com
so, that should be "${var.name}" and not just "${name}"

--
Lowe Schmidt | +46 723 867 157

To unsubscribe from this group and stop receiving emails from it, send an email to terraform-tool+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/terraform-tool/90381c43-e371-4ff6-9fa3-a9733709089f%40googlegroups.com.

je...@anyperk.com

unread,
Nov 16, 2016, 7:57:51 PM11/16/16
to Terraform
I tried that, and it still gives me the same error, but now with "var.name" instead of "name":

Error applying plan:


2016/11/14 14:10:49 [DEBUG] plugin: waiting for all plugin processes to complete...
1 error(s) occurred:


* data.template_file.chef-environment: failed to render : 2:15: unknown variable accessed: var.name


Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed
. Please address the error
above
and apply again to incrementally change your infrastructure.



To clarify, the "name" var is passed into the template file via the template_file resource var block:

template_file resource declaration:

data "template_file" "chef-environment" {
 template = "path/to/template"

  vars {
 
...    
    name
= "hello"

    app1_db_host
= "${coalesce(module.app1.db_fqdn, module.app0.db_fqdn)}"

  }
}


template_file file:

{
 
"template_file_name": "${name}",
 
"app1_db_host": "${app1_db_host}"
}

From what I know about template_file files, they don't need to reference their variables with the "var." syntax. 

I also noticed that the template_file vars block does not allow inline interpolation - the docs explicitly require static, simple variables: https://www.terraform.io/docs/providers/template/d/file.html#vars

So I think I need a workaround where the coalesce() interpolation takes places outside the template_file vars block - possibly in a null_data_source block. But I've tried a few options, including suggestions in this thread but haven't found any that work: https://github.com/hashicorp/terraform/issues/4084

je...@anyperk.com

unread,
Nov 18, 2016, 7:45:14 PM11/18/16
to Terraform
Okay, I solve my problem: the output variable module.app1.db_fqdn references a resource that doesn't exist. Therefore, Terraform errors out anywhere the module.app1.db_fqdn is referenced. 

In my app1 module, I changed the output variable to:

output "db_fqdn" {
  value = "${join(",", aws_route53_record.db_master.*.fqdn)}"
}

Which creates my intended effect of assigning an empty string to the output variable module.app1.db_fqdn. Then in my template_file resource declaration I wrote:

data "template_file" "chef-environment" {
 template = "path/to/template"

  vars {
  ...    
    name = "hello"

    app1_db_host = "${coalesce(element(split(",", module.app1.db_fqdn), 0), module.app0.db_fqdn)}"

  }
}

This compares the sometimes-empty string of module.app1.db_fqdn against the non-empty string of module.app0.db_fqdn and assigns whichever first value is non-empty.

Reply all
Reply to author
Forward
0 new messages