Understanding Terraform Variables
1. Terraform Input Variables
Definition
Input variables allow you to customize your Terraform modules, passing different values during deployment without hardcoding them into the configurations. They act like parameters, making your code flexible for different environments.
Syntax
An input variable is defined using the variable
block. Here’s an example:
variable "instance_type" {
description = "Type of EC2 instance"
type = string
default = "t2.micro"
}
Assigning Input Variable Values
Default Value: As shown above, a default value is set within the variable definition.
Environment Variables: You can pass variable values using environment variables prefixed with
TF_VAR_
. For example:export TF_VAR_instance_type="t3.large"
Terraform CLI: Variables can be passed via the command line using the
-var
flag:terraform apply -var="instance_type=t3.medium"
Variable Files (
.tfvars
): Store variable values in.tfvars
files or auto-loadedterraform.tfvars
file:instance_type = "t3.micro"
Example
Consider a Terraform file that provisions an EC2 instance:
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = var.instance_type
}
In this case, the instance_type
can be passed dynamically during execution, making the module adaptable.
2. Terraform Output Variables
Definition
Output variables allow you to display information about the infrastructure after Terraform has run, such as an EC2 instance ID or an IP address. They help in sharing values between different Terraform configurations or passing data to external tools.
Syntax
Here’s a simple example of an output variable:
output "instance_ip" {
description = "Public IP address of the instance"
value = aws_instance.example.public_ip
}
When the terraform apply
is complete, the output will display the public IP address of the EC2 instance.
Sensitive Output
Output variables can also be marked as sensitive to hide values from the CLI output:
output "db_password" {
description = "Database password"
value = aws_db_instance.example.password
sensitive = true
}
When marked as sensitive, Terraform will not display the value in the CLI output, providing an extra layer of security.
3. Variable Precedence
Terraform provides multiple ways to pass input variables, and understanding how Terraform resolves them is critical to avoiding confusion. Variables are evaluated in the following order of precedence (highest to lowest):
Command-line flags (
-var
or-var-file
): Variables passed via command-line flags override all others.terraform apply -var="instance_type=t3.large"
Environment variables: Variables defined as environment variables take precedence over
.tfvars
files and defaults.export TF_VAR_instance_type="t3.medium"
Terraform
.tfvars
files: These are automatically loaded if namedterraform.tfvars
or*.auto.tfvars
. Other.tfvars
files can be passed using the-var-file
flag.terraform apply -var-file="production.tfvars"
Default value: If no value is provided through the above methods, Terraform will use the default value defined in the variable block.
Example
Let’s consider the following scenario:
You define a default value for
instance_type
ast2.micro
.You pass a different value using an environment variable:
t3.large
.You also pass another value using the CLI:
t3.medium
.
Here’s how Terraform resolves it:
- The value passed via CLI (
t3.medium
) will take precedence.
4. The sensitive
Meta-Argument
The sensitive argument ensures that the variable values do not get logged or exposed in the output. This is particularly useful for sensitive information such as passwords, access keys, or any other secrets.
Using Sensitive Input Variables
You can mark input variables as sensitive using the sensitive
attribute:
variable "db_password" {
description = "Password for the RDS instance"
type = string
sensitive = true
}
By marking the variable as sensitive
, Terraform will:
Not display the value during
terraform plan
orterraform apply
.Not store the value in the state file in plain text (though the state file itself can still be a sensitive asset, so ensure it is secured).
Example: Handling Sensitive Variables
variable "db_password" {
description = "Password for the database"
type = string
sensitive = true
}
resource "aws_db_instance" "example" {
allocated_storage = 10
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
name = "mydb"
username = "admin"
password = var.db_password # Sensitive variable
}
Sensitive Output Example
Output values marked as sensitive won’t display their actual content:
output "db_instance_password" {
value = aws_db_instance.example.password
sensitive = true
}
The output will only show:
Outputs:
db_instance_password = <sensitive>
5. Combining Input and Output Variables
Sometimes, you may want to combine input variables with outputs. For instance, you can create a resource using input variables and output some of its attributes:
variable "bucket_name" {
description = "Name of the S3 bucket"
type = string
}
resource "aws_s3_bucket" "example" {
bucket = var.bucket_name
}
output "bucket_id" {
value = aws_s3_bucket.example.id
}
In this case, the bucket_name
is passed as an input, and after provisioning, Terraform outputs the bucket_id
.
Conclusion
Terraform variables, both input and output, provide a great deal of flexibility and reusability to your infrastructure code. By understanding variable precedence, you can control which values Terraform uses during execution. Additionally, the sensitive
meta-argument is a powerful tool for securing sensitive information, ensuring it’s not displayed in outputs or logs.
Subscribe to my newsletter
Read articles from Rohit directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Rohit
Rohit
I'm a results-driven professional skilled in both DevOps and Web Development. Here's a snapshot of what I bring to the table: 💻 DevOps Expertise: AWS Certified Solutions Architect Associate: Proficient in deploying and managing applications in the cloud. Automation Enthusiast: Leveraging Python for task automation, enhancing development workflows. 🔧 Tools & Technologies: Ansible, Terraform, Docker, Prometheus, Kubernetes, Linux, Git, Github Actions, EC2, S3, VPC, R53 and other AWS services. 🌐 Web Development: Proficient in HTML, CSS, JavaScript, React, Redux-toolkit, Node.js, Express.js and Tailwind CSS. Specialized in building high-performance websites with Gatsby.js. Let's connect to discuss how my DevOps skills and frontend expertise can contribute to your projects or team. Open to collaboration and always eager to learn! Aside from my work, I've also contributed to open-source projects, like adding a feature for Focalboard Mattermost.