I am trying to associated NIC addresses to the existing application security group using the id. However, I am getting " Inappropriate value for attribute "network_interface_id": string required for azurerm_network_interface_application_security_group_association"
Below is my azure terraform code.
main.tf ( root module )
module "virtualmachine" {
source = "./virtualmachine"
virtual_machines = var.virtual_machines
}
vairable.tf ( root module )
variable "virtual_machines" {}
virtual machine module code
resource "azurerm_network_interface" "nic" {
for_each = {
for vm in flatten([
for vm_name, vm in var.virtual_machines.nodes : [
for nic_name, nic in vm.networks : {
vm_number = vm.vm_num,
vm_name = vm_name,
nic_name = nic_name,
subnet_value = nic.subnet
nic_name_value = nic.nic_name
}
]
]) : "${vm.vm_name}-${vm.nic_name}" => vm
}
name = "${each.value.nic_name_value}-nic"
location = "eastus"
resource_group_name = "test"
ip_configuration {
name = "${each.value.nic_name_value}-ipconfig"
subnet_id = each.value.subnet_value
private_ip_address_allocation = "Dynamic"
}
}
resource "azurerm_linux_virtual_machine" "vm" {
depends_on = [azurerm_network_interface.nic]
for_each = var.virtual_machines.nodes
name = "${each.value.vm_name}-${each.value.vm_num}"
admin_username = "testadmin"
admin_password = "test@1234522"
disable_password_authentication = false
location = "eastus"
resource_group_name = "test"
network_interface_ids = [for nic_key, nic in azurerm_network_interface.nic : nic.id if startswith(nic_key, "${each.key}-")]
size = "Standard_B2ms"
os_disk {
name = "${each.value.vm_name}-${each.value.vm_num}-OSdisk"
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "RedHat"
offer = "RHEL"
sku = "82gen2"
version = "latest"
}
}
resource "azurerm_network_interface_application_security_group_association" "asg_association" {
for_each = {
for vm in flatten([
for vm_name, vm in var.virtual_machines.nodes : [
for asg_name, asg in vm.ass_nic_asg : {
asg_name = asg_name
vm_name = vm_name
asg_id = asg.asg_id
}
]
]) : "${vm.vm_name}-${vm.asg_name}" => vm
}
network_interface_id = [for nic_key, nic in azurerm_network_interface.nic : nic.id]
application_security_group_id = each.value.asg_id
}
virtual machine variable.tf
variable "virtual_machines" {}
variable.tfvars
virtual_machines = {
nodes = {
app1_node1 = {
"vm_name" = "app"
"vm_num" = "1"
networks = {
nic1 = {
"nic_name" = "app-1"
"subnet" = "****/app-subnet"
},
}
ass_nic_asg = {
asg1 = {
asg_id = "***/app-asg"
}
ags2 = {
asg_id = "***/app-asg"
}
}
}
}
}
Error :
│ Error: Incorrect attribute value type
│
│ on virtualmachine\main.tf line 69, in resource "azurerm_network_interface_application_security_group_association" "asg_association":
│ 69: network_interface_id = [for nic_key, nic in azurerm_network_interface.nic : nic.id]
│ ├────────────────
│ │ azurerm_network_interface.nic is object with 1 attribute "app1_node1-nic1"
│
│ Inappropriate value for attribute "network_interface_id": string required.
╵
╷
│ Error: Incorrect attribute value type
│
│ on virtualmachine\main.tf line 69, in resource "azurerm_network_interface_application_security_group_association" "asg_association":
│ 69: network_interface_id = [for nic_key, nic in azurerm_network_interface.nic : nic.id]
│ ├────────────────
│ │ azurerm_network_interface.nic is object with 1 attribute "app1_node1-nic1"
│
│ Inappropriate value for attribute "network_interface_id": string required.
╵
can someone through a light where I am doing wrong in getting the network interface id ?
Expected - tfvars structure
virtual_machines = {
nodes = {
app1_node1 = {
"vm_name" = "app"
"vm_num" = "1"
networks = {
nic1 = {
"nic_name" = "app-1"
"subnet" = "**/app-subnet"
"asg_ids" = ["**/app-asg", "**/db-asg"]
},
nic2 = {
"nic_name" = "app-2"
"subnet" = "**app-subnet"
"asg_ids" = ["**/app-asg", "**/db-asg"]
},
}
}
}
}
You are facing a typical problem that occurs when using
for_eachand complex object structures in Terraform. This problem is more evident when you want to link resources to each other.indicates that Terraform is expecting a single string for
network_interface_id, but your expression is generating a list of strings. This happens because you're using a list comprehension inside the assignment which generates a list.Moreover, the new error you encountered after applying the suggested fix:
Error: Invalid indexis due to attempting to access a network interface that does not exist for the given key. This is because yourfor_eachin theazurerm_network_interface_application_security_group_associationresource attempts to loop over a set of VMs and their associated ASGs without directly correlating them with the specific NICs they should be associated with.I tried a configuration and made some necessary corrections and I was able to achieve the requirement.
My Terraform configurations:
main.tf:
modules/virtual_machine_setup/main.tfterraform.tfvars:
Output: