DEV Community

Aisalkyn Aidarova
Aisalkyn Aidarova

Posted on

Advanced Terraform Concepts

Step 1 — Create Project

Create a new project.

mkdir terraform-functions-lab
cd terraform-functions-lab
Enter fullscreen mode Exit fullscreen mode

Create files:

main.tf
variables.tf
outputs.tf
terraform.tfvars
Enter fullscreen mode Exit fullscreen mode

Step 2 — Terraform Settings Block

This tells Terraform which providers to use.

main.tf

terraform {

  required_version = ">= 1.5"

  required_providers {

    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }

    local = {
      source = "hashicorp/local"
      version = "~> 2.4"
    }

  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation

Settings block defines:

  • Terraform version
  • required providers
  • provider versions

This ensures consistent environments across teams.


Step 3 — Provider Configuration

Add AWS provider.

provider "aws" {
  region = var.aws_region
}
Enter fullscreen mode Exit fullscreen mode

Step 4 — Variables

variables.tf

variable "aws_region" {
  default = "us-east-2"
}

variable "instance_types" {

  type = map(string)

  default = {
    dev  = "t2.micro"
    prod = "t2.small"
  }

}

variable "ports" {

  type = list(number)

  default = [22,80,443]

}

variable "servers" {

  type = list(string)

  default = [
    "web",
    "api",
    "worker"
  ]

}
Enter fullscreen mode Exit fullscreen mode

Step 5 — Terraform Functions

We will now use these functions:

lookup()
length()
element()
format()
timestamp()
Enter fullscreen mode Exit fullscreen mode

Step 6 — Security Group with Dynamic Block

Dynamic blocks are useful when you want Terraform to generate multiple blocks automatically.

resource "aws_security_group" "web" {

  name = "terraform-dynamic-sg"

  dynamic "ingress" {

    for_each = var.ports

    content {

      from_port = ingress.value
      to_port   = ingress.value
      protocol  = "tcp"
      cidr_blocks = ["0.0.0.0/0"]

    }

  }

}
Enter fullscreen mode Exit fullscreen mode

What dynamic block does

Instead of writing:

ingress {22}
ingress {80}
ingress {443}
Enter fullscreen mode Exit fullscreen mode

Terraform generates them automatically.


Step 7 — Using count

Create multiple EC2 instances.

resource "aws_instance" "count_servers" {

  count = length(var.servers)

  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = lookup(var.instance_types,"dev")

  tags = {

    Name = format("count-server-%s", element(var.servers,count.index))

  }

}
Enter fullscreen mode Exit fullscreen mode

Functions used

length()

Counts number of elements.

length(var.servers)
Enter fullscreen mode Exit fullscreen mode

If servers list has 3 elements, Terraform creates 3 instances.


element()

Returns element from list.

element(var.servers,count.index)
Enter fullscreen mode Exit fullscreen mode

Example result:

web
api
worker
Enter fullscreen mode Exit fullscreen mode

format()

Formats strings.

format("count-server-%s",name)
Enter fullscreen mode Exit fullscreen mode

Output example:

count-server-web
count-server-api
count-server-worker
Enter fullscreen mode Exit fullscreen mode

lookup()

Gets value from map.

lookup(var.instance_types,"dev")
Enter fullscreen mode Exit fullscreen mode

Returns:

t2.micro
Enter fullscreen mode Exit fullscreen mode

Step 8 — Using for_each

Create instances using for_each.

resource "aws_instance" "foreach_servers" {

  for_each = toset(var.servers)

  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  tags = {

    Name = "foreach-${each.value}"

  }

}
Enter fullscreen mode Exit fullscreen mode

Difference

count

server[0]
server[1]
server[2]
Enter fullscreen mode Exit fullscreen mode

for_each

server["web"]
server["api"]
server["worker"]
Enter fullscreen mode Exit fullscreen mode

Step 9 — Using timestamp()

Create file containing deployment time.

resource "local_file" "deployment_info" {

  filename = "deployment.txt"

  content = "Deployment time: ${timestamp()}"

}
Enter fullscreen mode Exit fullscreen mode

Example output file:

Deployment time: 2026-03-16T14:20:33Z
Enter fullscreen mode Exit fullscreen mode

Step 10 — Terraform Outputs

outputs.tf

output "server_count" {

  value = length(var.servers)

}

output "deployment_time" {

  value = timestamp()

}
Enter fullscreen mode Exit fullscreen mode

Run:

terraform output
Enter fullscreen mode Exit fullscreen mode

Step 11 — Initialize Terraform

Run:

terraform init -upgrade
Enter fullscreen mode Exit fullscreen mode

What -upgrade does

It upgrades providers to the latest compatible version.

Example:

aws v5.40 -> v5.55
Enter fullscreen mode Exit fullscreen mode

Step 12 — Terraform Plan with Output File

Run:

terraform plan -out=infra.plan
Enter fullscreen mode Exit fullscreen mode

This saves execution plan.

Benefits:

  • review plan
  • share plan with team
  • ensure no changes occur before apply

Apply saved plan:

terraform apply infra.plan
Enter fullscreen mode Exit fullscreen mode

Step 13 — Target Specific Resource

Plan only one resource.

terraform plan -target=local_file.deployment_info
Enter fullscreen mode Exit fullscreen mode

Apply only one resource.

terraform apply -target=local_file.deployment_info
Enter fullscreen mode Exit fullscreen mode

Destroy specific resource.

terraform destroy -target=local_file.deployment_info
Enter fullscreen mode Exit fullscreen mode

Step 14 — Target Security Group

Example:

terraform apply -target=aws_security_group.web
Enter fullscreen mode Exit fullscreen mode

This creates only security group.


Step 15 — Terraform Taint

Taint forces resource recreation.

Example:

terraform taint aws_instance.count_servers[0]
Enter fullscreen mode Exit fullscreen mode

Next apply:

terraform apply
Enter fullscreen mode Exit fullscreen mode

Terraform destroys and recreates that instance.


Step 16 — Terraform Graph

Visualize Terraform infrastructure.

Run:

terraform graph
Enter fullscreen mode Exit fullscreen mode

Example output:

aws_security_group.web
        
aws_instance.count_servers
        
outputs
Enter fullscreen mode Exit fullscreen mode

You can convert graph to image:

terraform graph | dot -Tpng > graph.png
Enter fullscreen mode Exit fullscreen mode

Step 17 — Terraform Output Command

View outputs:

terraform output
Enter fullscreen mode Exit fullscreen mode

Example:

server_count = 3
deployment_time = 2026-03-16T14:20:33Z
Enter fullscreen mode Exit fullscreen mode

Step 18 — Terraform at Scale (API Throttling)

When Terraform manages hundreds or thousands of resources, cloud providers may limit requests.

Example:

AWS allows limited API calls per second.

If Terraform sends too many requests:

API throttling
Rate exceeded
Enter fullscreen mode Exit fullscreen mode

Solutions

1️⃣ Reduce parallelism

terraform apply -parallelism=5
Enter fullscreen mode Exit fullscreen mode

Default is 10 parallel operations.


2️⃣ Use modules

Split infrastructure into smaller deployments.


3️⃣ Use workspaces

Separate environments:

dev
stage
prod
Enter fullscreen mode Exit fullscreen mode

4️⃣ Use remote state

Store state in:

S3
Terraform Cloud
Azure Storage
Enter fullscreen mode Exit fullscreen mode

Final Architecture Created

This lab creates:

Security Group
3 EC2 instances using count
3 EC2 instances using for_each
Local file with timestamp
Outputs
Enter fullscreen mode Exit fullscreen mode

also practice:

terraform init -upgrade
terraform plan -out
terraform apply -target
terraform destroy -target
terraform graph
terraform taint
terraform output
Enter fullscreen mode Exit fullscreen mode

Top comments (0)