Saturday, May 3, 2025

Terraform locals

Terraform locals

Class 18th Terraform Locals May3rd(Devops)

In Terraform ,locals are used to define local values within module. These values help simplify configurations by assigning names to expressions, making them easier to reference throughout the configuration 

Why Use locals?

Improve readability :Instead of repeating complex expressions, you can define them once and use muliple.

Avoid repetition :Helps in maintaining the DRY(Don't repeat yours self) priciple

Enhance Maintainability :If a value need to updated, you only change it in once a place .

Step1:

[ec2-user@ip-172-31-17-136 ccit]$ cat cloudinfra.tf
provider "aws" {
region = "eu-west-1"
}
locals{
bucketname="ccitbucket242"
env="dev"
}
resource "aws_s3_bucket" "ccitbucket" {
bucket=local.bucketname
 tags = {
   Name = local.env
  }
}
resource "aws_vpc" "ccitvpc"{
 cidr_block ="10.0.0.0/16"
 tags = {
   Name = "${local.env}-VPC" # concate
   }
}

[ec2-user@ip-172-31-17-136 ccit]$ terraform apply -auto-approve

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

Step2:You see VPC dev created, this way we can use locals

                                                             Variable Precedence

  • Define the level priority for variables in terraform
  • Terraform will pick the variables in the following order:
  1. CLI (command prompt)
  2. dev.tfvars
  3. Environment variables
  4. variable.tf

Step1: Just simple script bucket creation
[ec2-user@ip-172-31-17-136 ccit]$ cat cloudinfra.tf
provider "aws" {
region = "eu-west-1"
}
resource "aws_s3_bucket" "ccitbucket" {
bucket=var.bucketname
}
variable "bucketname" {
 default ="ccitbucket3may-var"
}

Step2:We plan the variable through cli using command the script already had bucketname default name, if you pass value specifically though cli 

[ec2-user@ip-172-31-17-136 ccit]$ terraform apply -auto-approve -var="bucketname=ccitbucket3may-cli"

Plan: 1 to add, 0 to change, 1 to destroy.
aws_s3_bucket.ccitbucket: Destroying... [id=ccitbucket3may-var]
aws_s3_bucket.ccitbucket: Destruction complete after 1s
aws_s3_bucket.ccitbucket: Creating...
aws_s3_bucket.ccitbucket: Creation complete after 0s [id=ccitbucket3may-cli]
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.

Step3: As you observe ,it was not take default value as per variable precedence it takes cli name 

Step2: dev.tfvars which you pass value to cli command explicitly, it will take that one only
Step3:Environment variables,as see even you have set environment value also it took cli name only
[ec2-user@ip-172-31-17-136 ccit]$ export TF_VAR_bucketname=ccitbucket3may-envar
[ec2-user@ip-172-31-17-136 ccit]$ terraform apply -auto-approve -var="bucketname=ccitbucket3may-cli1"
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.

Step4: with out pass any value it will take environment variable value,use use globally for the variable
[ec2-user@ip-172-31-17-136 ccit]$ terraform apply -auto-approve
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.


unset TF_VAR_bucketname

                                                      Terraform Collections
Collections are just array concept key value pair ,for this have elements (for loops,set,list,map)
for_each: is used to loop over a map or  a set to create multiple resources dynamically ,se the the string

List in terraform 
A list in terraform is an ordered collection of elements where each item has a specific position(index).Duplicate are allowed 

Set in terraform
Set in terraform in an unordered collection of unique elements .Duplicates are not allowed 

List example foreach not support for_each, it will support for set or map

Step1: List using create buckets 
[ec2-user@ip-172-31-17-136 ccit]$ cat cloudinfra.tf
provider "aws" {
region = "eu-west-1"
}
resource "aws_s3_bucket" "ccitbucket" {
  count =length(var.my_list)
  bucket="ccit-${var.my_list[count.index]}"
}
variable "my_list" {
  type=list(string)
  default =["bucket3may-1","bucket3may-2","bucket3may-3"]
}
[ec2-user@ip-172-31-17-136 ccit]$ terraform apply -auto-approve
Plan: 3 to add, 0 to change, 0 to destroy.
aws_s3_bucket.ccitbucket[2]: Creating...
aws_s3_bucket.ccitbucket[0]: Creating...
aws_s3_bucket.ccitbucket[1]: Creating...
aws_s3_bucket.ccitbucket[0]: Creation complete after 1s [id=ccit-bucket3may-1]
aws_s3_bucket.ccitbucket[2]: Creation complete after 1s [id=ccit-bucket3may-3]
aws_s3_bucket.ccitbucket[1]: Creation complete after 1s [id=ccit-bucket3may-2]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
using list successfully create three buckets

Step2:if you give list duplicate value ,it will try create error out remain will created, if you over come this problem use set
[ec2-user@ip-172-31-17-136 ccit]$ terraform apply -auto-approve
  default =["bucket3may-1","bucket3may-2","bucket3may-3","bucket3may-3"]
 Error: creating S3 Bucket (ccit-bucket3may-3): operation error S3: CreateBucket, https response error StatusCode: 409, RequestID: BucketAlreadyOwnedByYou:
│   with aws_s3_bucket.ccitbucket[2],
│   on cloudinfra.tf line 5, in resource "aws_s3_bucket" "ccitbucket":
│    5: resource "aws_s3_bucket" "ccitbucket" {

SET

Step1: set need to use for_each

[ec2-user@ip-172-31-17-136 ccit]$ cat cloudinfra.tf
provider "aws" {
region = "eu-west-1"
}
resource "aws_s3_bucket" "ccitbucket" {
  for_each =var.my_list
  bucket= "ccit-${each.value}"
}
variable "my_list" {
  type=set(string)
  default =["bucket3may-1","bucket3may-2","bucket3may-3","bucket3may-3" ]
}
[ec2-user@ip-172-31-17-136 ccit]$ terraform apply -auto-approve
Plan: 3 to add, 0 to change, 0 to destroy.
aws_s3_bucket.ccitbucket["bucket3may-2"]: Creating...
aws_s3_bucket.ccitbucket["bucket3may-3"]: Creating...
aws_s3_bucket.ccitbucket["bucket3may-1"]: Creating...
aws_s3_bucket.ccitbucket["bucket3may-2"]: Creation complete after 1s [id=ccit-bucket3may-2]
aws_s3_bucket.ccitbucket["bucket3may-3"]: Creation complete after 1s [id=ccit-bucket3may-3]
aws_s3_bucket.ccitbucket["bucket3may-1"]: Creation complete after 1s [id=ccit-bucket3may-1]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
Created three buckets, with out any issue even duplicate because set will remove the duplicate
limitations

Tags
Tags :Main use of tags for all your resource metadata information about key-value like 
what is the which project,client who use like that information for undestanding 
Step1:
[ec2-user@ip-172-31-17-136 ccit]$ cat cloudinfra.tf
provider "aws" {
region = "eu-west-1"
}
resource "aws_s3_bucket" "ccitbucket" {
  bucket= "ccit-bucket3may-1"
  tags = {
  Name="CCITbucket"
  Env="dev"
  client="Zepto"}
}
[ec2-user@ip-172-31-17-136 ccit]$ terraform apply -auto-approve
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Step2:See like below we can give tags for the resources

Step3: Same way you can use variables also, see here drawback number lines repeated to over come this issue use map
[ec2-user@ip-172-31-17-136 ccit]$ cat cloudinfra.tf
provider "aws" {
region = "eu-west-1"
}
resource "aws_s3_bucket" "ccitbucket" {
  bucket= "ccit-bucket3may-1"
  tags = {
  Name =var.ccittagname
  Env =var.ccittagenv
  client=var.ccittagclient }
}
variable "ccittagname"{
   default = "CCITbucket"
}
variable "ccittagenv"{
default = "dev"
}
variable "ccittagclient"{
default = "zepto"
}
[ec2-user@ip-172-31-17-136 ccit]$ terraform apply -auto-approve
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Map
Used to pass both key and values to variables.
KEY-VALUE can also called as object or dictionary, it will save more line compared to above
[ec2-user@ip-172-31-17-136 ccit]$ cat cloudinfra.tf
provider "aws" {
region = "eu-west-1"
}
resource "aws_s3_bucket" "ccitbucket" {
  bucket= "ccit-bucket3may-1"
  tags = var.tags
}
variable "tags"{
  type = map(string)
  default= {
  Name ="CCITbucket"
  Env = "dev"
  client="zepto"
}
}
Created successfully bucket with tags 
[ec2-user@ip-172-31-17-136 ccit]$ terraform apply -auto-approve
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

 General info
 Practice terraform built-in-functions as far we used length(),upper()..
 Type of expression:variable expression, function expression, conditional expression, resource attribute
 
 Type of Block:
 Provider
 Resource
 Variables
 Output
 Locals
 Terraform 
Arguments: key value pair inside blocks ,which you have assigned variable values 
 ami="ami-04e7764922e1e3a57"
 instance_type="t2.micro"

 Terraform Advantage:
->Will support Multi cloud(Azure,aws,CGP,Kubernetes..etc)
->Modular & reusable code (which we use terraform module ,reusable complete project level, if you store you code .tf s3 bucket you can use any where in your code reusability)
->Declarative language(HCL Hashicorp  configuration language),easy to read and manage
->Support Infrastructure automation (Integrates with CI/CD pipelines (Jenkins,Github,Actions,..etc)
->Open-source & extensible( Free to use terraform cloud offering extra features,Can be extended with providers & plugin)
 Terraform Disavantage:
State file management issues
Learning HCL syntax 
Longer Execution time for large deployments(comparatively aws formation template ,aws templates has native)
Destroy command is dangers 

                           ---Thanks 



No comments:

Post a Comment