Last Updated on August 7, 2025 by Arnav Sharma
Let’s assume you want to configure resources where attributes require similar structures. A list-to-map conversion with objects makes this more manageable.
Example
Consider this scenario: you have a list of property names. You want to create a map where each property name is a key, and the value is an object defining that property’s type.
Steps
Define Your List:
variable "property_list" {
type = list(string)
default = ["name", "description", "type"]
}
Create an Empty Map:
locals {
property_map = {}
}
Use a for loop:
locals {
property_map = {
for prop in var.property_list : prop => {
"type" = "string" # Assign a default type
}
}
}
Explanation
- We start with a variable
property_listcontaining the names of your properties. - An empty map,
property_map, is created within alocalsblock. - The
forloop iterates over eachprop(property name) in theproperty_list. - Inside the loop, it constructs an object with the current
propas the key. The object has a single attribute, “type”, set to “string” (you can customize this). - This object is then added to the
property_map.
Output
The resulting property_map would look like this:
{
"name" = { "type" = "string" }
"description" = { "type" = "string" }
"type" = { "type" = "string" }
}
Usage
You could then use this property_map to dynamically create resource configurations, feeding these objects into attributes.
Key Points
localsare used to define values that can be referenced elsewhere in your Terraform configuration.forloops are essential for transforming data structures in Terraform.- Customize the object’s structure within the
forloop to suit your specific use case (add more attributes, change types, etc.).
Example of Azure VM:
Let’s say you need to create several Azure VMs with similar configurations, but you want to vary the VM names and possibly some other attributes.
provider "azurerm" {
# ... Your Azure provider configuration ...
}
# Variables for VM configuration
variable "vm_names" {
type = list(string)
default = ["webserver-01", "webserver-02", "dbserver"]
}
variable "base_vm_config" {
type = map(object({
size = string
resource_group_name = string
location = string
image_urn = string
admin_username = string
admin_password = string
}))
default = {
size = "Standard_B2s"
resource_group_name = "my-resource-group"
location = "eastus"
image_urn = "Canonical:UbuntuServer:18.04-LTS:latest"
admin_username = "adminuser"
admin_password = "your_secure_password"
}
}
# Customize individual VM configurations
locals {
vm_configs = {
for vm_index, vm_name in var.vm_names : vm_name => merge(var.base_vm_config, {
name = vm_name,
size = (vm_index == 2 ? "Standard_D2s_v3" : var.base_vm_config.size),
tags = {
"role" = (vm_name == "dbserver" ? "database" : "web")
}
})
}
}
# Iterate and create VMs using the map
resource "azurerm_virtual_machine" "vm" {
for_each = local.vm_configs
# Access VM settings with each.key (VM name) and each.value
name = each.key
size = each.value.size
resource_group_name = each.value.resource_group_name
location = each.value.location
# ... (other VM configurations using each.value: network_interface_ids, storage_image_reference, etc.)
os_profile {
computer_name = each.key
admin_username = var.base_vm_config.admin_username
admin_password = var.base_vm_config.admin_password
}
os_profile_linux_config {
disable_password_authentication = false
}
}
Explanation:
- provider “azurerm”: Configures the Azure Resource Manager provider. You’ll need to have this set up with your Azure credentials.
- variable “vm_names”: Defines a list of your desired Azure VM names.
- variable “base_vm_config”: A map storing the core configuration that will be shared across most of your VMs.
- locals “vm_configs”:
forloop: Iterates over both the name and index (vm_index) of each VM.- merge: Combines the
base_vm_configwith customizations:- name: Sets the VM name.
- size: Conditionally assigns a different size for the third VM.
- tags: Assigns role-based tags for identification.
- resource “azurerm_virtual_machine” “vm”:
- for_each: Iterates over the
vm_configsmap. - each.key: Provides the VM name (e.g., “webserver-01”).
- each.value: Provides the entire configuration object for that specific VM.
- Example usage: Access
each.value.size,each.value.tags, etc.
- for_each: Iterates over the