Learn How to Use the Magic of Terraform Locals — Step-by-Step Guide
If you’re a DevOps engineer or cloud infrastructure professional, you’ve probably heard of Terraform. This powerful tool allows you to manage and automate your cloud resources with a simple configuration language. But have you ever struggled with organizing and referencing your Terraform variables and resources? Enter Terraform locals.
Locals are a way to define and reference variables and resources within your Terraform code. They can help you improve the readability and organization of your code, making it easier for you and your team to understand and maintain. But how do you use them effectively? In this article, we’ll dive into the basics of Terraform locals and explore some practical examples of how to use them in your infrastructure as code. Whether you’re new to Terraform or a seasoned pro, this article has something for you.
So, what exactly are Terraform locals? Simply put, they are variables and resources that are defined and used within a single Terraform configuration file. They are a way to group related resources and variables together, making your code easier to read and maintain.
To define a local, you use the local block in your Terraform code. For example:
locals {
variable1 = "value1"
variable2 = "value2"
}You can then reference these locals within your code using the ${local.variable_name} syntax. For example:
resource "aws_instance" "web_server" {
ami = "${local.ami_id}"
instance_type = "${local.instance_type}"
count = "${local.server_count}"
}One of the main benefits of using locals is that they can help you avoid repeating the same values multiple times within your code. This can be especially helpful if you have a large number of resources that share common properties. Instead of defining these values separately for each resource, you can define them as locals and reference them as needed. This not only makes your code more concise, but it also makes it easier to update values in the future.
Another benefit of locals is that they can improve the readability of your code. By grouping related variables and resources together, you can make it easier for yourself and others to understand the purpose and context of each component. This can be especially helpful for team members who are new to your project, or for when you revisit your code after a long period of time.
So now that you understand the basics of Terraform locals, let's take a look at some practical examples of how you can use them in your infrastructure as code.
One common use case for Terraform locals is to define and reference common values across multiple resources. For example, let’s say you are building an AWS infrastructure that includes a VPC, subnets, and security groups. You might want to use locals to define values such as the VPC ID, subnet CIDR blocks, and security group rules. Here’s how this could look in your Terraform code:
locals {
vpc_id = "${aws_vpc.main.id}"
subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
sg_rules = [
{
protocol = "tcp"
from_port = 80
to_port = 80
cidr_blocks = ["0.0.0.0/0"]
},
{
protocol = "tcp"
from_port = 22
to_port = 22
cidr_blocks = ["0.0.0.0/0"]
}
]
}
resource "aws_subnet" "private" {
count = "${length(local.subnet_cidrs)}"
vpc_id = "${local.vpc_id}"
cidr_block = "${local.subnet_cidrs[count.index]}"
availability_zone = "${data.aws_availability_zones.all.names[count.index]}"
tags = {
Name = "private-${count.index + 1}"
}
}
resource "aws_security_group" "web" {
name = "web-sg"
vpc_id = "${local.vpc_id}"
ingress = "${local.sg_rules}"
}In this example, we use locals to define the VPC ID, subnet CIDR blocks, and security group rules. We then reference these locals in our resource blocks to apply the values to the appropriate resources. This helps to keep our code organized and easy to understand.
As you become more comfortable with Terraform locals, you may find that they are useful for defining and referencing different environments in your infrastructure. For example, you might have separate environments for development, staging, and production, each with its own set of resources and configurations.
To manage these environments, you can use locals to define and reference environment-specific values. Here’s an example of how this might look in your Terraform code:
locals {
environment = "${var.environment}"
development {
vpc_id = "dev_vpc_id"
subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
}
staging {
vpc_id = "staging_vpc_id"
subnet_cidrs = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"]
}
production {
vpc_id = "production_vpc_id"
subnet_cidrs = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"]
}
}
resource "aws_subnet" "private" {
count = "${length(local.environment.subnet_cidrs)}"
vpc_id = "${local.environment.vpc_id}"
cidr_block = "${local.environment.subnet_cidrs[count.index]}"
availability_zone = "${data.aws_availability_zones.all.names[count.index]}"
tags = {
Name = "${local.environment}-${count.index + 1}"
}
}In this example, we use a top-level local called environment to store the current environment value (which is passed in as a variable). We then define separate locals for each environment (development, staging, and production), each with its own set of values for the VPC ID and subnet CIDR blocks.
To reference these values in our resource blocks, we use the ${local.environment.value} syntax. For example, to reference the VPC ID for the current environment, we use ${local.environment.vpc_id}. This allows us to easily apply the appropriate values for each environment, without having to manually update our resource blocks for each environment.
As you can see, Terraform locals are a powerful tool that can help you improve the organization and readability of your infrastructure as code. Whether you are defining common values across multiple resources, or managing different environments, locals can help you write cleaner and more maintainable code.
While Terraform locals are a useful tool for managing and organizing your infrastructure as code, it’s important to understand their limitations as well. Here are a few things to keep in mind when using locals:
- Locals are only available within the configuration file in which they are defined. This means that you cannot reference a local defined in one file from another file. If you need to share values across multiple files, you will need to use Terraform variables or modules instead.
- Locals cannot be used as outputs. If you need to return a value from your Terraform configuration (such as the ID of a resource), you will need to use an output instead.
- Locals cannot reference other locals. If you need to use the value of one local in the definition of another local, you will need to define the first local as a variable and pass it in as an argument.
- Locals can’t reference Data or Resource sources, and it will usually lead to Cycling error
While these limitations may seem restrictive, they are in place to help ensure that your Terraform code is easy to understand and maintain. By understanding the capabilities and limitations of locals, you can use them effectively in your infrastructure as code.
I hope this article has helped you understand the basics of Terraform locals and how they can be used to improve the organization and readability of your infrastructure as code. Whether you are new to Terraform or an experienced user, locals are a valuable tool to have in your toolkit.
If you’re interested in learning more about Terraform and other cloud infrastructure tools, be sure to subscribe to my channel. I share tips and tricks on a variety of topics, including Terraform, AWS, Azure, GCP, and more. Stay up to date with the latest trends and best practices in cloud infrastructure!
Thanks for reading!
And if you’re feeling particularly generous, you could buy me a coffee at www.buymeacoffee.com/kingmichael. Your support would greatly help in keeping me motivated and writing articles that you love.




