Terraform

How to use Terraform locals

Hello. In this tutorial, we will understand Terraform locals.

1. Introduction

Terraform is a tool for building, changing, and versioning the infrastructure safely and efficiently. It is used to manage the infrastructure of the popular cloud service providers and custom in-house solutions. It helps manage both low-level (Compute, Storage, Networking, etc.) and high-level components (such as SaaS, DNS, etc.) Terraform deployment automation is divided into different sections i.e. –

  • IaaC – IaaC is popularly known as the Infrastructure as a Code wherein the infrastructure is described using a high-level configuration syntax. This allows a blueprint of the infrastructure which can be deployed, versioned, and shared for re-use
  • Execution Plans – Terraform has a planning step where it generates an execution plan. The execution plan tells the administrator what Terraform will do once applied and helps to avoid any surprises when it creates the infrastructure
  • Resource Graph – Terraform builds a graph of all the resources and parallelizes the creation and modification of non-dependent resources. This offers insights into learning the dependencies in their infrastructure
  • Change Automation – Terraform allows to apply of complex changesets to the infrastructure with minimal human intervention

1.1 Configuration language

Terraform has its configuration language designed to meet the infrastructure automation requirements. The main purpose of this language is to declare resources and a group of resources (gathered into a module) represents a larger unit of configuration. Language syntax consists of a few elements i.e. – Blocks, Arguments, and Expressions.

  • Blocks – Containers for other contents and represents the object configuration
  • Arguments – Assign a value to the name and appear within the blocks
  • Expressions – Represents a single value, referenced value, or combination of other values

1.2 Steps

To create the infrastructure via the Terraform scripts following commands need to be executed.

  • terraform init – Initializing the new or existing terraform configuration
  • terraform plan – Generate the execution plan from the resources specified in the file
  • terraform apply – Create the infrastructure from the resources specified in the file
  • terraform destroy – Destroy the created infrastructure

1.3 Terraform locals

The locals in Terraform assign a name to an expression that can be used multiple times within a module. The values are defined in the locals blocks as shown in below syntax –

locals {
  some_key = "some_value"
}

2. Practice

Let us dive into some practice stuff from here. You’re free to choose the IDE of your choice. I am using Visual Studio Code as my preferred IDE for the development with the HashiCorp Terraform extension installed. The extension offers syntax highlighting and other editing features for Terraform files using the Terraform language server.

2.1 Pre-requisite

To proceed we will be needing an AWS CLI user having the right set of permissions required for creating the infrastructure. I am using an existing user and attached the EC2 full access policy attached to this user so that the IAM user can successfully create the required infrastructure. The access and secret key generated for the user will be used in the project’s root variables.tf file.

2.2 Creating an EC2 instance and using the locals

2.2.1 Variable file

The file contains the declarations required to create the EC2 instance such as amazon machine image id, instance type, zone id, etc, and AWS login details for the provider block. Add the below code to the file.

variables.tf

# ec2 variables
variable "ami_id" {
  default = "free_tier_ami_id" # remember to check for free-tier ami id before runnning the script to avoid unwanted money
}
variable "instance_type" {
  default = "t2.micro" # creating instance under free tier
}
variable "zone_id" {
  default = "ap-south-1a"
}
variable "key_pair" {
  default = "ec2_keypair_filename"
}
variable "subnet_id" {
  default = "subnet_id"
}
variable "vpcid" {
  default = "vpc_id"
}
variable "instance_count" {
  default = 1
}
# volume variables
variable "ebs_volume_name" {
  default = "/dev/xvda"
}
variable "ebs_volume_size" {
  default = 8 # free tier configuration
}
variable "ebs_volume_type" {
  default = "gp2"
}
# iam variables
variable "cli_usr" {
  default = "your_aws_cli_usr_access_key"
}
variable "cli_usr_key" {
  default = "your_aws_cli_usr_secret_key"
}
# aws region
variable "region" {
  default = "ap-south-1"
}

2.2.2 Implementation file

Add the following code to the main file responsible to set up the implementation. The file will refer to the local environment variables while setting tags for the resource and specifying the CIDR blocks for the security group,

main.tf

provider "aws" {
  region     = var.region
  access_key = var.cli_usr
  secret_key = var.cli_usr_key
}

# creating local variables
locals {
  environment = "development"
  cidr_block  = "0.0.0.0/0"
}

# security group resource
resource "aws_security_group" "ec2-sg" {
  vpc_id = var.vpcid
  ingress = [
    {
      description      = "ssh"
      from_port        = 22
      to_port          = 22
      protocol         = "tcp"
      cidr_blocks      = ["${local.cidr_block}"]
      ipv6_cidr_blocks = null
      prefix_list_ids  = null
      security_groups  = null
      self             = null
    }
  ]
  egress = [
    {
      description      = "all-open"
      from_port        = 0
      to_port          = 0
      protocol         = "-1"
      cidr_blocks      = ["${local.cidr_block}"]
      ipv6_cidr_blocks = null
      prefix_list_ids  = null
      security_groups  = null
      self             = null
    }
  ]
  tags = {
    "label" = "${local.environment}"
  }
}

# ec2 resource
resource "aws_instance" "ec2_example" {
  ami               = var.ami_id
  availability_zone = var.zone_id
  instance_type     = var.instance_type
  key_name          = var.key_pair
  count             = var.instance_count
  security_groups   = ["${aws_security_group.ec2-sg.id}"]
  subnet_id         = var.subnet_id
  ebs_block_device {
    device_name           = var.ebs_volume_name
    volume_size           = var.ebs_volume_size
    volume_type           = var.ebs_volume_type
    delete_on_termination = true
  }
  tags = {
    "label" = "${local.environment}"
  }
}

3. Code Run

Navigate to the project directory containing the above scripts and open the terminal. Execute the below commands in the respective order within the directory.

Commands

-- step1: initializing the new or existing terraform configuration --
terraform init

-- step2: generating the execution plan --
terraform plan

-- step3: building the infrastructure --
-- auto-approve flag skips interactive approval of the plan before applying
terraform apply --auto-approve

-- step4: destroying the infrastructure --
-- auto-approve flag skips interactive approval of the plan before applying
terraform destroy --auto-approve

4. Demo

Once the terraform script is successfully executed head over the AWS console to confirm that the EC2 instance is successfully created on the EC2 dashboard.

Terraform locals - aws ec2
Fig. 1: AWS EC2 instance created via Terraform

That is all for this tutorial and I hope the article served you with whatever you were looking for. Happy Learning and do not forget to share!

5. Summary

In this tutorial, we learned an introduction to Terraform, Locals, and EC2 instances created in the AWS portal. You can download the source code from the Downloads section.

6. Download the Project

This was a tutorial on learning and implementing Terraform locals.

Download
You can download the full source code of this example here: How to use Terraform locals

Yatin

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button