Terraform supports several variable types for using with Input Variables. The most common is likely the string
type but Terraform also supports a few more type options to choose from.
Terraform supports three primitive types for Input Variables. These are the primary primitive types supported by all programming languages for representing variables of strings, numbers, and boolean values.
Here’s the list of primitive types supported by Terraform along with descriptions of the type of data they can represent:
Here are simple examples of defining Input Variables using each of the primitive types:
In addition to primitive types, Terraform also supports a couple complex types. Complex types allow you to group multiple values together into a single variable. Complex types in Terraform are represented using type constructors; with shorthand keyword versions supported as well.
Here’s the list of complex types supported by Terraform along with descriptions of the types:
Collection Types
The Collection types in Terraform as similar to the programming construct called an Array. They allow you to group multiple values of the same type into single variable value.
There are three kinds of Collection types in Terraform:
list(...)
– A sequence of values identified by an index starting with zero.map(...)
– A collection of values; each with a string label identifier.set(...)
– A collection of unique values without any secondary identifiers or ordering.
Here are simple examples of defining Input Variables using each of the Collection types:
# List of type String
variable "vm_ip_allow_list" {
type = list(string)
}
# Map of Strings
variable "vm_ip_map" {
type = map(string)
}
# Set of Numbers
variable "my_set" {
type = set(number)
}
Here are sample values for each of the above Input Variable examples of Collection types:
# List of type String
vm_ip_allow_list = [
'10.50.0.1/32'
'10.83.0.5/32'
]
# Map of Strings (using colons ':')
vm_ip_map = {
"vm1": "10.50.0.1/32"
"vm2": "10.83.0.5/32"
}
# Map of Strings (using equals '=')
vm_ip_map = {
"vm1" = "10.50.0.1/32"
"vm2" = "10.83.0.5/32"
}
# Set of Numbers
my_set = [1, 2, 3, 4, 5]
Note: The Terraform map complex type can be compared to a Key / Value Dictionary type in other programming languages. You define a set of values, then each individual value can be referenced using the string label identifier as the key to retrieve just that single value.
Structural Types
Structural types in Terraform allow multiple values of different types to be grouped together as a single value. Using structural types requires a data schema to be defined for the Input Variables type so that Terraform knows what a valid value is.
Here’s are the two structural types supported in Terraform:
object(...)
– A collection of values each with their own type.tuple(...)
– A sequence of values each with their own type.
Here are simple examples of defining Input Variables using each of the Structural types:
# Object with defined schema
variable "vm_configs" {
type = object({
location = string
size = string
instance_count = number
})
}
# Tuple with defined schema
variable "tuple_values" {
type = tuple([
string,
number,
bool
])
}
Here are sample values for each of the above Input Variable examples of Structural types:
# Input Variable of type Object
vm_configs = {
location = "eastus"
size = "Standard_DS2"
instance_count = 4
}
# Input Variable of type Tuple
tuple_values = [
"Chris",
42,
true
]
Configure Resources using Input Variables
Input Variables can be referenced within Terraform code using the var
keyword that exposes a sort of object that makes properties accessible for each of the Input Variables defined. Input Variables are referenced in a similar fashion to local
variables this way by using the var
keyword instead.
Here’s an example of referencing an Input Variable named location
:
var.location
Referencing Input Variables is useless unless you use the value of the variable to configure a resource. You can assign the Input Variable value directly to resources properties, like the following:
# Create an Azure resource group using the passed in location
resource "azurerm_resource_group" "b59" {
name = "b59-rg"
location = var.location
}
You can also assign Input Variable values to local
variables, or even use them as inputs to other Terraform functions.
locals {
location_to_use = var.location
location_lower = lower(var.location)
}
Pass Input Variables to Terraform Deployments
Input Variables in Terraform are used to pass in configuration values to the Terraform project at time of deployment. There are two methods supported for doing this using the Terraform CLI when running Terraform commands.
-var
flag enables a single input variable value to be passed in at the command-line.-var-file
flag enables multiple input variable values to be passed in by referencing a file that contains the values.
Using the -var
Command-line Flag
The -var
flag is used to pass values for Input Variables to Terraform commands. This flag can be used with both of the Terraform plan
and apply
commands.
The argument passed to the -var
flag is a string surrounded by either single or double quotes. The value within the quotes is made up of the name of the Input Variable followed by a equal (=
) sign then followed by the value for the Input Variable to pass in.
Input Variable values are passed to the -var
flag in the below format:
# Using single quotes
-var '<input-variable-name>=<value>'
# Using double quotes
-var "<input-variable-name>=<value>"
Here’s are some examples showing how to pass Input Variable values to Terraform commands:
# Pass Input Variable to 'plan' command
terraform plan \
-var 'location=eastus' \
-var 'vm_size=Standard_DS2'
# Pass Input Variable to 'apply' command
terraform apply \
-var 'location=eastus' \
-var 'vm_size=Standard_DS2'
Related: If you’re interested in taking the code reuse in the direction of implementing conditional deployment logic, then we recommend you also check out the “Terraform Feature Flags & Environment Toggle Design Patterns | Build5Nines” written by Chris Pietschmann.
The above examples of the -var
flag for Terraform commands pass in string type Input Variables. The -var
flag can also be used to pass in Input Variables with list
and map
data types. Here’s a couple examples showing how to pass the values for these types of Input Variables to Terraform commands:
# List Input Variable
terraform apply \
-var='locations=["eastus","westus"]'
# Map Input Variable
terraform apply \
-var='location_resource_group_name={"eastus": "App-EastUS-RG", "westus": "App-WestUS-RG"}'
Remember, the -var
argument can be used multiple times on a single Terraform command to add all the necessary Input Parameters required for the Terraform project.
Using .tfvars
Files and -var-file
Command-line Flag
The -var-file
flag is used to pass Input Variable values into Terraform plan
and apply
commands using a file that contains the values. This allows you to save the Input Variable values in a file with a .tfvars
extension that can be checked into source control for you variable environments you need to deploy to / manage.
The .tfvars
file contents will contain the definition for the Input Variable values to pass into the Terraform commands. These are defined in a similar way to how local
Variables are defined in Terraform code.
Here’s an example .tfvars
file defining a few Input Variable values:
environment = 'production'
location = 'eastus'
vm_instance_count = 4
vm_ip_allow_list = [
'10.50.0.1/32'
'10.83.0.5/32'
]
Once you have one or more .tfvars
files created, you can then use the -var-file
flag to pass in the name of the file for Terraform to pull in for passing Input Variables to the Terraform command. Multiple -var-file
flags can be used on the same Terraform command to pass in multiple .tfplans
files as necessary.
Here’s a couple examples of using the -var-file
flag to pass in .tfvars
files to Terraform commands:
# Pass .tfvar files to 'plan' command
terraform plan \
-var-file 'production.tfvars' \
-var-file 'secrets.tfvars'
# Pass .tfvar files to 'apply ' command
terraform apply \
-var-file 'production.tfvars' \
-var-file 'secrets.tfvars'
It’s worth noting that you can pass in both -var
and -var-file
flags into either the plan
or apply
commands at the same time. This is useful when you have multiple Input Variable values defined within .tfvars
files that are checked into source control, while other Input Variables must be passed in at the command-line as part of a CI/CD release pipeline.
Here’s an example of passing in both to the terraform apply
command:
terraform plan \
-var 'secret=$(secretValue)'
-var-file 'production.tfvars'
Notice, in the above example, the secret
Input Variable is being passed in with the value from the $(secretValue)
bash variable. When running a Terraform command inside a CI/CD pipeline, the previous step of the pipeline or even the pipeline variables will define what the value is for this Input Variable. This way you can have the CI/CD pipeline pass in the specific value for a Terraform Input Variable without the value being checked into source control, as the .tfvars
files will be contained within the source repository with the rest of the Terraform project files. This is a common method of passing in passwords or other secrets that are environment specific, but also need to be hidden from accessibility by developers or other team members with access to the source code repository.
Load Input Variables Automatically from .tfvars
Files
In addition to using the -var-file
flag to explicitly specify the -tfvars
files to use for declaring the Input Variable values, you can also use certain special file names for Terraform to automatically pull in .tfvars
files. There are a couple different file names and naming pattern you can use for .tfvars
files in your Terraform project, and Terraform will automatically load them when you run a Terraform plan
or apply
command.
The automatic loading of .tfva
rs files is based on the following file names and pattern:
- Files named with these exact file names will automatically be loaded to populate Input Variables:
terraform.tfvars
or terraform.tfvars.json
- Any files with the following suffixes will automatically be loaded to populate Input Variables:
.auto.tfvars
or .auto.tfvars.json
Files with names that end in .json
are parsed in as JSON objects. The root object properties correspond to Input Variable names.
Here’s a simple JSON example of the contents that could be used within a .json
file defining Input Variables:
{
"location": "eastus",
"vm_ip_allow_list": [
'10.50.0.1/32'
'10.83.0.5/32'
]
}
Using Environment Variables
When running Terraform commands, you can also use Environment Variables to define the values for Input Variables on your Terraform project. Terraform automatically will pull in any Environment Variables that are named using the prefix of TF_VAR_
followed by the name of the Input Variable.
When using Environment Variables to define Input Variables for Terraform deployment, be sure to keep in mind that if the Operating System is case-sensitive, then Terraform will match variable names exactly as given during configuration. As a result, the upper and lower case of the Environment Variable will need to exactly match the Input Variable name.
Set Environment Variable using Bash
Here’s an example using Bash to specify the value of an Input Variable named location
by setting the Environment Variable TF_VAR_location
:
$ export TF_VAR_location="eastus"
Set Environment Variable using PowerShell
Here’s an example of using PowerShell to specify the value of an Input Variable named location
by setting the Environment Variable TF_VAR_location
:
PS C:\> $env:TF_VAR_location = 'eastus'
Once the Environment Variable is set with the TF_VAR_
prefix, then Terraform will automatically pull in it’s value for the Input Variable with the same name when running Terraform commands.
Complex Type Environment Variables
The map
and list
complex type values can also be defined using Environment Variables when passing Input Variable values to Terraform plan
and apply
commands.
Here’s an example of defining a list
data type Input Variable value using an Environment Variable using Bash:
$ export TF_VAR_locations='["eastus","westus"]'
When using this method to define complex typed Input Variable values, take care with string escaping rules of the Bash shell. Be sure to mind readability and ease of maintenance with scripts using this method. It’s generally recommended to use .tfvars
files where possible to avoid mistakes with passing complex types Input Variable values to Terraform commands.
Input Variable Definition Precedence
With multiple methods of being able to pass Input Variable values to Terraform plan
and apply
commands there is a specific order in which variables values are assigned. This is important if the same Input Variable is specified multiple times so you can be sure the expected value is used to override other duplicate value definitions for the same Input Variable.
When Terraform loads Input Variable values from the various definition methods, they are loaded in the following order with later sources taking precedence over earlier sources:
- Environment variables
terraform.tfvars
file, if presentterraform.tfvars.json
file, if present- Any
.auto.tfvars
or .auto.tfvars.json
files, processed in lexical order of their filenames. - Any
-var
and -var-file
flags on the command-line, in the order they are provided.
Note: With Terraform 0.12 and later, variables for map and object values behave as other types with the later source taking precedence over earlier sources. Previous versions of Terraform will merge map values together rather than override them.
Wrap Up
You can use Input Variables to pass in variable values to Terraform deployments. These can be used to define feature flags and other varying configurations that need to be different for different environments you are deploying to. There are multiple methods of passing in Input Variables (command-line flags, .tfvars
files and Environment Variables) giving you flexibility in defining and passing the values in to the deployment.
Happy Terraforming!
Niciun comentariu:
Trimiteți un comentariu