4.4. Config Files

Preparation

Create a new directory for this exercise:

mkdir -p $LAB_ROOT/intermediate/multi_env
cd $LAB_ROOT/intermediate/multi_env

Optional: Create empty files:

touch {main,variables,outputs}.tf

Step 4.4.1: Define variable and output

Create a new file named variables.tf and add the following content:

variable "environment" {}

Create a new file named outputs.tf and add the following content:

output "current_env" {
  value = var.environment
}

Create a new file named main.tf and add the following content:

terraform {
  backend "local" {}
}

Explanation

The backend of type local is declared but missing the path argument; this is a so-called “partial configuration”. The missing argument will be added via a config file.

Step 4.4.2: Offload configuration to separate files

It is best practice separating configuration from HCL code. For this purpose we create a dedicated directory:

mkdir config

Create a new file named config/dev.tfvars and add the following content:

environment = "dev"

Create a new file named config/dev_backend.tfvars and add the following content:

path = "dev.tfstate"

Step 4.4.3: Init and apply using config files

Now we init Terraform by specifying a backend configuration with the option -backend-config:

terraform init -backend-config=config/dev_backend.tfvars

Then we apply the code by specifying a variable configuration with the option -var-file:

terraform apply -var-file=config/dev.tfvars

You should now see the following output:

...
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

current_env = "dev"

And a state file called dev.tfstate containing the Terraform state.

Explanation

The backend and variable configuration files abstract the code from different “instances”. This pattern can be used to provision different environments like dev, test, prod.

Step 4.4.4: Create a production configuration

To add another set of configuration for a “production” environment, lets just add two more files:

Create a new file named config/prod.tfvars and add the following content:

environment = "prod"

Create a new file named config/prod_backend.tfvars and add the following content:

path = "prod.tfstate"
terraform init -backend-config=config/prod_backend.tfvars -reconfigure
terraform apply -var-file=config/prod.tfvars

You should now see two Terraform state files for each set of configuration:

  • dev.tfstate
  • prod.tfstate

Try it out

It is a common pattern to set credentials via the shell environment. Terraform has built-in support to set variables via environment by prefixing the Terraform variable name with TF_VAR_.

Add the following to variables.tf:

variable "secret" { }

and the following to outputs.tf:

output "secret" {
  value = var.secret
}

Then set the value in the shell:

export TF_VAR_secret=mysupersecret

Now run terraform apply -var-file=config/prod.tfvars