Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set variables from env vars #1621

Merged
merged 2 commits into from
Apr 22, 2015
Merged

Set variables from env vars #1621

merged 2 commits into from
Apr 22, 2015

Conversation

mitchellh
Copy link
Contributor

Fixes #62 (enough for now, at least)

This makes it so that you can set the env var TF_VAR_name to set the variable with the name "name".

In the future, we'd still like to add ${env.NAME} syntax to the configuration, but the way we'd like to do that represents significantly more engineering effort. This is a nice stop-gap solution to support env vars for configuration that is simple to implement. And it isn't mutually exclusive to env.NAME interpolations: we'll keep both when we implement them.

I've found this style of configuration to be very useful in automation environments.

@knuckolls
Copy link
Contributor

I like this as a stopgap and prefer it to tfvars files. 💯 lgtm

@phinze
Copy link
Contributor

phinze commented Apr 22, 2015

Fresh, simple, delicious. 🚢

mitchellh added a commit that referenced this pull request Apr 22, 2015
Set variables from env vars
@mitchellh mitchellh merged commit af4396a into master Apr 22, 2015
@mitchellh mitchellh deleted the f-envs branch April 22, 2015 13:50
@JeanMertz
Copy link
Contributor

@mitchellh I am having troubles getting this to work.

If I set TF_VAR_dme_akey and I have a module calling a dme_record resource, and that module has a variables.tf file with dme_akey and dme_skey variables, I still get the error:

* module root: module dns: required variable dme_akey not set

Does the environment variable not propagate through to a module?

I am using the Terraform master branch.

update actually it doesn't seem to work for non-modules as well. I suspect this is an error on my side. Investigating.

@mitchellh
Copy link
Contributor Author

@JeanMertz You can only set variables in the root module, can you show me your config?

@enxebre
Copy link

enxebre commented May 11, 2015

Just notice that variables needs to has a default value other wise TF_VAR won't work as terraform breaks before during apply. Also does this support overriding values for Mappings?
Many thanks for such a great work!

@clstokes
Copy link
Contributor

@enxebre I ran into the default value issue as well and opened #1930 to address it. Feel free to add to it if I missed something.

@tamsky
Copy link
Contributor

tamsky commented Jun 2, 2015

And it isn't mutually exclusive to env.NAME interpolations: we'll keep both when we implement them.

Any chance you've already decided, and are willing to share, which of the two TF_VAR_NAME vs ${env.NAME} will have precedence over the other?

@eppdot
Copy link

eppdot commented Jun 17, 2015

it would be nice if environment variables propagate into modules aswell.

@rgabo
Copy link

rgabo commented Jul 1, 2015

Relying on standard environment variables such as USER for sensible defaults would be nice so still looking forward to ${env.USER} 😄

We'd use USER as the default value for key_name and a prefix we use to isolate environments from each other. Let everyone have their little sandbox by default. Permanent environments (dev, prd) are shared through remote state and shared key.

@pll
Copy link

pll commented Jul 16, 2015

+1 for ${env.FOO} support.

I want to use ${env.USER} and other things as well. This would be especially handy when tagging things

@james-s-nduka
Copy link

+1 for being able to use ${env.FOO}

@tamsky
Copy link
Contributor

tamsky commented Sep 14, 2015

We currently use a little helper script to do this for us:

#!/bin/bash
DATE=$(date +%D)
export TF_VAR_username=$USER
export TF_VAR_date="$DATE"

exec terraform "$@"

@goodtune
Copy link

I wrote a bash wrapper to load my variables to the environment from a .vars file.

#!/bin/bash
# https://gist.github.com/goodtune/2cd676718b16752816a4

# Use this script to load the contents of a .vars file in your current working
# directory into the environment before running terraform.
#
# Useful for avoiding numerous '-var "var=val"' options on the command line.
#
# Your .vars file should contain each var=val on a single line.

/usr/bin/env -S "$(sed -e 's/^/TF_VAR_/' .vars 2> /dev/null)" \
    terraform "$@"

I place this in my ~/bin directory and then can, for example, do either of:

terraform plan -var do_token=xxx -var do_region=nyc2

or

tf plan

@scarolan
Copy link
Contributor

Could someone provide a simple example of how I can read AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables into my terraform config, without hard-coding the keys anywhere? I searched high and low and was unable to find a simple, clear example for new users.

@pll
Copy link

pll commented Dec 30, 2015

@scarolan - The best solution I found was to write a wrapper around terraform to allow me to use a profile listed in ~/.aws/credentials. Check out my runTF.py script here:

https://github.com/pll/terraform_infrastructure

for an example of how I did it. That's not the latest version of the code, but it works (I've vastly simplified it since I put this up).

@scarolan
Copy link
Contributor

Thanks, hopefully the developers will consider reading in these credentials directly from ~/.aws/config or ~/.aws/credentials, or environment variables in the future. Having to put these creds in another file, or jump through other hoops (like wrapper scripts) feels janky.

@pll
Copy link

pll commented Dec 30, 2015

You can definitely set environment variables, that's clearly documented. You can also pass them in as -var='aws_access_key=XXX' and -var='aws_secret_key=YYY'

@scarolan
Copy link
Contributor

@pll I don't want to set environment variables. I already have them, and i'm wiling to make more if I need to match the naming syntax. What I want to know is how do I use these in my example.tf file, instead of hard-coding my keys in yet another file.

AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY

@scarolan
Copy link
Contributor

Trying to work through the quickstart intro, what do I put in here?

provider "aws" {
    access_key = WHATGOESHERE
    secret_key = ANDHERE
    region = "us-east-1"
}

resource "aws_instance" "example" {
    ami = "ami-d05e75b8"
    instance_type = "t2.micro"
}

@pll
Copy link

pll commented Dec 30, 2015

"${aws_access_key}"
"$aws_secret_key}"

Then, from the command line, run tf like this:

$ terraform plan -var='aws_access_key=YOUR_AWS_ACCESS_KEY' -var='aws_secret_key=YOUR_AWS_SECRET_KEY'

@scarolan
Copy link
Contributor

got it. So what you're saying is there is no way to simply run terraform plan by itself without:

A. A wrapper script
B. Adding those env vars on the command line
C. Hard-coding my keys into another file inside the directory

@pll
Copy link

pll commented Dec 30, 2015

No, you can also use environment variables as explained here:
https://www.terraform.io/docs/providers/aws/

@pll
Copy link

pll commented Dec 30, 2015

FYI: You should join the #terraform-tool irc channel, it's more real-time :)

@scarolan
Copy link
Contributor

Thanks, i'll jump in there.

@zerolaser
Copy link

zerolaser commented Sep 15, 2016

@phinze The correct way of using environment variable is to
export TF_VAR_profile=$AWS_PROFILE and then perform terraform plan ?
or
assigning directly like this ?
provider "aws" {
region = "${var.region}"
profile = "${env.AWS_PROFILE}"
}

@devops1337
Copy link

devops1337 commented Dec 16, 2016

This doesn't work for uppercase vars in the following key rds_db_name = "TF_VAR_RDS_DB_NAME" returns:

Errors:

  * aws_db_instance.dbx: only lowercase alphanumeric characters and hyphens allowed in "identifier"
  * aws_db_instance.dbx: first character of "identifier" must be a letter

Lowercase does appear to work rds_db_name = "TF_VAR_rds_db_name". Other uppercase VARS appear to be working (not returning errors).

@devops1337
Copy link

devops1337 commented Dec 16, 2016

And the following doesn't appear to be working for me:

aws_access_key = "TF_VAR_AWS_ACCESS_KEY"
aws_secret_key = "TF_VAR_AWS_SECRET_KEY"

Vars set as export AWS_ACCESS_KEY=<access-key> && export AWS_SECRET_KEY=<secret-key>.

Returns:

Error refreshing state: 1 error(s) occurred:

* InvalidClientTokenId: The security token included in the request is invalid.
        status code: 403, request id: xxx

The keys are correct. Now I just input the keys manually.

@mitchellh
Copy link
Contributor Author

@devops1337 This allows variables to be set with env vars, not you to specify values coming from env vars. It appears your latter example is trying to do that... Instead the way you'd set them as TF_VAR_aws_access_key

@ghost
Copy link

ghost commented Apr 18, 2020

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.

@ghost ghost locked and limited conversation to collaborators Apr 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Environment variables in .tf files