Hi @apparentlymart thanks for asking and your help. Below is code I am trying to achieve.
main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.30.0"
}
}
}
provider "azurerm" {
features {
}
}
module "resourcegroup" {
source = "./modules/resourcegroup"
rg_name = var.rg_name
location = var.location
}
module "networking" {
source = "./modules/networking"
rg_name = module.resourcegroup.resource_group_name
location = module.resourcegroup.location_id
vnet_name = var.vnet_name
address_space = var.address_space
subnets = var.subnets
network_security_group_names = var.network_security_group_names
network_sucurity_group_rules = var.network_sucurity_group_rules
}
module "compute" {
source = "./modules/compute"
rg_name = module.resourcegroup.resource_group_name
location = module.resourcegroup.location_id
network_interface_name = tomap({
for k, subnet_id in module.networking.subnet_ids : k => {
name = k
subnet_id = subnet_id }
})
}
variables.tf
variable "rg_name" {}
variable "location" {}
variable "vnet_name" {}
variable "address_space" {}
variable "subnets" {
type = map(string)
}
variable "network_interface_name" {
type = map (
object ({
name = string
subnet_id = string
})
)
}
variable "network_sucurity_group_rules" {
type=list
}
variable "network_security_group_names" {
type=map(string)
}
terraform.tfvars
rg_name = "Az3Tier"
location = "SouthEast Asia"
vnet_name = "Az3tier-vnet"
address_space = "10.0.0.0/16"
subnets = {
"web-subnet" = "10.0.1.0/24"
"app-subnet" = "10.0.2.0/24"
"db-subnet" = "10.0.3.0/24"
}
network_security_group_names = {
"web-nsg" = "web-subnet"
"app-nsg" = "app-subnet"
"db-nsg" = "db-subnet"
}
network_sucurity_group_rules = [
{
id=1,
priority = "200",
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "3389"
source_address_prefix = "*"
destination_address_prefix = "*"
network_security_group_names = "web-nsg"
},
{
id=2,
priority = "300",
direction = "Inbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "*"
destination_address_prefix = "*"
network_security_group_names = "web-nsg"
},
{
id=3,
priority = "200",
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "3389"
source_address_prefix = "10.0.1.0/24"
destination_address_prefix = "10.0.2.0/24"
network_security_group_names = "app-nsg"
},
{
id=4,
priority = "200",
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "1433"
source_address_prefix = "10.0.2.0/24"
destination_address_prefix = "10.0.3.0/24"
network_security_group_names = "db-nsg"
},
{
id=5,
priority = "4094",
direction = "Inbound"
access = "Deny"
protocol = "*"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "*"
network_security_group_names = "db-nsg"
},
{
id=6,
priority = "4096",
direction = "Outbound"
access = "Deny"
protocol = "*"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "*"
network_security_group_names = "db-nsg"
}
]
network_interface_name = [ {
name = "web-nic"
subnet_id = "web-subnet"
},
{
name = "app-nic"
subnet_id = "app-subnet"
},
{
name = "db-nic"
subnet_id = "db-subnet"
}
]
module / resourcegroup
rg.tf
resource "azurerm_resource_group" "ex-re-1" {
name = var.rg_name
location = var.location
}
variables.tf
variable "rg_name" {}
variable "location" {}
output.tf
output "resource_group_name" {
value = azurerm_resource_group.ex-re-1.name
description = "Name of the resource group"
}
output "location_id" {
value = azurerm_resource_group.ex-re-1.location
description = "Location id of the resource group"
}
modules / networking
vnet.tf
resource "azurerm_virtual_network" "ex-re-2" {
name = var.vnet_name
location = var.location
resource_group_name = var.rg_name
address_space = [var.address_space]
}
resource "azurerm_subnet" "ex-re-3" {
for_each = var.subnets
resource_group_name = var.rg_name
virtual_network_name = azurerm_virtual_network.ex-re-2.name
name = each.key
address_prefixes = [each.value]
}
resource "azurerm_network_security_group" "ex-re-4" {
for_each = var.network_security_group_names
name = each.key
location = var.location
resource_group_name = var.rg_name
}
resource "azurerm_subnet_network_security_group_association" "ex-re-5" {
for_each = var.network_security_group_names
subnet_id = azurerm_subnet.ex-re-3[each.value].id
network_security_group_id = azurerm_network_security_group.ex-re-4[each.key].id
}
resource "azurerm_network_security_rule" "ex-re-6" {
for_each = {for rule in var.network_sucurity_group_rules:rule.id => rule}
name = "${each.value.access}-${each.value.destination_port_range}"
priority = each.value.priority
direction = each.value.direction
access = each.value.access
protocol = each.value.protocol
source_port_range = each.value.source_port_range
destination_port_range = each.value.destination_port_range
source_address_prefix = each.value.source_address_prefix
destination_address_prefix = each.value.destination_address_prefix
resource_group_name = var.rg_name
network_security_group_name = azurerm_network_security_group.ex-re-4[each.value.network_security_group_names].name
}
variables.tf
variable "rg_name" {}
variable "location" {}
variable "vnet_name" {}
variable "address_space" {}
variable "subnets" {
type = map(string)
}
variable "network_security_group_names" {
type=map(string)
}
variable "network_sucurity_group_rules" {
type=list
}
output.tf
output "network_name" {
value = azurerm_virtual_network.ex-re-2
description = "Name of the virtual network"
}
output "subnet_ids" {
value = tomap ({for k, s in azurerm_subnet.ex-re-3:k => s.id})
}
modules/computing
main.tf
resource "azurerm_network_interface" "ex-re-7" {
for_each = var.network_interface_name
name = each.value.name
resource_group_name = var.rg_name
location = var.location
ip_configuration{
name = "Internal"
subnet_id = each.value.subnet_id
private_ip_address_allocation = "Dynamic"
}
}
variables.tf
variable "rg_name" {}
variable "location" {}
variable "network_interface_name" {
type = map (
object ({
name = string
subnet_id = string
})
)
}
Sorry for the long coding since I split the resources into different groups as modules.
And the output error is…
PS C:\Terraform\5-11-2022> terraform init
Initializing modules...
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of hashicorp/azurerm from the dependency lock file
- Using previously-installed hashicorp/azurerm v3.30.0
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
PS C:\Terraform\5-11-2022> terraform validate
Success! The configuration is valid.
PS C:\Terraform\5-11-2022> terraform plan -out main.tfplan
module.resourcegroup.azurerm_resource_group.ex-re-1: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier]
module.networking.azurerm_network_security_group.ex-re-4["app-nsg"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/networkSecurityGroups/app-nsg]
module.networking.azurerm_virtual_network.ex-re-2: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/virtualNetworks/Az3tier-vnet]
module.networking.azurerm_network_security_group.ex-re-4["web-nsg"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/networkSecurityGroups/web-nsg]
module.networking.azurerm_network_security_group.ex-re-4["db-nsg"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/networkSecurityGroups/db-nsg]
module.networking.azurerm_subnet.ex-re-3["web-subnet"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/virtualNetworks/Az3tier-vnet/subnets/web-subnet]
module.networking.azurerm_subnet.ex-re-3["app-subnet"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/virtualNetworks/Az3tier-vnet/subnets/app-subnet]
module.networking.azurerm_subnet.ex-re-3["db-subnet"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/virtualNetworks/Az3tier-vnet/subnets/db-subnet]
module.networking.azurerm_network_security_rule.ex-re-6["1"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/networkSecurityGroups/web-nsg/securityRules/Allow-3389]
module.networking.azurerm_network_security_rule.ex-re-6["2"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/networkSecurityGroups/web-nsg/securityRules/Allow-80]
module.networking.azurerm_network_security_rule.ex-re-6["6"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/networkSecurityGroups/db-nsg/securityRules/Deny-*]
module.networking.azurerm_network_security_rule.ex-re-6["5"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/networkSecurityGroups/db-nsg/securityRules/Deny-*]
module.networking.azurerm_network_security_rule.ex-re-6["4"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/networkSecurityGroups/db-nsg/securityRules/Allow-1433]
module.networking.azurerm_network_security_rule.ex-re-6["3"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/networkSecurityGroups/app-nsg/securityRules/Allow-3389]
module.networking.azurerm_subnet_network_security_group_association.ex-re-5["web-nsg"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/virtualNetworks/Az3tier-vnet/subnets/web-subnet]
module.networking.azurerm_subnet_network_security_group_association.ex-re-5["db-nsg"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/virtualNetworks/Az3tier-vnet/subnets/db-subnet]
module.networking.azurerm_subnet_network_security_group_association.ex-re-5["app-nsg"]: Refreshing state... [id=/subscriptions/8e4dbcff-3b28-4654-837f-458c790f4e5f/resourceGroups/Az3Tier/providers/Microsoft.Network/virtualNetworks/Az3tier-vnet/subnets/app-subnet]
╷
│ Error: Invalid value for input variable
│
│ on terraform.tfvars line 91:
│ 91: network_interface_name = [ {
│ 92: name = "web-nic"
│ 93: subnet_id = "web-subnet"
│ 94: },
│ 95: {
│ 96: name = "app-nic"
│ 97: subnet_id = "app-subnet"
│ 98: },
│ 99: {
│ 100: name = "db-nic"
│ 101: subnet_id = "db-subnet"
│ 102: }
│ 103: ]
│
│ The given value is not valid for variable "network_interface_name": map of object required.
╵
PS C:\Terraform\5-11-2022>
I understand that the map of object is required as input. But not sure how I bring into map of object terraform.tfvars. Sorry for the very long code and your help is highly appreciated.
Regards,
Hajee_78