If Azure subnets are created inline as part of the vnet definition, can the subnet ID be extracted directly? Or is some "massaging" required?
I have the following:
module "vnet" {
source = "Azure/avm-res-network-virtualnetwork/azurerm"
version = "0.7.1"
address_space = ["10.10.0.0/16"]
location = uksouth
name = vnet01
resource_group_name = rg-temp
subnets = {
one = {
name = "subnet01"
address_prefixes = ["10.10.1.0/24"]
}
two = {
name = "subnet02"
address_prefixes = ["10.10.2.0/24"]
}
}
}
I am then trying to create a private endpoint in the second subnet
resource "azurerm_private_endpoint" "acr" {
name = "endpoint-acr01"
location = uksouth
resource_group_name = rg-temp
subnet_id = module.vnet.subnets["subnet02"].id
private_service_connection {
name = "psconn-acr01"
private_connection_resource_id = module.acr.acr_id.id
is_manual_connection = false
subresource_names = ["registry"]
}
}
But this throws the error:
module.vnet.subnets["subnet02"] is object with 4 attributes
This object does not have an attribute named "id".
Is the subnet id directly accessible in this way? Or do I need to do something "funky" to extract it?
You are using a module that wraps the provider's resource types, so this is really a question about that module rather than about Terraform or the hashicorp/azurerm
provider.
At the time of writing the module's subnets
output value is defined like this:
output "subnets" {
description = <<DESCRIPTION
Information about the subnets created in the module.
Please refer to the subnet module documentation for details of the outputs.
DESCRIPTION
value = module.subnet
}
...and so it's really just passing on verbatim the value produce by a nested module call.
That module call is, at the time of writing, a call into the ./modules/subnet
directory using for_each
, and so from that we can at least conclude that the top-level subnets
output value is a mapping with the same keys as you passed in to the subnets
input variable: subnet01
and subnet02
.
The elements of that mapping are also definitely objects because a module call always produces an object. But what attributes those objects have depends on how that nested module is defined.
At the time of writing the nested module defines the following output values:
output "application_gateway_ip_configuration_resource_id" {
description = "The application gateway ip configurations resource id."
value = try(azapi_resource.subnet.body.properties.applicationGatewayIPConfigurations.id, null)
}
output "name" {
description = "The resource name of the subnet."
value = azapi_resource.subnet.name
}
output "resource" {
description = "All attributes of the subnet"
value = azapi_resource.subnet
}
output "resource_id" {
description = "The resource ID of the subnet."
value = azapi_resource.subnet.id
}
Therefore those are the only valid attribute names that you can write after module.vnet.subnets["subnet02"]
with the current version of this module.
It seems like resource_id
holds the value you want -- the subnet's ID -- so you can write that as module.vnet.subnets["subnet02"].resource_id
.
The module is also exporting the entire object representing the subnet as the resource
attribute, and so you can access anything documented as a result of azapi_resource
as a nested attribute under that attribute. That resource type's id
attribute is exported as module.vnet.subnets["subnet02"].resource.id
, for example, although of course that's redundant with the resource_id
output value that I mentioned in the previous paragraph.