Terraform Tutorials: Local Values using Local Block

What is local value in terraform?

In Terraform, a locals block is used to define local variables within a module, allowing you to create reusable expressions and reduce duplication in your code.

Remember

  • within a module,

Local values can be used to simplify complex expressions or to make your code more readable by giving a name to a value that is used multiple times within a module. Additionally, local values can be used to reduce the amount of redundant code in your module by allowing you to define common values in one place and use them throughout your code.

These are variables that are local to a module. They are defined, assigned, and used in the same module, and defined in the “locals” block. Below is an example snippet on a local block:

Local variables can be declared once and used any number of times in the module. These can be accessed as objects by using the format of “local.Variable_Name”.

Unlike variables found in programming languages, Terraform’s locals don’t change values during or between Terraform runs such as plan, apply, or destroy. You can use locals to give a name to the result of any Terraform expression, and re-use that name throughout your configuration. Unlike input variables, locals are not set directly by users of your configuration.

Set of related local values can be declared together in a single locals block. The expressions assigned to local value names can either be simple constants or can be more complex expressions that transform or combine values from elsewhere in the module.

Example


locals {
  service_name = "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
  owner        = "Community Team"
}


resource "github_repository" "example" {
  name        = local.service_name
  description = "My awesome codebase"

  visibility = "public"
}

Comparing modules to functions in a traditional programming language:

  • Input variables are analogous to function arguments and
  • Outputs values are analogous to function return values, then
  • local values are comparable to a function’s local temporary symbols.

When To Use Local Values?

  • Local values can be helpful to avoid repeating the same values or expressions multiple times in a configuration, but if overused they can also make a configuration hard to read by future maintainers by hiding the actual values used.
  • Use local values only in moderation, in situations where a single value or result is used in many places and that value is likely to be changed in future. The ability to easily change the value in a central place is the key advantage of local values.
  • Each locals block can have as many locals as needed, and there can be any number of locals blocks within a module. The names given for the items in the local block must be unique throughout a module. The given value can be any expression that is valid within the current module.
  • The expression of a local value can refer to other locals, but as usual reference cycles are not allowed. That is, a local cannot refer to itself or to a variable that refers (directly or indirectly) back to it.

Example 1 Program


# This is a DRAFT and not yet implemented; final syntax/behavior may differ

locals {
  config = {
    region = "${var.region}"
    # ...and any other settings you want to make available to modules...
  }
}

module "example" {
  source = "./example"

  # pass the whole config object in a single variable
  config = "${local.config}"
}

Example 2 –


Example 2 - 

locals {
  service_name = "forum"
  owner        = "Community Team"
}

locals {
  # Ids for multiple sets of EC2 instances, merged together
  instance_ids = concat(aws_instance.blue.*.id, aws_instance.green.*.id)
}

locals {
  # Common tags to be assigned to all resources
  common_tags = {
    Service = local.service_name
    Owner   = local.owner
  }
}

resource "aws_instance" "example" {
  # ...

  tags = local.common_tags
}

Example 3 – Terraform workspaces and locals for environment separation


provider "aws" {
  region= "us-east-1"
}
resouce "aws_instance" "my_service" {
  ami="ami-7b4d7900"
  instance_type="t2.micro"
}

$ terraform workspace new production

provider "aws" {
  region= "us-east-1"
}
locals {
  env="${terraform.workspace}"
  counts = {
    "default"=1
    "production"=3
  }
  instances = {
    "default"="t2.micro"
    "production"="t4.large"
  }
  instance_type="${lookup(local.instances,env)}"
  count="${lookup(local.counts,local.env)}"
}
resource "aws_instance" "my_service" {
  ami="ami-7b4d7900"
  instance_type="${local.instance_type}"
  count="${local.count}"
}

Example 4 –

##----------------------
##  Terraform: Local  ##
##----------------------
## Create a directory and get inside it
mkdir terraform && cd terraform

## Create resources
vi main.tf
------------------
#declare variable
variable "name" {
default = "myapp"
}
#aws provider
provider "aws" {
access_key = "<your_access_key>"
secret_key = "<your_secret_key>"
region = "ap-south-1"
}
#get region details
data "aws_region" "myregion" {}
#get availability zone details
data "aws_availability_zones" "myavailabilityzones" {}
#get account details
data "aws_caller_identity" "myidentity" {}

#declare local
locals {
tag_prefix = "${var.name}_${data.aws_caller_identity.myidentity.account_id}_${data.aws_region.myregion.name}"
}

#create vpc
resource "aws_vpc" "myvpc" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags {
Name = "${local.tag_prefix}_vpc" #local block called
}
}
#create subnet
resource "aws_subnet" "myvpc_subnet" {
vpc_id = "${aws_vpc.myvpc.id}"
cidr_block = "10.0.0.0/24"
availability_zone = "${data.aws_availability_zones.myavailabilityzones.names[0]}"
tags {
   Name = "${local.tag_prefix}_subnet" #local block called
  }
}
------------------

## Format code
terraform fmt

## Initialize terraform
terraform init

## Create the resource
terraform apply

## Show state
terraform show

## Cleanup
## Destory resources
terraform destory

## Remove terraform directory
cd .. && rm -rf terraform


Rajesh Kumar
Follow me