Terraform Variables: A Comprehensive Guide to Dynamic Infrastructure Configuration
Malcolm Matalka
On this page
- Introduction
- Introduction to Terraform Variables
- variable_name
- type_constraint
- default_value
- Types of Terraform Variables
- Input Variables
- Local Variables
- Passing Terraform Variables as Input
- Variable Definitions File (variables.tf)
- Variable Values File (.tfvars)
- Runtime Variables
- Defining Variables in Terraform Modules
- Terraform Variable vs. Terraform Output
- Custom Validation Rules
- Use of null Value in Terraform
- Sensitive Data Handling
- Using for_each Loops in Variables
- Creating Multiple S3 Buckets with for_each
- Integration with Terrateam
- Key Features
- Full Example
- Understanding Terrateam
- Frequently Asked Questions
- 1. What is a variable set in Terraform?
- 2. What does ${} do in Terraform?
- 3. What are variable definition files in Terraform, and when should I use them?
- 4. How do I set default values for Terraform variables?
- Conclusion
Introduction
In this guide, we will explore Terraform variables and the part they play when creating infrastructure. You will learn how to define variables and use these variables, including looping constructs, to create multiple resources efficiently. Infrastructure engineers can write reusable Terraform code across various customizable environments to meet specific deployment needs by leveraging variables.
This guide aims to equip you with a thorough understanding of defining, using, and managing variables in Terraform, ensuring your infrastructure is scalable and maintainable—and many more aspects of dynamic infrastructure setup, including looping and sensitive data handling.
Introduction to Terraform Variables
Terraform variables are placeholders for values that can be assigned to various resources, such as the name of an S3 bucket, an EKS cluster, or even the number of machines you want to create.
Using variables, you can easily customize and reuse Terraform code without hardcoding specific values directly into your infrastructure setup.
This flexibility allows for seamless adjustments to different environments or resource requirements by modifying the assigned terraform variables value.
Terraform variables are most commonly declared using the variable
block within your Terraform code, with the following syntax, although there are other ways to define them.
variable_name
Identifies the variable for referencing throughout your code.
type_constraint
Specifies the allowed value types such as ‘string,’’ number’, ‘bool,’ ‘list,’ or ‘map.’
default_value
Defines a default value for the variable, ensuring smooth configuration adjustments.
Types of Terraform Variables
Input Variables
Input variables in Terraform pass values from outside the configuration or module. Input variables allow for dynamic values to be assigned to resource attributes. Input variables are the most common and widely used method to pass values from outside the configuration or module. Input variables act as inputs to resources and can be defined along with specific attributes like type, default, value, and description.
For instance, consider the input variables values in following example:
The above is a declaration of an input variable named instance_type
, which specifies the type of EC2 instance to create. This variable declaration is a string with a default value of “t2.micro” and a description to guide the user.
Local Variables
Local variables simplify and organize configurations by allowing you to define values that are reused within a Terraform resource. These variables can store static and dynamic data, making your configuration more maintainable and readable. They are handy for reducing repetition, enhancing clarity, and managing complex expressions or values used in multiple places.
The provided code includes a local variable named region_identifier
with a value of “us-east-1”. This local variable consistently names resources and their output variable values, ensuring a coherent naming convention that includes the region identifier.
Passing Terraform Variables as Input
Variable Definitions File (variables.tf)
A variables.tf
is a file where you generally define all the variables in one place. This is a common practice for defining the variable definitions files.
Variable Values File (.tfvars)
Variable value files, such as terraform.tfvars
or *.auto.tfvars
, offer a convenient method for managing Terraform’s environment-specific configurations.
main.tf
variables.tfvars
You can use the —var-file
flag during the terraform apply
command to run Terraform with a variable definition and value files such as .tfvars or YAML files. This allows you to choose a file containing the variable values you want to use for the run.
Runtime Variables
Runtime variables are provided at the command line when running Terraform commands like terraform plan
or terraform apply
. You could use this process to pass the variable at runtime.
Defining Variables in Terraform Modules
We’ve learned about using variables. Now, let’s delve into Terraform modules, another key feature that enhances the reusability and maintainability of your Terraform code. A module in Terraform is a container for multiple resources used together. It’s a way to package and encapsulate related resources and variables.
We are now going to create an AWS EC2 instance using Terraform modules. This approach allows us to encapsulate the configuration into a reusable module.
First, create a directory for your module, e.g., modules, and add the following to your module.
variables.tf
main.tf
In the project’s root directory, main.tf file that calls the module, which includes main.tf and variables.tf . Make sure to replace “./modules” with the correct path to your module if it’s different.
main.tf
Run the terraform init
command in your root directory to initialize Terraform.
Terraform Variable vs. Terraform Output
Feature | Terraform Variable | Terraform Output |
---|---|---|
Purpose | Used to pass external input values back into a Terraform configuration. | Used to return information about the infrastructure built or modified to the user. |
Arguments | Input to the Terraform configuration. | Output to the end user about the build of the infrastructure or modifications. |
Usage | Allow users to customize configurations without altering the code. | Enable users to retrieve and use information from the infrastructure, such as IP addresses, keys, or IDs. |
Syntax | Defined within a variable block and referenced with var.<variable_name> | Defined within an output block and referenced with output.<output_name> or via CLI. |
Example | variable "instance_size" { default = "t2.micro" } | output "instance_zones" { value = aws_instance.app_server.availability_zone } |
Custom Validation Rules
Custom validation rules in Terraform allow you to define constraints on the values of your variables, ensuring that user-provided values meet specific criteria before Terraform applies the configuration.
For example, to enforce a naming convention for EC2 instances in Terraform and ensure that all infrastructure components adhere to a standard naming pattern, such as starting with "terrateam"
you can use custom validation within the instance_name variable block.
Custom validation rules in Terraform allow you to specify conditions string values that input variables must meet. If the conditions are not met, Terraform will prevent the plan or apply from proceeding, thus ensuring compliance with your naming standards.
Here’s an example of defining the instance_name variable with a custom validation rule to enforce that every instance name starts with "terrateam"
followed by a word character (letter, digit, or underscore):
main.tf
The regex function is utilized to match the beginning of the instance_name
variable value against the pattern ^terrateam
, where ^
denotes the start of the string, and terrateam
specifies the required prefix for the instance name. The can
function is then used to safely evaluate the regex function. It returns true
if the pattern matches the beginning of the instance_name
value and false
otherwise. If the evaluation returns false
, indicating that the instance name does not start with the required prefix, Terraform will display the specified error message and prevent the configuration from being applied.
Run the terraform apply
command, if we chose the id terrateam-dev01:
We should receive the following output:
If we change the value of instance_name
to something that is not starting with “terrateam”, like “terateam”, the terraform apply
will fail:
Use of null
Value in Terraform
A null
value represents the absence of a value. It can be useful in various scenarios, such as conditionally omitting an argument in a resource or module or representing an optional attribute that has not been set. Using null
can help create more flexible and dynamic Terraform configurations.
The provided Terraform code snippet demonstrates how to use the null
value to create optional functionality within a Terraform configuration. Specifically, it showcases an optional additional_tags
variable for an AWS EC2 instance. This variable is a map of strings intended for additional tags that users might want to apply to the EC2 instance. By default, the map
variable is set to null
, indicating that it is optional and does not require a value to be provided by the user.
Sensitive Data Handling
Handling sensitive data such as passwords securely is crucial in infrastructure management. In our Terraform configuration, we define two variables: username
and password
. The password variable is marked as a sensitive value, ensuring its value is not exposed in plaintext in the Terraform state or console output.
With this configuration, Terraform securely handles the data of sensitive variables, such as passwords. After applying the configuration, the values of the variables are printed to the console, ensuring that sensitive information remains protected.
Using for_each
Loops in Variables
Using for_each
allows you to efficiently create multiple resources with similar configurations. This approach is particularly beneficial when managing a large number of resources that share common characteristics but require individual configuration.
When you use for_each
, Terraform creates a separate instance of the resource or module for each element in the provided map or set. Each instance is managed independently, with its own creation, update, and destruction lifecycle. This is particularly useful when you want to create similar resources that need to be configured slightly differently, such as having different names or settings.
Creating Multiple S3 Buckets with for_each
Let’s create five S3 buckets using a set of strings to define their names.
First, we define a local variable with a set of the desired bucket names:
main.tf
Next, we use the for_each
in the S3 bucket resource block to create a bucket for each name in the set:
for_each
iterates over the local.bucket_names
set, and each. value represents the current bucket name being processed. The bucket attribute is set to each. value, which creates five S3 buckets with the names specified in the set.
With the configuration defined, run terraform init
and terraform apply
:
Integration with Terrateam
Terrateam is Terraform GitOps CI/CD. It automates Terraform operations by responding to GitHub events, making infrastructure management as seamless as code commits, pull request comments, and merges.
Key Features
Infrastructure as Code (IaC): Terrateam facilitates the use of Terraform, an IaC tool, allowing teams to define and provision infrastructure using simple, declarative configuration files.
Automated Terraform Workflows: Terrateam automates the execution of Terraform plans and applies operations in response to GitHub events, ensuring consistent infrastructure updates.
Full Example
To set up Terrateam in your GitHub repository and ensure it works seamlessly with your Terraform configurations, including main.tf
for resource definitions, provider.tf
for provider configurations, and variables.tf
for input variables, you must carefully create and include three critical files:
- config.yml
- terrateam.yml
- trustpolicy.json
The config.yml
provides the essential configuration needed to run Terraform in the pipeline. It allows you to define how Terrateam interacts with your Terraform configurations and GitHub repository
The terrateam.yml
file is a GitHub Actions workflow file that must be stored in your Terraform repository’s .github/workflows
directory. This file specifies the GitHub Action Terrateam will run when changes are made to your repository, such as running a terraform plan and terraform apply.
The trustpolicy.json
file is necessary for setting up AWS Authentication and Authorization with Terrateam. It defines the trust relationship policy that allows Terrateam to assume an AWS IAM role on your behalf, facilitating secure and seamless interaction with AWS resources.
For the complete code, visit here.
The first thing you need to do is update your infrastructure by modifying the Terraform files in your repository. This could involve changing resource configurations in main.tf
, adjusting provider settings in provider.tf
, or updating variable values in variables.tf
.
Once your changes are ready, create a pull request in GitHub. This PR should include the modifications in your Terraform configurations. Opening a PR triggers Terrateam to run a Terraform plan operation, which shows the potential effects of merging these changes without applying them.
In this example we’ll create a simple S3 bucket.
Understanding Terrateam
Terrateam Plan
You can automate the planning and application of resource changes like S3 buckets. For instance, if your Terraform configuration includes an S3 bucket, Terrateam can help manage the lifecycle of this resource through pull requests, applying changes only after thorough review and approval, ensuring that your S3 bucket configurations are always up to date and correctly provisioned.
Terrateam Pre Hooks
Pre hooks for Terraform plan operations let you run specific commands or scripts before executing the Terraform plan. This can be useful for setting up the environment, such as configuring variables or downloading necessary dependencies. It ensures that the Terraform plan operation has everything it needs to run successfully and can accurately reflect the changes that will be applied to your infrastructure.
Terrateam Apply
Terrateam can automatically run a Terraform apply operation when a pull request is merged. This applies the changes in the pull request to your infrastructure, ensuring that your infrastructure is always in sync with your repository’s state. This ensures that your main branch always reflects the current state of your infrastructure.
Terrateam Post Hooks
Post hooks in Terrateam allow you to execute custom commands or scripts after Terraform operations. For example, after a Terraform apply operation, you might want to run a script that clears the cache or restarts services affected by the infrastructure changes. This ensures that any necessary cleanup or follow-up actions are automatically taken care of, maintaining your infrastructure’s health and performance.
After we comment terrateam apply
in the pull request, our bucket is created via Terrateam.
Frequently Asked Questions
1. What is a variable set in Terraform?
A variable set in Terraform is a collection of variables that can be applied to multiple workspaces or configurations. It allows you to reuse the same set of variables across different Terraform projects or modules, ensuring consistency and simplifying the management of common variables. For example, in Terraform, a variable set for deploying an AWS S3 bucket across multiple environments might include variables like bucket_prefix and region, allowing for consistent bucket naming and location settings across development, staging, and production workspaces.
2. What does ${}
do in Terraform?
In Terraform, the ${}
syntax is used for interpolation, which allows you to insert the value of a variable or an expression into a string. For example, consider the following code:
This uses interpolation to create a tag for the EBS snapshot that includes the instance type and the current date, providing a clear and informative identifier for the backup. This tells Terraform to replace the placeholder with the variable’s actual value when executing the configuration.
3. What are variable definition files in Terraform, and when should I use them?
Variable definition files in Terraform are variables.tf or have the file extension .tfvars or .tfvars.json and are used to define the values of input variables. These files can be loaded automatically by Terraform if they are named terraform.tfvars or *.auto.tfvars, or they can be specified on the command line using the -var-file flag. They are particularly useful for setting different sets of values for different environments, like development, staging, and production
4. How do I set default values for Terraform variables?
Using the default keyword, default values for Terraform variables can be set within the variable definition. If an input variable is declared without a default value, Terraform will prompt the user for a value when applying the configuration, unless the value is provided through a .tfvars file or directly on the command line.
Conclusion
To wrap up, Terraform variables, in conjunction with tools like Terrateam, elevate cloud infrastructure management to new heights. By enabling dynamic, secure, and efficient resource configuration, they embody the essence of modern infrastructure as code (IaC) practices. From facilitating seamless authentication with environment variables to offering granular control through custom validation and sensitive data handling, Terraform variables ensure that your infrastructure is manageable and adaptable to the evolving needs of cloud-native development.