Terraform: "unknown variable referenced" error with `var-file` command-line option

Created on 29 Oct 2016  ยท  5Comments  ยท  Source: hashicorp/terraform

Terraform Version

$ terraform -v
Terraform v0.7.7

Affected Resource(s)

This appears to affect Terraform core, though I'm using the digitalocean provider.

Terraform Configuration Files

The contents of configuration.tf:

provider "digitalocean" {
  token = "${var.digitalocean_api_token}"
}

resource "digitalocean_droplet" "xenial" {
  image = "ubuntu-16-04-x64"
  name = "ubuntu-xenial"
  region = "nyc1"
  size = "512mb"
}

The contents of ../secrets.tfvars:

variable "digitalocean_api_token" {
    type = "string"
    default = "abcdef"
}

Debug Output

I'm including two sets of debugging output:

  1. Without variable "digitalocean_api_token" {} in configuration.py.
  2. With variable "digitalocean_api_token" {} in configuration.py.

See here: https://gist.github.com/NicholasPCole/3dd41ca123ad72dd712a66379b137c19

Panic Output (n/a)

Expected Behavior

The Terraform action (plan, apply, destroy, etc.) runs with the API token defined in my ../secrets.tfvars file.

Actual Behavior

I receive an error about unknown variables and no action is taken.

module root: 1 error(s) occurred:

* provider config 'digitalocean': unknown variable referenced: 'digitalocean_api_token'. define it with 'variable' blocks

Searching GitHub issues, I found this recommendation to insert something like variable "digitalocean_api_token" {} in my configuration file. Doing that, I get a different error, however:

Error configuring: 1 error(s) occurred:

* 1:3: unknown variable accessed: var.digitalocean_api_token in:

${var.digitalocean_api_token}

Steps to Reproduce

Run terraform apply -var-file=../secrets.tfvars. This results in the "unknown variable referenced" error.

Alternatively:

  1. Insert variable "digitalocean_api_token" {} into the above configuration.tf file.
  2. Run the same terraform apply -var-file=../secrets.tfvars. This results in the "unknown variable accessed" error.

Important Factoids

I've tried different forms of syntax with no success, even knowing -var-file=variables.tf is the documented syntax:

  • -var-file versus --var-file.
  • -var-file=../secrets.tfvars versus -var-file ../secrets.tfvars.
  • Single quotes and double quotes around the ../secrets.tfvars file name.
  • Using absolute versus relative file paths to secrets.tfvars.

Are there any restrictions on loading variable files from other directories?

References

Most helpful comment

Gaaaaaaaaaaaaaaaaaa. This same issue was driving me nuts.

Now I "see" it, the difference between declaration and assigning.

For future readers.

You will probably have a SomeFile.tf file that DECLARES the variable.

variable "myCoolVariable" { type = "string" description = "myCoolVariable Description." default = "" }

Notice, I'm setting the default to empty-string on purpose. Because I want it to be filled with the value from the tfvars file that has the SET variable (described immediately below)

Then you'll have a myfile.tfvars file that SETS the (in this case...overrides that empty-string) value. Note for string its a simple name = "value"

myCoolVariable = "MyCoolValue"

~Then you'll run the code as seen below. SomeFile.tf will be "auto included" because it ends with .tf.
you'll use the command line to specify the tfvars file. Note, because I'm using powershell, I an putting double-quotes around my tfvars file name.

terraform.exe apply --var-file="myfile.tfvars"

Then it worked!

All 5 comments

Hi @NicholasPCole. Sorry for the frustrations here.

I think the issue here is that -var-file doesn't do what you're expecting here. You are attempting to use it to refer to a file containing variable configuration blocks that _declare_ variables, but it's actually for referencing files containing variable _assignments_.

However, I see that you've already tried a variant of the config where the variable block moves into a .tf file in your configuration directory, and that didn't work for you either. I'm a little confused by the error message you received there: I would've expected instead for you to see an error saying that the digitalocean_api_token is required, since you didn't provide a default.

I would expect the following formulation to work:

# configuration.tf

variable "digitalocean_api_token" {}

provider "digitalocean" {
  token = "${var.digitalocean_api_token}"
}

resource "digitalocean_droplet" "xenial" {
  image = "ubuntu-16-04-x64"
  name = "ubuntu-xenial"
  region = "nyc1"
  size = "512mb"
}
# ../secrets.tfvars

digitalocean_api_token = "abcdef"

You'd then invoke Terraform as follows, with the current directory being the one containing the configuration.tf file:

terraform plan -var-file="../secrets.tfvars"

There are some other possible permutations here that place different data in different places, but the above should work. Would you mind giving it a try and letting me know how it works out? At first blush it seems the same as your second example except that I still referenced the secrets.tfvars file in the command line to set the value; I'm not sure if there's something deeper going on in your case that I'm not seeing.

Thanks so much for taking a look and replying, @apparentlymart. I spent an embarrassingly long time trying to figure this out the other night and that explanation of declaring vs. assigning cleared it up perfectly. :)

I haven't seen any sort of "digitalocean_api_token is required" error message, but it works following your example of changing ../secrets.tfvars to contain an assignment instead of a declaration. I'll go ahead and close this issue; thanks again!

Gaaaaaaaaaaaaaaaaaa. This same issue was driving me nuts.

Now I "see" it, the difference between declaration and assigning.

For future readers.

You will probably have a SomeFile.tf file that DECLARES the variable.

variable "myCoolVariable" { type = "string" description = "myCoolVariable Description." default = "" }

Notice, I'm setting the default to empty-string on purpose. Because I want it to be filled with the value from the tfvars file that has the SET variable (described immediately below)

Then you'll have a myfile.tfvars file that SETS the (in this case...overrides that empty-string) value. Note for string its a simple name = "value"

myCoolVariable = "MyCoolValue"

~Then you'll run the code as seen below. SomeFile.tf will be "auto included" because it ends with .tf.
you'll use the command line to specify the tfvars file. Note, because I'm using powershell, I an putting double-quotes around my tfvars file name.

terraform.exe apply --var-file="myfile.tfvars"

Then it worked!

In my case it was because I was using a module, but the variables.tf declaration were outside the module. It fixed once I moved it to inside the module.

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

bloopletech picture bloopletech  ยท  82Comments

kforsthoevel picture kforsthoevel  ยท  86Comments

jszwedko picture jszwedko  ยท  77Comments

mirogta picture mirogta  ยท  74Comments

felnne picture felnne  ยท  133Comments