Today was all about Terraform type constraints.I finally understood how Terraform handles different data types, how to structure them properly, and how powerful they become when you combine them inside real infrastructure code.
What I Learned Today
1. Type Constraints Make Terraform Safer and Cleaner
I finally understood why Terraform allows you to define types for your variables.
It forces consistency, reduces errors, and makes your configuration more predictable.
2. List & Set Types (and how to index them)
-
List : ordered, allows duplicates, access with index (
[0],[1]) - Set : unordered, unique values, must convert to list for indexing
I used list and set types heavily today especially for selecting regions, VM types, and CIDR blocks.
3. Tuples and Map Types
- Tuple : ordered collection of mixed types
- Map : key/value structure, perfect for tags and metadata
Using a tuple for ingress rules was interesting because each element had a different type:
number, string, number.
4. Nested Types (Objects Inside Objects)
I learned how to nest complex constraints using the object() type and how to pass an entire structure (region, monitoring, instance_count) into resource blocks cleanly.
It felt like switching from Terraform beginner scripting to Terraform engineering.
Commands I Used Today
Only two commands were used today, simple but essential:
terraform initterraform plan
Because today was more about variable types and configuration structure than provisioning new resources.
My Terraform Files for Day 07
Below is exactly what I used today nothing added, nothing removed.
main.tf
resource "aws_instance" "example" {
count = var.config.instance_count
ami = "resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64"
instance_type = var.allowed_vm_type[1]
#region = tolist(var.allowed_region)[0]
region = var.config.region
monitoring = var.config.monitoring
associate_public_ip_address = var.associate_public_ip
tags = var.tags
}
resource "aws_security_group" "allow_tls" {
name = "allow_tls"
description = "Allow TLS inbound traffic and all outbound traffic"
tags = var.tags
}
resource "aws_vpc_security_group_ingress_rule" "allow_tls_ipv4" {
security_group_id = aws_security_group.allow_tls.id
cidr_ipv4 = var.cidr_block[0]
from_port = var.ingress_values[0]
ip_protocol = var.ingress_values[1]
to_port = var.ingress_values[2]
}
resource "aws_vpc_security_group_egress_rule" "allow_all_traffic_ipv4" {
security_group_id = aws_security_group.allow_tls.id
cidr_ipv4 = "0.0.0.0/0"
ip_protocol = "-1"
}
variable.tf
variable "environment" {
type = string
default = "dev"
}
variable "instance_count" {
description = "Number of EC2 instances to create"
type = number
}
variable "region" {
type = string
default = "us-east-1"
}
variable "monitoring_enabled" {
description = "Enable detailed monitoring for EC2 instances"
type = bool
default = true
}
variable "associate_public_ip" {
description = "Associate public IP address with EC2 instance"
type = bool
default = true
}
variable "cidr_block" {
description = "CIDR block for the VPC"
type = list(string)
default = ["10.0.0.0/8", "192.168.0.0/16", "172.16.0.0/12"]
}
variable "allowed_vm_type" {
description = "List of allowed VM types"
type = list(string)
default = ["t2.micro", "t2.small", "t3.micro", "t3.small"]
}
variable "allowed_region" {
description = "List of allowed AWS regions"
type = set(string)
default = ["us-east-1", "us-west-2", "eu-west-1"]
}
variable "tags" {
type = map(string)
default = {
Environment = "dev"
Name = "dev-Instance"
}
}
variable "ingress_values" {
type = tuple([number, string, number])
default = [443, "tcp", 443]
}
variable "config" {
type = object({
region = string,
monitoring = bool,
instance_count = number
})
default = {
region = "us-east-1",
monitoring = true,
instance_count = 1
}
}
backend.tf
terraform {
backend "s3" {
bucket = "devopswithzacks-terraform-state"
key = "dev/terraform.tfstate"
region = "us-east-1"
encrypt = true
use_lockfile = true
}
}
.gitignore
.terraform.lock.hcl
terraform.tfvars
.terraform/
*.tfvars.json
*.log
crash.log
*.terraform.*backup
*.tfstate
*.tfstate.backup
Final Thoughts for Day 07
Understanding type constraints, nested data structures, and how to access values inside them completely transformed how I write Terraform configurations. These aren’t just “variables” anymore these are structured, predictable inputs that make scaling infrastructure easier and safer.
Every day, Terraform becomes more intuitive, and these building blocks are exactly what I’ll need for more complex modules later in the challenge.
Day 07 DONE.
On to Day 08.
Top comments (0)