Skip to content

Terraform Input Variables with Collection Type set

Step-01: Introduction

  • Implement Collection Type set
  • What is set ?

Usecase

  • We will implement 4 environments (dev, qa, staging and prod) using single set of templates
  • We will use for_each and set combination to do that.
  • For each environment, following Resources will be created with single set of Terraform Configs
  • Resource Group
  • Virtual Network
  • Subnet
  • Public IP & Public Azure DNS Name
  • Network Interface
  • RHEL Virtual machine
  • Provision sample webserver in that RHEL VM

Step-02: Implement complex type cosntructors like list

sets:

  1. Sets do not support element ordering, meaning that traversing sets is not guaranteed to yield the same order each time and that their elements can not be accessed in a targeted way.
  2. They contain unique elements repeated exactly once, and specifying the same element multiple times will result in them being coalesced with only one instance being present in the set.
  3. Declaring a set is similar to declaring a list, the only difference being the type of the variable:
    # 2. Environment Name
    variable "environment" {
      description = "Environment Name"
      type = set(string)
      default = ["dev1", "qa1", "staging1", "prod1"]
    }
    

Step-03: c2-variables.tf

  • Define the Input Variable Type set for environment.
    # 2. Environment Name
    variable "environment" {
      description = "Environment Name"
      type = set(string)
      default = ["dev1", "qa1", "staging1", "prod1"]
    }
    

Step-04: terraform.tfvars

  • Core focus on variables will be on environment variable of type set
  • Rest variables are hard-coded in those respective resources.
  • Review environment variable in terraform.tfvars
    business_unit = "it"
    environment = ["dev2", "myqa2", "staging2", "prod2"]
    resoure_group_name = "rg"
    

Step-05: c1-versions.tf

  • As we are going to create 4 environments, our Random String Resource also need to be traversed in for_each loop to create 4 random strings per environment
  • Create 4 Random Strings using for_each with set variable var.environment
    # Random String Resource
    resource "random_string" "myrandom" {
      for_each = var.environment
      length = 6
      upper = false 
      special = false
      number = false   
    }
    

Step-06: c3-resource-group.tf

  • Create 4 Resource Groups using for_each with set variable var.environment
    # Resource-1: Azure Resource Group
    resource "azurerm_resource_group" "myrg" {
      for_each = var.environment
      name = "${var.business_unit}-${each.key}-${var.resoure_group_name}"
      location = var.resoure_group_location
    }
    

Step-07: c4-virtual-network.tf - Virtual Network

  • Create 4 Virtual Networks using for_each with set variable var.environment
  • One Virtual Network will be created in each Resource Group
    # Create Virtual Network
    resource "azurerm_virtual_network" "myvnet" {
      for_each = var.environment
      name                = "${var.business_unit}-${each.key}-${var.virtual_network_name}"
      address_space       = ["10.0.0.0/16"]
      location            = azurerm_resource_group.myrg[each.key].location
      resource_group_name = azurerm_resource_group.myrg[each.key].name
    }
    

Step-08: c4-virtual-network.tf - Subnet

  • Create 4 Subnets using for_each with set variable var.environment
  • One Subnet will be created in each Virtual Network
    # Create Subnet
    resource "azurerm_subnet" "mysubnet" {
      for_each = var.environment
      #name                 = "mysubnet-1"
      name = "${var.business_unit}-${each.key}-${var.virtual_network_name}-mysubnet"
      resource_group_name  = azurerm_resource_group.myrg[each.key].name
      virtual_network_name = azurerm_virtual_network.myvnet[each.key].name
      address_prefixes     = ["10.0.2.0/24"]
    }
    

Step-09: c4-virtual-network.tf - Public IP

  • Create 4 Public IPs using for_each with set variable var.environment
  • One Public IP will be created and associated to respective Network Interface in each Virtual Network
    # Create Public IP Address
    resource "azurerm_public_ip" "mypublicip" {
      for_each = var.environment
      #name                = "mypublicip-1"
      name = "${var.business_unit}-${each.key}-${var.virtual_network_name}-mypublicip"  
      resource_group_name = azurerm_resource_group.myrg[each.key].name
      location            = azurerm_resource_group.myrg[each.key].location
      allocation_method   = "Static"
      #domain_name_label = "app1-vm-${random_string.myrandom[each.key].id}"
       domain_name_label = "app1-vm-${each.key}-${random_string.myrandom[each.key].id}"
      tags = {
        environment = "Dev"
      }
    }
    

Step-10: c4-virtual-network.tf - Network Interface

  • Create 4 Network Interfaces using for_each with set variable var.environment
  • One Network Interface will be created and associated to respective Virtual Machine in each Virtual Network
    # Create Network Interface
    resource "azurerm_network_interface" "myvmnic" {
      for_each = var.environment
      #name                = "vmnic"
      name = "${var.business_unit}-${each.key}-${var.virtual_network_name}-myvmnic"    
      location            = azurerm_resource_group.myrg[each.key].location
      resource_group_name = azurerm_resource_group.myrg[each.key].name
    
      ip_configuration {
        name                          = "internal"
        subnet_id                     = azurerm_subnet.mysubnet[each.key].id
        private_ip_address_allocation = "Dynamic"
        public_ip_address_id = azurerm_public_ip.mypublicip[each.key].id 
      }
    }
    

Step-11: c5-linux-virtual-machine.tf - Linux Virutal Machine

  • Create 4 Virtual Machines using for_each with set variable var.environment
  • One Virtual Machine will be created in each Virtual Network and associated to respective Network Interface
    # Resource: Azure Linux Virtual Machine
    resource "azurerm_linux_virtual_machine" "mylinuxvm" {
      for_each = var.environment
      name                = "mylinuxvm-${each.key}"
      computer_name       = "devlinux-${each.key}" # Hostname of the VM
      resource_group_name = azurerm_resource_group.myrg[each.key].name
      location            = azurerm_resource_group.myrg[each.key].location
      size                = "Standard_DS1_v2"
      admin_username      = "azureuser"
      network_interface_ids = [azurerm_network_interface.myvmnic[each.key].id]
      admin_ssh_key {
        username   = "azureuser"
        public_key = file("${path.module}/ssh-keys/terraform-azure.pub")
      }
      os_disk {
        name = "osdisk${each.key}"
        caching              = "ReadWrite"
        storage_account_type = "Standard_LRS"
        #disk_size_gb = 20
      }
      source_image_reference {
        publisher = "RedHat"
        offer     = "RHEL"
        sku       = "83-gen2"
        version   = "latest"
      }
      custom_data = filebase64("${path.module}/app-scripts/app1-cloud-init.txt")
    }
    

Step-12: Execute Terraform Commands

# Initialize Terraform
terraform init

# Validate Terraform configuration files
terraform validate

# Format Terraform configuration files
terraform fmt

# Review the terraform plan
terraform plan 

# Terraform Apply
terraform apply -auto-approve

# Observation
1. Verify 4 Random Resources created
2. Verify 4 Resource Groups created
3. Verify 4 Virtual Networks created
4. Verify 4 Subnets created
5. Verify 4 Network Interfaces created
6. Verify 4 Virtual Machines created
7. Verify 4 public ips created
8. Verify Disks for Virtual Machines - 4 osdisk created

# Access Sample App
## Root Context
http://app1-vm-dev2-yjedfa.eastus.cloudapp.azure.com
http://app1-vm-myqa2-ysutkd.eastus.cloudapp.azure.com
http://app1-vm-prod2-qoaqpq.eastus.cloudapp.azure.com
http://app1-vm-staging2-pcyeuc.eastus.cloudapp.azure.com

## App1 Context
http://app1-vm-dev2-yjedfa.eastus.cloudapp.azure.com/app1/index.html
http://app1-vm-myqa2-ysutkd.eastus.cloudapp.azure.com/app1/index.html
http://app1-vm-prod2-qoaqpq.eastus.cloudapp.azure.com/app1/index.html
http://app1-vm-staging2-pcyeuc.eastus.cloudapp.azure.com/app1/index.html

## metadata.html
http://app1-vm-dev2-yjedfa.eastus.cloudapp.azure.com/app1/metadata.html
http://app1-vm-myqa2-ysutkd.eastus.cloudapp.azure.com/app1/metadata.html
http://app1-vm-prod2-qoaqpq.eastus.cloudapp.azure.com/app1/metadata.html
http://app1-vm-staging2-pcyeuc.eastus.cloudapp.azure.com/app1/metadata.html

Step-10: Clean-Up

# Destroy Resources
terraform destroy -auto-approve

# Delete Files
rm -rf .terraform* 
rm -rf terraform.tfstate*

References

🎉 New Course
Ultimate DevOps Real-World Project Implementation on AWS
$15.99 $84.99 81% OFF
MARCH2026
Enroll Now on Udemy →
🎉 Offer