HashiCorp Learn
Infrastructure
  • TerraformTerraformLearn terraformDocs
  • PackerPackerLearn packerDocs
  • VagrantVagrantLearn vagrantDocs
Security
  • VaultVaultLearn vaultDocs
  • BoundaryBoundaryLearn boundaryDocs
Networking
  • ConsulConsulLearn consulDocs
Applications
  • NomadNomadLearn nomadDocs
  • WaypointWaypointLearn waypointDocs
  • HashiCorp Cloud Platform (HCP) LogoHashiCorp Cloud Platform (HCP)HashiCorp Cloud Platform (HCP)Docs
Type '/' to Search
Loading account...
  • Bookmarks
  • Manage Account
  • Overview
  • Defining Variables
  • Using Variables in Configuration
  • Assigning Variables
  • Variable Types
DocsForum
Back to terraform
GCPView Collection
    Introduction to Infrastructure as Code with TerraformInstall TerraformBuild InfrastructureChange InfrastructureDestroy InfrastructureCreate Resource DependenciesProvision InfrastructureDefine Input VariablesQuery Data with Output Variables

Define Input Variables

  • 7 min
  • Products Usedterraform

You now have enough Terraform knowledge to create useful configurations, but the configuration still hardcodes the project name, zone, and other arguments. To become truly shareable and version controlled, we need to parameterize the configurations. This page introduces input variables as a way to do this.

»Defining Variables

First, convert a few of the hardcoded values into variables.

Create another file called variables.tf with the following contents:

variable "project" { }

variable "credentials_file" { }

variable "region" {
  default = "us-central1"
}

variable "zone" {
  default = "us-central1-c"
}

Tip:: Terraform loads all files ending in .tf in a directory, so it doesn't matter to terraform where your variables are defined. We recommend defining them in their own file to make your configuration easier to organize and understand.

This file defines three variables within your Terraform configuration. The first one has an empty block: { }. The other two set defaults. If a default value is set, the variable is optional. Otherwise, the variable is required. If you run terraform plan now, Terraform will prompt you for the values for project and credentials_file.

»Using Variables in Configuration

Next, update the GCP provider configuration in main.tf to use these new variables.

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
    }
  }
}

provider "google" {
  version = "3.5.0"

- credentials = file("<NAME>.json")
+ credentials = file(var.credentials_file)

- project = "<PROJECT_ID>"
- region  = "us-central1"
- zone    = "us-central1-c"
+ project = var.project
+ region  = var.region
+ zone    = var.zone
}

Variables are referenced with the var. prefix.

»Assigning Variables

There are several ways to assign variables, depending on your needs.

»Command-line flags

You can set variables directly on the command-line with the -var flag. Any command in Terraform that inspects the configuration accepts this flag, such as apply, plan, and refresh:

$ terraform plan -var 'project=<PROJECT_ID>'
var.credentials_file
  Enter a value:

Setting variables this way will not save them, and they'll have to be passed this way every time you run terraform. Notice that since you didn't enter all the variables on the command line, Terraform prompts you for the remaining ones. Cancel the run with Ctrl+C.

»From a file

To persist variable values, create a file and assign variables within this file. Create a new file named terraform.tfvars with the following contents:

project = "<PROJECT_ID>"
credentials_file = "<NAME>.json"

Note: Be sure to replace <PROJECT_ID> with your project's ID, and <NAME> with the name of your credentials file.

Terraform automatically loads all files which match terraform.tfvars or *.auto.tfvars present in the current directory to populate variables. You can also specify a file to load with the -var-file command line argument.

These files are the same syntax as Terraform configuration files.

For security reasons, we recommend never saving usernames and passwords to version control. Your terraform configuration will probably need these secret values, though. One solution is to create a local secret variables file and use -var-file to load it. You can also use multiple -var-file arguments in a single command, with some checked in to version control and others not checked in.

»From environment variables

Terraform will read environment variables in the form of TF_VAR_name to find the value for a variable. For example, in this configuration the TF_VAR_region environment variable could be used to set the region terraform variable.

»UI Input

If you execute terraform apply with some variables unspecified, Terraform will ask you to input their values interactively. These values are not saved, but this provides a convenient workflow when getting started with Terraform. UI input is not recommended for everyday use of Terraform.

Note: In Terraform versions 0.11 and earlier, UI input is only supported for string variables. List and map variables must be populated via one of the other mechanisms. Terraform 0.12 introduces the ability to populate complex variable types from the UI prompt.

»Variable Defaults

If no value is assigned to a variable via any of these methods and the variable has a default key in its declaration, that value will be used for the variable.

»Variable Types

Terraform supports a number of different variable types. The most common ones are described below, and you can read the Terraform documentation for a complete list.

»Strings

If no type is specified, then Terraform assumes a variable is a string. Like most programming languages, strings are just a sequence of characters. You can also explicitly define a variable as a string.

Explicitly define project as a string by updating variables.tf.

variable "project" {
+ type = string
}

This usually isn't necessary, though, since the string type would otherwise be assumed.

»Numbers

A number, like a string, is pretty straightforward. Any valid integer or floating point value is allowed. When processing your configuration, Terraform will generally do the right thing when converting from a string to a number. So defining the number type is more about ensure the correct type of input is used.

variable "web_instance_count" {
  type    = number
  default = 1
}

»Lists

Like lists or arrays found in many programming languages, a list is a sequence of values.

Add a variable to variables.tf to define the CIDR network blocks to your configuration as a list by either setting the default to a list, or setting the type to list.

variable "cidrs" { default = [] }

You can specify list values in a tfvars file as well. Add the following to terraform.tfvars:

cidrs = [ "10.0.0.0/16", "10.1.0.0/16" ]

We'll use these values later on in this tutorial.

»Maps

Maps are a way to create variables that are lookup tables. Terraform maps are similar to data structures found in programming languages, sometimes referred to as maps or dictionaries.

In your configuration, the machine type is currently set to f1-micro. You might want different machine types for different environments. You can use a map to accomplish this.

Add a map that defines the machine types for each environment to your variables.tf file.

variable "environment" {
  type    = string
  default = "dev"
}

variable "machine_types" {
  type    = map
  default = {
    dev  = "f1-micro"
    test = "n1-highcpu-32"
    prod = "n1-highcpu-32"
  }
}

As with lists, a variable can have a map type assigned explicitly, or it can be implicitly declared as a map by specifying a default value that is a map.

Use the machine_types map to set the machine type for the first vm_instance in main.tf.

resource "google_compute_instance" "vm_instance" {
  name         = "terraform-instance"
-  machine_type = "f1-micro"
+  machine_type = var.machine_types[var.environment]
  tags         = ["web", "dev"]

  # ...
}

The square-bracket index notation used here is how we access values inside a map type variable.

Run terraform plan. Because of the default value we used for environment, you should see that there are no changes to apply.

Maps can also use a static value lookup directly. For example: var.machine_types["dev"] will resolve to "f1-micro".

»Assigning Maps

We set defaults above, but maps can also be set using the -var and -var-file values. For example:

$ terraform apply -var 'machine_types={ dev = "f1-micro", test = "n1-standard-16", prod = "n1-standard-16" }'

Note: Even if every key will be assigned as input, the variable must be established as a map in your configuration by setting its type to map or its default to {}.

You can also set a map's keys from a .tfvars file after it is defined as a map.

Starting with these variable definitions in variables.tf.

variable "region" {
  type = string
  default = "us-central1"
}

variable "machine_types" {
  type    = map
  default = {
    dev  = "f1-micro"
    test = "n1-highcpu-32"
    prod = "n1-highcpu-32"
  }
}

Specify values in your terraform.tfvars file.

region = "us-central1"

machine_types = {
  dev  = "f1-micro"
  test = "n1-highcpu-32"
  prod = "n1-highcpu-32"
}

Once again, running terraform apply at this point will have no effect, because the value "f1-micro" from the map is the same as the hard coded value used originally.


PreviousProvision InfrastructureNextQuery Data with Output Variables
HashiCorp
  • System Status
  • Terms of Use
  • Security
  • Privacy
stdin: is not a tty