I'm new to Terraform and trying to figure out how to use it to create multiple VMs in different Azure regions. I'm expecting it to do the entire deployment, including creating VNETs, subnets, NICs, and everything related to the VM. I've gotten pretty far, but am stuck on how to get the subnet ID that gets created and use it in the NIC creation. I have tried a few different things and can't get it to work how I need it to. If there is a more efficient way to achieve this I'd love to hear it!
Here's my code:
variable "regions" {
type = map(object({
name = string
region = string
address_space = string
}))
default = {
"us-east-2" = {
name = "us-east-2"
region = "East US 2"
address_space = "10.1.0.0/16"
},
"uk-south" = {
name = "uk-south"
region = "UK South"
address_space = "10.2.0.0/16"
},
"aus-east" = {
name = "aus-east"
region = "Australia East"
address_space = "10.3.0.0/16"
}
}
}
variable "resource-group" {
default = "rg-vm"
}
resource "azurerm_virtual_network" "vnet" {
for_each = var.regions
name = "vnet-${each.value.name}"
location = each.value.region
resource_group_name = var.resource-group
address_space = ["${each.value.address_space}"]
}
resource "azurerm_subnet" "subnet-lan" {
for_each = var.regions
name = "vnet-${each.value.name}-LAN"
resource_group_name = var.resource-group
virtual_network_name = "vnet-${each.value.name}"
address_prefixes = ["${cidrsubnet(each.value.address_space, 8, 1)}"]
}
output "subnet_ids" {
value = {
for k, v in azurerm_subnet.subnet-lan : k => v.id
}
depends_on = [azurerm_subnet.subnet-lan]
}
resource "azurerm_network_interface" "nic" {
for_each = var.regions
name = "nic-${each.value.name}-ub-vm01"
location = each.value.region
resource_group_name = var.resource-group
ip_configuration {
name = "ipconfig1"
subnet_id = each.value.id
private_ip_address_allocation = "Dynamic"
}
}
I have tried using an output clause among other things and I keep getting errors when trying to reference the subnets that get created.
Using output from one terraform resource for_each in another resource
Issue seems to with the way you refer the each.value.id
for azurerm_network_interface
this refers won't add the actual ID which may results in the blocker.
Try refer as mentioned below make necessay changes as in the way you refering subnet in NIC as mentioned below
Demo configuration:
variable "regions" {
type = map(object({
name = string
region = string
address_space = string
}))
default = {
"us-east-2" = {
name = "usvk-east-2"
region = "East US 2"
address_space = "10.1.0.0/16"
},
"uk-south" = {
name = "ukvk-south"
region = "UK South"
address_space = "10.2.0.0/16"
},
"aus-east" = {
name = "ausvk-east"
region = "Australia East"
address_space = "10.3.0.0/16"
}
}
}
variable "resource_group_name" {
default = "rgvk-vm"
}
resource "azurerm_resource_group" "rg" {
name = var.resource_group_name
location = "East US"
}
resource "azurerm_virtual_network" "vnet" {
for_each = var.regions
name = "vnet-${each.value.name}"
location = each.value.region
resource_group_name = azurerm_resource_group.rg.name
address_space = [each.value.address_space]
}
resource "azurerm_subnet" "subnet" {
for_each = var.regions
name = "subnet-${each.value.name}"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet[each.key].name
address_prefixes = ["${cidrsubnet(each.value.address_space, 8, 1)}"]
}
resource "azurerm_network_interface" "nic" {
for_each = var.regions
name = "nic-${each.value.name}-ub-vm01"
location = each.value.region
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "ipconfig1"
subnet_id = azurerm_subnet.subnet[each.key].id
private_ip_address_allocation = "Dynamic"
}
}
deployment:
Refer:
https://build5nines.com/terraform-ip-functions-for-managing-ip-addresses-cidr-blocks-and-subnets/
https://discuss.hashicorp.com/t/multiple-for-each/51076
https://dev.azure.com/v-scheedella/MT%20Stack%20Overflow/_workitems/edit/42784