Hi guys,
I’m hoping you can help, we recently upgraded our version of Terraform from version 0.12.26 to 0.13.4… Since then we have started to use for_each on our root modules. Now that we have done this, we can no longer use the outputs generated by the child module in our root main.tf like we could previously.
More specifically, we have root modules in our root-level main.tf file which call child modules to create either a Linux or Windows VM. This all works well, VM’s, NIC’s, NSG’s and disks are created as expected. However, when we then try to read the output from said child module back into the root module to then add NSG rules to the relevant NSG’s it fails with:
Error: Incorrect attribute value type
on main.tf line 69, in resource “azurerm_network_security_rule” “fico-app-sr-80”:
69: network_security_group_name = module.fico_app_vm.linux_vm_nsgInappropriate value for attribute “network_security_group_name”: string
required.
If I then update that line to add double quotes (network_security_group_name = “module.fico_app_vm.linux_vm_nsg”) to get around the type error, we see the following error:
Error: Error Creating/Updating Network Security Rule “nsr-sbox-dd-fed-ddsp-http80” (NSG “module.fico_app_vm.linux_vm_nsg” / Resource Group “rg-dwp-sbox-dd-fed-ddsp-app”): network.SecurityRulesClient#CreateOrUpdate: Failure sending request: StatusCode=404 – Original Error: Code=“ResourceNotFound” Message="The Resource ‘Microsoft.Network/networkSecurityGroups/module.fico_app_vm.linux_vm_nsg’ under resource group ‘rg-dwp-sbox-dd-fed-ddsp-app’ was not found. For more details please go to https://aka.ms/ARMResourceNotFoundFix"
on main.tf line 58, in resource “azurerm_network_security_rule” “fico-app-sr-80”:
58: resource “azurerm_network_security_rule” “fico-app-sr-80” {
I have checked in the Azure Console that the NSG has been created in the correct resource group, I believe the module output isn’t being populated, probably passing it as a literal string due to the double quotes I used to get around the type error.
I have included my tf files below to help debug. Please let me know if there is any other information I should provide.
> root module .tfvars:
**
app_servers ={
app-1 = {
size = “Standard_E2s_v3”
admin_username = “azureuser”
public_key = “XXX”
disks = [32, 32]
zone_vm = “1”
zone_disk = [“1”]
}
}
root module main.tf:
module "fico_app_vm" { for_each = var.app_servers source = "../modules/compute/linux_vm" source_image_id = var.app_image_id location = var.location vm_name = each.key vm_identifier = "${var.vm_identifier}${var.instance_number}" vm = each.value disks = each.value["disks"] resource_group = azurerm_resource_group.rg_dwp_fico_app.name directorate = var.directorate business_unit = var.business_unit environment = var.environment network_rg_identifier = var.network_rg_identifier subnet_name = "sub-dwp-${var.environment}-${var.directorate}-${var.business_unit}-be01" diag_storage_account_name = var.diag_storage_account_name ansible_storage_account_name = var.ansible_storage_account_name ansible_storage_account_key = var.ansible_storage_account_key log_analytics_workspace_name = var.log_analytics_workspace_name backup_policy_name = var.backup_policy_name enable_management_locks = true }
root level variables.tf:
variable “app_servers” {
description = “Variable for defining each instance”
type = map(object({
size = string
admin_username = string
public_key = string
disks = list(number)
zone_vm = string
zone_disk = list(string)
}))
}
child module main.tf:
resource “azurerm_network_security_group” “dwp_network_security_group” {
name = “nsg-{var.environment}-{var.directorate}-{var.business_unit}-{var.vm_identifier}-${var.vm_name}”
resource_group_name = var.resource_group
location = var.location
}
child module outputs.tf:
output “linux_vm_nsg” {
value = azurerm_network_security_group.dwp_network_security_group.name
}
root module main.tf (trying to reference child module output to set NSG rules):
resource “azurerm_network_security_rule” “fico-app-sr-80” {
name = “nsr-{var.environment}-{var.directorate}-{var.business_unit}-{var.vm_identifier}${var.instance_number}-http80”
priority = 100
direction = “Inbound”
access = “Allow”
protocol = “"
source_port_range = "”
destination_port_range = “80”
source_address_prefixes = [“module.fico_web_vm.linux_vm_ips”]
destination_address_prefix = “VirtualNetwork”
resource_group_name = “azurerm_resource_group.rg_dwp_fico_app.name”
network_security_group_name = module.fico_app_vm.linux_vm_nsg
}