A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://developer.hashicorp.com/terraform/tutorials/configuration-language/locals below:

Simplify Terraform configuration with locals | Terraform

Terraform local values (or "locals") assign a name to an expression or value. Using locals simplifies your Terraform configuration – since you can reference the local multiple times, you reduce duplication in your code. Locals can also help you write more readable configuration by using meaningful names rather than hard-coding values.

Unlike variables found in programming languages, Terraform's locals do not 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.

In this tutorial, you will use Terraform to deploy a web application on AWS. The supporting infrastructure includes a VPC, load balancer, and EC2 instances. You will then use local values to reduce repetition in the configuration, and then combine local values with input variables to require a minimal set of resource tags while still allowing for user customization.

You can complete this tutorial using the same workflow with either Terraform Community Edition or HCP Terraform. HCP Terraform is a platform that you can use to manage and execute your Terraform projects. It includes features like remote state and execution, structured plan output, workspace resource summaries, and more.

Select the HCP Terraform tab to complete this tutorial using HCP Terraform.

Note

Some of the infrastructure in this tutorial may not qualify for the AWS free tier. Destroy the infrastructure at the end of the guide to avoid unnecessary charges. We are not responsible for any charges that you incur.

Clone the example repository for this tutorial. The configuration in this repository defines a web application, VPC, load balancer, and EC2 instances.

$ git clone https://github.com/hashicorp-education/learn-terraform-locals

Change to the repository directory.

$ cd learn-terraform-locals

Initialize this configuration.

$ terraform init
Initializing the backend...
##...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Open your terraform.tf file and uncomment the cloud block. Replace the organization name with your own HCP Terraform organization.

terraform.tf

terraform {
  cloud {
    organization = "organization-name"
    workspaces {
      name = "learn-terraform-locals"
    }
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.4.0"
    }
  }

  required_version = ">= 1.1"
}

Initialize your configuration. Terraform will automatically create the learn-terraform-locals workspace in your HCP Terraform organization.

$ terraform init
Initializing HCP Terraform...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Installing hashicorp/aws v4.4.0...
- Installed hashicorp/aws v4.4.0 (signed by HashiCorp)
HCP Terraform has been successfully initialized!
You may now begin working with HCP Terraform. Try running "terraform plan" to
see any changes that are required for your infrastructure.
If you ever set or change modules or Terraform Settings, run "terraform init"
again to reinitialize your working directory.

Now apply the configuration. Respond to the confirmation prompt with a yes to create the example infrastructure.

$ terraform apply

## ...

Apply complete! Resources: 40 added, 0 changed, 0 destroyed.

Outputs:

public_dns_name = "lb-GHB-my-project-dev-816845261.us-east-2.elb.amazonaws.com"

Tip

This tutorial shows the output for Terraform commands run with the Terraform CLI. If you are following the HCP Terraform workflow, the output may differ slightly but the results will be the same.

If you use HCP Terraform to provision your resources, your workspace now displays the list of all of the resources it manages.

In the configuration's main.tf file, several resource names consist of interpolations of the resource type and the project and environment values from the resource_tags variable. Reduce duplication and simplify the configuration by setting the shared part of each name as a local value to re-use across your configuration.

First, define the local name_suffix by pasting the following snippet at the top of main.tf.

main.tf

locals {
  name_suffix = "${var.resource_tags["project"]}-${var.resource_tags["environment"]}"
}

As in any Terraform configuration, the order of your resource definitions and values does not affect how Terraform interprets them. To make your configuration more readable, consider putting local definitions near the top of your files.

Now, update the name attributes in the configuration to use this new local value.

main.tf

 module "vpc" {
   source  = "terraform-aws-modules/vpc/aws"
   version = "2.66.0"

   name = "vpc-${local.name_suffix}"
   ## ...
 }

 module "app_security_group" {
   source  = "terraform-aws-modules/security-group/aws//modules/web"
   version = "3.17.0"

   name        = "web-sg-${local.name_suffix}"
   ## ...
 }

 module "lb_security_group" {
   source  = "terraform-aws-modules/security-group/aws//modules/web"
   version = "3.17.0"

   name        = "lb-sg-${local.name_suffix}"
   ## ...
 }

 module "elb_http" {
   source  = "terraform-aws-modules/elb/aws"
   version = "2.4.0"

   # Ensure load balancer name is unique
   name = "lb-${random_string.lb_id.result}-${local.name_suffix}"
   ## ...
 }

Note that the load balancer name includes a random string to ensure that it is unique, which is a requirement for AWS load balancer names.

Apply the configuration to verify that the names' values have not changed.

$ terraform apply
random_string.lb_id: Refreshing state... [id=yeH]
module.vpc.aws_vpc.this[0]: Refreshing state... [id=vpc-02e45747200845db6]
module.vpc.aws_eip.nat[0]: Refreshing state... [id=eipalloc-09ebe519c3eec2991]

## ...

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

public_dns_name = "lb-yeH-my-project-dev-1748354490.us-east-2.elb.amazonaws.com"

Unlike variable values, local values can use dynamic expressions and resource arguments. The resource_tags map in variables.tf defines the tags for the local name_suffix as defaults. A user could override the default value for this map and omit the project_name and environment tags.

Many projects require that all resources are tagged in a certain way to track them. To enforce this requirement, use a local value in combination with variables so the tags assigned to resources include at least the project name and environment.

Tip

This tutorial uses local values to manage resource tags for educational purposes. Use AWS provider-level default tags to set global tags on your AWS resources.

Add the following new variable definitions to variables.tf.

variables.tf

variable "project_name" {
  description = "Name of the project."
  type        = string
  default     = "my-project"
}

variable "environment" {
  description = "Name of the environment."
  type        = string
  default     = "dev"
}

Next, change the default value of the resource_tags variable to an empty map.

variables.tf

 variable "resource_tags" {
   description = "Tags to set for all resources"
   type        = map(string)
   default     = { }
 }

Add a new locals block to main.tf to create a map combining both required tags and user defined tags.

main.tf

locals {
  required_tags = {
    project     = var.project_name,
    environment = var.environment
  }
  tags = merge(var.resource_tags, local.required_tags)
}

All of your configuration's local values can be defined in a single locals block, or you can use multiple blocks.

Update the definition of the name_suffix local to use the new variables for project_name and environment.

main.tf

locals {
  name_suffix = "${var.project_name}-${var.environment}"
}

Then, update the five references to tags in main.tf to use the new local value.

main.tf

  tags = local.tags
## ... replace all five occurrences of `tags = var.resource_tags`

Finally, add an output named tags to your outputs.tf file. This output will display the tags you used in this configuration. Based on your local value, the tags are a combination of var.resource_tags and local.required_tags.

outputs.tf

output "tags" {
  value = local.tags
}

Now, apply these changes to confirm that the tags for each resource to a combination of the required_tags local value and the resource_tags variable. Respond to the confirmation prompt with yes. Once again, because none of the values of changed, Terraform will show no changes to apply.

$ terraform apply
random_string.lb_id: Refreshing state... [id=yeH]
module.vpc.aws_vpc.this[0]: Refreshing state... [id=vpc-02e45747200845db6]
module.vpc.aws_eip.nat[1]: Refreshing state... [id=eipalloc-011888e01ac7b377a]

## ...

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

public_dns_name = "lb-GHB-my-project-dev-816845261.us-east-2.elb.amazonaws.com"
tags = {
  "environment" = "dev"
  "project" = "my-project"
}

Next, run another apply, this time changing the environment from dev to prod. Since this updates the local value with the tags map and the resource name suffix, Terraform will have to recreate some of your resources. Respond to the confirmation prompt with yes.

$ terraform apply -var "environment=prod"
random_string.lb_id: Refreshing state... [id=yeH]
module.vpc.aws_vpc.this[0]: Refreshing state... [id=vpc-02e45747200845db6]
module.vpc.aws_eip.nat[1]: Refreshing state... [id=eipalloc-011888e01ac7b377a]

## ...

Plan: 17 to add, 15 to change, 17 to destroy.

Changes to Outputs:
  ~ public_dns_name = "lb-GHB-my-project-dev-816845261.us-east-2.elb.amazonaws.com" -> (known after apply)
  ~ tags            = {
      ~ environment = "dev" -> "prod"
        # (1 unchanged element hidden)
    }

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

  ## ...

module.app_security_group.module.sg.aws_security_group.this_name_prefix[0]: Destruction complete after 1s
module.lb_security_group.module.sg.aws_security_group.this_name_prefix[0]: Destruction complete after 2s

Apply complete! Resources: 17 added, 15 changed, 17 destroyed.

Outputs:

public_dns_name = "lb-GHB-my-project-prod-1689308961.us-east-2.elb.amazonaws.com"
tags = {
  "environment" = "prod"
  "project" = "my-project"
}

Before moving on, destroy the infrastructure you created by running the terraform destroy command. Respond to the confirmation prompt with yes.

$ terraform destroy

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:
##...

Plan: 0 to add, 0 to change, 42 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

##...

Destroy complete! Resources: 42 destroyed.

If you used HCP Terraform for this tutorial, after destroying your resources, delete the learn-terraform-locals workspace from your HCP Terraform organization.

In this tutorial, you defined and used Terraform local values to reduce duplication and improve configuration readability. You also combined user-defined variables with locals to improve the consistency of your infrastructure tags.

Review the following resources for more guidance on refining your Terraform configuration:


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4