How to use Terraform outputs and inputs
Get a quick lesson in what input, output, and local variables are and how to use them in Terraform, HashiCorp's open-source IaC software tool.
Jun 08, 2023 • 9 Minute Read
Terraform is a very powerful and efficient tool to deploy and manage infrastructure in your environment. With so many providers and modules, there isn’t much Terraform can’t do.
The big draw to Terraform is the way you can create resources in multiple environments using the same configuration or as your infrastructure grows and becomes more complex, the need to use variables grows. The way you can accomplish this is with input and output variables.
In this post, we are going to explore what the variables are and how to use them in your Terraform configuration.
What are Terraform Output Variables?
Think of output variables as return value of a Terraform module. There are several uses for output variables. Here are some examples:
- We can use outputs to expose a subset of a child module’s resource attributes to a parent module.
- We can use outputs to print values from a root module in the CLI output after running
terraform apply
. - If you are using a remote state, other configurations can access the outputs of a root module, via the
terraform_remote_state
data source
These are just a few examples of why we would use output variables. To declare an output value, you must declare them in an output block as shown in the example below.
output "instance_ip_addr" {
value = aws_instance.server.private_ip
}
There are three optional arguments you can use when declaring output variables.
- Description - You can describe the purpose of each value using this argument.
output "instance_ip_addr" {
value = aws_instance.server.private_ip
description = "The private IP address of the main server instance."
}
- Sensitive - When using this option, Terraform will hide values mark as sensitive in the outputs of the
terraform plan
andterraform apply
command.
output "db_password" {
value = aws_db_instance.db.password
description = "The password for logging in to the database."
sensitive = true
}
- Depends_on - This option is useful when a parent module accesses output values exported by one of its child modules. The dependencies of that output value allow Terraform to correctly determine the dependencies between resources defined in other modules.
output "instance_ip_addr" {
value = aws_instance.server.private_ip
description = "The private IP address of the main server instance."
depends_on = [
# Security group rule must be created before this IP address could
# actually be used, otherwise the services will be unreachable.
aws_security_group_rule.local_access,
]
}
Output variables can be quite useful when building out your configuration. Especially when needing special instructions or login information for anyone deploying the infrastructure or resources I the infrastructure. Let’s wrap this up by talking a little bit about the third way to use variables.
How to use Local Variables
Local variables assign a name to an expression so it can be used multiple times from within a module without repeating it. If you are familiar with most programming languages, a local variable is like a function’s temporary local variable. Below is an example on how to declare a local variable.
locals {
# Common tags to be assigned to all resources
common_tags = {
Service = local.service_name
Owner = local.owner
}
}
You would then call the local variable by referencing the expression like so : tags = local.common_tags
in the resource block of the configuration. A local value can only be accessed in expressions within the module where it was declared.
So when do I use a local variable you might ask! Well, local variables can be helpful to avoid repeating the same values or expressions multiple times in a configuration. If they are overused though, they can also make a configuration very hard to read by future contributors to the configuration by hiding the actual values used. It is suggested to use them in moderation.
What are Terraform Input Variables?
So we have talked about output variables quite a bit, but now let’s talk about input variables and what they are used for.
Input variables are your primary way to apply parameters to your Terraform configuration. It allows aspects of your configuration to be customized without altering the Terraform module’s own source code and allowing modules to be shared between different configurations.
You can declare variables in the root module of your configuration. You can set those by using CLI options and environment variables. If you are familiar with most programming languages, Terraform modules are comparable to function definitions:
- Input variables are similar to function arguments.
- Output values are similar to function return values.
- Local values are similar to a function’s temporary local variables.
Need more Terraform tips? Check out our Ultimate Terraform Commands Cheatsheet.
How do we declare an Input Variable?
An input variable needs to be declared using a variable block
in the Terraform configuration. The following example is how a variable block
looks:
variable "image" {
type = string
}
variable "availability_zone_names" {
type = list(string)
default = ["us-east-1]
}
In this example, we have two variables being declared. The label after the variable designation is the name for that variable. This needs to be unique among all the rest of the variables being declared.
If you want to add another image variable, you would need to do something like image_0
and then image_1
and so and so on.
Next, you would define the type, which in the first example is the string
type constraint. The next variable is defining the availability zones. You can see here the type in list(string
and there is a default if not defined us-east-1
. What this does is if there is no value provided by a variable then it will use the default.
Here is a list of the optional Arguments and Type Constraints that can be used:
Arguments:
-
default
- Default value which then makes the variable optional. -
type
- Specifies what value types are accepted for the variable. -
description
- Specifies the input variable’s documentation. -
validation
- Defines validation rules, usually in addition to type constraints. -
sensitive
- This limits the Terraform UI output when the variable is used in the configuration.
Type Constraints
string
number
bool
Type Constructors that can be used with Type Constraints
list(<TYPE>)
set(<TYPE>)
map(<TYPE>)
object({<ATTR_NAME> = <TYPE>, … })
tuple([<TYPE>, …])
In the variable block, the type argument allows you to restrict the value accepted as the value of the variable. If you do not set a constraint, then the type argument will accept any value. Type constraints are optional, but they are encouraged. Type constraints can allow Terraform to return a useful error message when troubleshooting issues.
Using a variable
A variable's value can be accessed from within the terraform module block by using var.<variable_name>
. Below we have an example demonstrating this.
resource "aws_instance" "example" {
instance_type = "t2.micro"
ami = var.image_id
}
The variable's value can only be accessed in an expression within the modules where it was declared.
The many ways to assign variables in Terraform
We have gone over some of the basics about input variables. Now let’s take a look at a few examples of how we can declare our variables.
This example below is how you can declare variables from the command line.
$ terraform apply -var="image_id=ami-abc123"
$ terraform apply -var='image_id_list=["ami-abc123","ami-def456"]' -var="instance_type=t2.micro"
$ terraform apply -var='image_id_map={"us-east-1":"ami-abc123","us-east-2":"ami-def456"}'
Here you can see we are providing the variables to terraform apply
command by the -var
option to specify our variables. If we have more than a few variables, we can create a variables file with either the .tfvars
or .tfvars.json
file extension and then specifying that file on the command line like the below example.
$ terraform apply -var-file="testing.tfvars"
The variable definition files use the same syntax as the rest of the Terraform configuration files.
We can also use Environment variables to set variables in Terraform. You can simply do this by exporting your variable like the below example.
$ export TF_VAR_image_id=ami-abc123
There is an order to things!
There is a variable definition precedence you need to be aware of when declaring variables. Terraform loads variables in a specific order. The order is as follows:
- Environment variables
- The
terraform.tfvars
file (if present) - The
terraform.tfvars.json
file (if present) - Any
*.auto.tfvars
or*.auto.tfvars.json
files (if present) - Any
-var
and-var-file
options on the command line.
This will help when building out some larger configuration files or when trying to use one configuration to deploy infrastructure to multiple cloud environments.
So that was a quick lesson in what input, output, and local variables are and how to use them in Terraform. They are extremely useful when building your Terraform configurations and will help you when you start building more complex, I mean fun Terraform configurations. Have fun, my Terraform gurus, and let’s continue to build the future on Terraform block at a time!
WATCH: Kubernetes + Azure, the HashiCorp way
Ever thought about creating a standardized way to deploy your applications and how to do so securely? Using the HashiCorp stack on Azure is an excellent place to start! Watch this free on-demand webinar where HashiCorp's Taylor Dolezal goes over the potential of using Terraform, Vault, and Waypoint.
Looking to level up your Terraform skills? Check out our HashiCorp Certified Terraform Associate course.
Think of output variables as return value of a Terraform module. There are several uses for output variables. See examples here!
Local variables assign a name to an expression so it can be used multiple times from within a module without repeating it. If you are familiar with most programming languages, a local variable is like a function’s temporary local variable.
Input variables are your primary way to apply parameters to your Terraform configuration. It allows aspects of your configuration to be customized without altering the Terraform module’s own source code and allowing modules to be shared between different configurations.
You can do this providing the variables to terraform apply command by the -var option to specify our variables. If we have more than a few variables, we can create a variables file with either the .tfvars or .tfvars.json file extension and then specifying that file on the command line.
Get the skills needed for a better career.
Master modern tech skills, get certified, and level up your career. Check out our current free courses or get a 7-day free trial. Whether you’re starting out or a seasoned pro, you can advance your career in cloud with ACG.