Reputation: 53
I am using terraform version 0.14.3. I have a module for creating an Azure Network Interface Card, as below:
resource "azurerm_network_interface" "nic" {
name = var.nic_name
location = var.location
resource_group_name = var.rg_name
ip_configuration {
name = var.ipconfig_name
subnet_id = var.subnet_id
private_ip_address_allocation = "Dynamic"
}
}
Its output is defined as :
output "nic_id" {
value = azurerm_network_interface.nic.id
}
I am calling this module in this parent module:
module "NIC" {
source = "./NIC"
for_each = var.nics
nic_name = each.value.nic_name
location = "eastus2"
rg_name = "abc-test-rg"
ipconfig_name = each.value.ipconfig_name
subnet_id = <subnet_id>
}
output "nic_ids" {
value = [for k in module.NIC.nic_id : k.id]
}
The NIC values are defined as below:
nics = {
nic1 = {
nic_name = "abc-nic-1"
ipconfig_name = "nic-1-ipconfig"
}
}
I want to loop around the NIC output IDs, and want them displayed. When I run above code, I get below error in terraform plan :
Error: Unsupported attribute
on main.tf line 15, in output "nic_ids":
15: value = [for k in module.NIC.nic_id : k.id]
|----------------
| module.NIC is object with 1 attribute "nic1"
This object does not have an attribute named "nic_id".
How do I get around it ?
Upvotes: 3
Views: 3842
Reputation: 74694
Your module "NIC"
block has for_each
set, and so the module.NIC
symbol elsewhere in the module is a mapping from instance keys to output objects, rather than just a single output object as for a singleton module.
Terraform's error message is attempting to draw attention to that with the following message:
module.NIC is object with 1 attribute "nic1"
Notice that nic1
here is a key from your var.nics
, and not one of the output values defined in your module.
Assuming that the nic_id
output you showed here is the only one defined in that module, the module.NIC
value would be shaped something like this:
{
nic1 = {
nic_id = "eni-e5aa89a3"
}
}
It sounds like you instead want to produce a value shaped like this:
{
nic1 = "eni-e5aa89a3"
}
If so, a suitable expression to get that result would be the following:
output "nic_ids" {
value = { for k, nic in module.NIC : k => nic.nic_id }
}
The above means: produce a mapping with one element for each instance of the NIC
module, whose key is the module instance key and whose value is the nic_id
output value.
Alternatively, if it doesn't matter which id belongs to which instance then you could produce an unordered set of ids, like this:
output "nic_ids" {
value = toset([for nic in module.NIC : nic.nic_id])
}
In this case the for
expression only defines a local symbol nic
, which represents the module instance object, because it doesn't do anything with the instance key. The toset
here is to represent that the IDs are not in any particular order: that isn't strictly necessary but I think it's a good practice to make sure that any other Terraform code depending on that value doesn't inadvertently depend on the current arbitrary ordering of the ids, which might change in future if you add or remove elements in var.nics
.
Upvotes: 7