# 🚀 Day 07 – Mastering Terraform Variable Type Constraints

Variables are central to making Terraform configurations flexible, reusable, and safe. On this day I learned about primitive types (string, number, bool), complex types (list, set, map, tuple, object), and how to use them — with validation — to build clean infrastructure code.

Below is what I learned, how types differ, and 10 conceptual tasks that illustrate how each type can be used in real-world AWS infrastructure definitions (with mini code examples).

## 🔹 Why Variable Type Constraints Matter

Terraform variables help avoid hard-coding values. Instead of embedding static values in configuration, you declare variables using `variable` blocks — which let you pass data at runtime or reuse the configuration across environments. [HashiCorp Developer+2HashiCorp Developer+2](https://developer.hashicorp.com/terraform/tutorials/configuration-language/variables?utm_source=chatgpt.com)

Specifying a `type` constraint ensures Terraform validates that the provided value matches expected structure. This reduces errors, enforces consistency, and makes modules safer and more maintainable. [HashiCorp Developer+2Env0+2](https://developer.hashicorp.com/terraform/language/expressions/type-constraints?utm_source=chatgpt.com)

When infrastructure grows (multiple environments, many resources), types + validation + organized variables make configuration manageable.

---

## 🧠 Terraform Variable Types Overview

Terraform supports different variable types:

### ✅ Primitive Types

* **string**: textual values (e.g. "${var.environment}-app")
    
* **number**: integers or floats (e.g. instance counts, sizes)
    
* **bool**: true/false flags (e.g. enable monitoring) [Medium+1](https://medium.com/%40chillcaley/terraform-variable-types-a-comprehensive-guide-a8f1a56da13d?utm_source=chatgpt.com)
    

### ✅ Collection & Structural Types

* **list(type)** — ordered collection of same-type elements
    
* **set(type)** — unordered no-duplicate collection (unique values)
    
* **map(type)** — key → value pairs with string keys
    
* **tuple(\[type1, type2, ...\])** — ordered, fixed-structure collection (types of elements defined)
    
* **object({key1=type1, key2=type2, ...})** — structured object with named attributes of defined types [HashiCorp Developer+2Medium+2](https://developer.hashicorp.com/terraform/language/expressions/type-constraints?utm_source=chatgpt.com)
    

Collections & structural types let you represent more complex data — tags, lists of subnets, security group settings, configuration objects etc.

---

## 🎯 Day 07 – 10 Conceptual Tasks & Mini Code Examples

Here are 10 tasks (as in challenge) along with example Terraform snippets demonstrating each type’s usage.

### **Task 1 — String Constraint (environment, region)**

Use `string` variables to set AWS provider region and naming conventions.

```plaintext
variable "environment" { type = string, default = "dev" }
variable "region"      { type = string, default = "us-east-1" }

provider "aws" {
  region = var.region
}

resource "aws_s3_bucket" "app_bucket" {
  bucket = "${var.environment}-terraform-bucket"
}
```

---

### **Task 2 — Number Constraint (instance\_count)**

Use `number` to create a variable number of EC2 instances.

```plaintext
variable "instance_count" { type = number, default = 2 }

resource "aws_instance" "web" {
  count         = var.instance_count
  ami           = "ami-xyz"
  instance_type = "t2.micro"
}
```

---

### **Task 3 — Boolean Constraint (monitoring\_enabled, associate\_public\_ip)**

Use `bool` to toggle resource parameters.

```plaintext
variable "monitoring_enabled"    { type = bool, default = true }
variable "associate_public_ip"   { type = bool, default = true }

resource "aws_instance" "server" {
  ami                         = "ami-xyz"
  instance_type               = "t2.micro"
  monitoring                  = var.monitoring_enabled
  associate_public_ip_address = var.associate_public_ip
}
```

---

### **Task 4 — List(string) Constraint (cidr\_block list)**

Use a list of strings for ordered configuration like VPC + subnets.

```plaintext
variable "cidr_block" {
  type    = list(string)
  default = ["10.0.0.0/8", "192.168.0.0/16", "172.16.0.0/12"]
}

resource "aws_vpc" "main" {
  cidr_block = var.cidr_block[0]
}

resource "aws_subnet" "subnet1" {
  cidr_block = var.cidr_block[1]
}

resource "aws_subnet" "subnet2" {
  cidr_block = var.cidr_block[2]
}
```

---

### **Task 5 — List(string) Constraint (allowed\_vm\_types validation)**

Use list to validate allowed VM types.

```plaintext
variable "allowed_vm_types" {
  type    = list(string)
  default = ["t2.micro", "t2.small", "t3.micro", "t3.small"]
}

variable "instance_type" {
  type = string

  validation {
    condition     = contains(var.allowed_vm_types, var.instance_type)
    error_message = "Instance type is not allowed!"
  }
}
```

---

### **Task 6 — Set(string) Constraint (allowed\_region validation)**

Use set to define allowed regions (unordered, unique) and validate region variable.

```plaintext
variable "allowed_region" {
  type    = set(string)
  default = ["us-east-1", "us-west-2", "eu-west-1"]
}

variable "region" {
  type = string

  validation {
    condition     = contains(var.allowed_region, var.region)
    error_message = "Region is not supported!"
  }
}
```

---

### **Task 7 — Map(string) Constraint (tags)**

Pass tags as a map to an AWS resource.

```plaintext
variable "tags" {
  type = map(string)
  default = {
    Environment = "dev"
    Name        = "dev-resource"
    created_by  = "terraform"
  }
}

resource "aws_vpc" "example" {
  cidr_block = "10.0.0.0/16"
  tags       = var.tags
}

output "resource_name" {
  value = var.tags["Name"]
}
```

---

### **Task 8 — Tuple Constraint (ingress\_values)**

Use tuple to define structured ingress rule parameters.

```plaintext
variable "ingress_values" {
  type    = tuple([number, string, number])
  default = [443, "tcp", 443]
}

resource "aws_security_group" "web_sg" {
  ingress {
    from_port   = var.ingress_values[0]
    protocol    = var.ingress_values[1]
    to_port     = var.ingress_values[2]
    cidr_blocks = ["0.0.0.0/0"]
  }
}
```

---

### **Task 9 — Object Constraint (config object)**

Use object type to group multiple settings into one variable.

```plaintext
variable "config" {
  type = object({
    region         = string
    monitoring     = bool
    instance_count = number
  })
  default = {
    region         = "us-east-1"
    monitoring     = true
    instance_count = 1
  }
}

provider "aws" {
  region = var.config.region
}

resource "aws_instance" "app" {
  count   = var.config.instance_count
  ami     = "ami-xyz"
  monitoring = var.config.monitoring
  instance_type = "t2.micro"
}
```

---

### **Task 10 — Mixed Type Constraints & Deployment Summary Output**

Combine different types into a deployment summary output.

```plaintext
output "deployment_summary" {
  value = {
    environment     = var.environment
    instance_count  = var.instance_count
    name_tag        = var.tags["Name"]
  }
}
```

---

## 🧠 My Day 07 Key Learnings

* Declaring types for input variables makes configurations safer and clearer. [HashiCorp Developer+2HashiCorp Developer+2](https://developer.hashicorp.com/terraform/tutorials/configuration-language/variables?utm_source=chatgpt.com)
    
* Collection & structural types (list, set, map, tuple, object) allow modeling complex data — helpful for tags, subnets, security rules, environment configs.
    
* Using `validation` blocks or `contains()` guards helps enforce business rules and prevent misconfigurations (e.g. invalid regions or wrong VM types).
    
* Good variable design + type constraints improves reusability and maintainability — essential for larger infrastructure. [DevOpsCube+2Brainboard Blog+2](https://devopscube.com/terraform-module-best-practices/?utm_source=chatgpt.com)
    

---

## 📺 Video (Day 07)

\[Embedded YouTube Video\]

[https://youtu.be/gu2oCJ9DQiQ?si=uJ4SXbdx3uA2roBp](https://youtu.be/gu2oCJ9DQiQ?si=uJ4SXbdx3uA2roBp)

---

## ✅ Conclusion

Day 07 transformed my understanding: from simple hard-coded configs to flexible, validated, and scalable Terraform setups. Now I’m ready to build robust infrastructure with confidence.  
Up for Day 08! 🚀

---
