25

(Please note: after receiving initial answers, this issue seems to not be just an issue with passing the variables, but with modularizing my configurations, note at the bottom where I hardcode the values yet the UI prompts me to provide the values)

Code example here

I've got a project I've broken into the following directory structure

master.tf
variables.tfvars
- providers/
-- digital_ocean/
--- digital_ocean.tf
--- variables.tf
-- cloud_flare/
--- cloud_flare.tf
--- variables.tf
- management/
-- jenkins/
--- jenkins-master.tf

I'm attempting to pass my Digital Ocean and Cloudflare tokens as variables, to their respective modules. Everything below the root directory is loaded into master.tf as a module.

I have the following in my varaibles.tfvars file:

cloudflare_email  ="service@email.com"
cloudflare_token  ="TOKEN_STRING"
do_token          ="${DO_PAT}"

The following lines appear in my master.tf

variable "do_token" {}
module "digital_ocean" {
    source          = "./providers/digital_ocean"
    token           = "${var.do_token}"
}


variable "cloudflare_email" {}
variable "cloudflare_token" {}
module "cloud_flare" {
    source          = "./providers/cloud_flare"
    email = "${var.cloudflare_email}"
    token = "${var.cloudflare_token}"
}

My digital_ocean module looks like

variable "token" {}

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

and the cloudflare provider looks like

variable "email" {}
variable "token" {}

provider "CloudFlare" {
    email = "${var.email}"
    token = "${var.token}"
}

Setting up my jenkins master server on DO

resource "digitalocean_droplet" "jenkins-master" {
...
}

From the command line I'm running terraform apply -var-file="variables.tfvars"

or I've also tried passing them via the CLI like so..

terraform apply \
  -var "cloudflare_email=service@email.com" \
  -var "cloudflare_token=TOKEN_STRING" \
  -var "do_token=${DO_PAT}"

With the above declarations, it will send me into UI mode and prompt me for those variables rather than reading them automatically. I've replicated this behavior on both Terraform v0.9.8 and v0.9.10.

Before I started breaking everything out into separate modules, passing in variables presented no issues.

I've tried pulling the provider declarations into master.tf to see if there were any weird behaviors with modularizing them, with the same behavior.

I also tried hard coding the values into the provider declarations and am experiencing the same behaviors.

codewizard
  • 1,029
  • 1
  • 13
  • 22

3 Answers3

39

Your variables.tfvars file should be named terraform.tfvars.

Per the docs:

If a terraform.tfvars file is present in the current directory, Terraform automatically loads it to populate variables. If the file is named something else, you can use the -var-file flag directly to specify a file. These files are the same syntax as Terraform configuration files. And like Terraform configuration files, these files can also be JSON.

If you want to use your own filenaming convention, you can set an alternative tfvars file with the -var-file flag like this (per the linked docs):

$ terraform plan \
-var-file="secret.tfvars" \
-var-file="production.tfvars"

For the CLI, you should quote only the value of the variable, like so:

terraform apply \ 
-var cloudflare_email="service@email.com" \ 
-var cloudflare_token="TOKEN_STRING" \ 
-var do_token="${DO_PAT}"
giraffesyo
  • 4,860
  • 1
  • 29
  • 39
vageli
  • 640
  • 5
  • 13
  • I was using he -var-file command but even still renaming the file to `terraform.tfvars` and quoting only the values in the CLI do not resolve the issue. – codewizard Jul 03 '17 at 15:46
  • I reproduced on my machine and renaming the file worked for me, but I have terraform 0.9.6. Are your cloudflare variables in `--- variables.tg` like it says in your question? The file extension could be an issue. – vageli Jul 03 '17 at 16:02
  • Sorry that was a typo. I'll update that to reflect `variables.tfvars`. Let me test in 0.9.6 and see if that resolves the issue. – codewizard Jul 03 '17 at 16:14
  • Hmmmm, switching to 0.9.6 doesn't seem to resolve the issue. Any chance I can convince you to upload a public git repo with what you've put together? I'll try to trim back the unnecessary parts of mine and put it online. – codewizard Jul 03 '17 at 16:20
  • I've provided a link to a github repo at the top of the question. Would you mind looking to see how it differs from yours. – codewizard Jul 03 '17 at 16:37
  • Running the code in your repo, I was prompted only for the digital ocean token – vageli Jul 03 '17 at 17:41
  • @codewizard Using the digitalocean provider directly in `master.tf` worked for me. Your issue is very much like one my colleague ran into: https://github.com/terraform-providers/terraform-provider-aws/issues/1043 – vageli Jul 03 '17 at 17:54
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/148245/discussion-between-vageli-and-codewizard). – vageli Jul 03 '17 at 17:57
4

Under your "Digital_ocean module" and "cloudflare provider", you declared two additional variables (which is "token" and "email") but you haven't captured the corresponding value in your variables.tfvars

Your vairables.tfvars should capture the values for token and email as below. That way you can use terraform apply -var-file="variables.tfvars" with out issue

cloudflare_email  ="service@email.com"
cloudflare_token  ="TOKEN_STRING"
do_token          ="${DO_PAT}"
token             ="token_string"
email             ="another@email.com"

or explicitly mention it with var as below

terraform apply -var "cloudflare_email=service@email.com" -var "cloudflare_token=TOKEN_STRING" -var "do_token=${DO_PAT}" -var "token=TOKEN_string -var "email=another@email.com"

I hope that helps

Innocent Anigbo
  • 4,435
  • 1
  • 19
  • 19
  • Unfortunately that is not the answer. Im passing the token and email variables when calling the module in master.tf. If I make the variable names consistent from the tfvars to the provider definition, it does not help either. – codewizard Jul 03 '17 at 14:58
  • Fair enough, but the token and email variables with corresponding value aren't mentioned in your master.tf config above. Where is the value for "${DO_PAT}" passed? – Innocent Anigbo Jul 03 '17 at 15:34
  • i'm not sure I follow what you're saying, they are in master.tf when I call the module? ```module "cloud_flare" { source = "./providers/cloud_flare" email = "${var.cloudflare_email}" token = "${var.cloudflare_token}" } ``` DO_PAT is an environment variable. And I guess that probably won't just get pulled into my tfvars, I just copied it over from when I was passing the variables via the command line. – codewizard Jul 03 '17 at 15:41
-4

this is wrong terraform apply -var-file="variables.tfvars"

terraform apply does not have this option var-file ,only plan has.

Eric
  • 1
  • 2
  • 2
    Please see this https://www.terraform.io/docs/language/values/variables.html#variable-definitions-tfvars-files#:~:text=terraform%20apply%20-var-file=%22testing.tfvars%22 – Ked Mardemootoo Jun 08 '21 at 11:20