chew224
chew224

Reputation: 501

Retrieve Azure VNET subnet IDs with Terraform

I want to retrieve/pull the subnet IDs from an existing VNET in Azure using the azurerm_virtual_network data source. My code below is not working as expected. Any help is appreciated.

data "azurerm_virtual_network" "vnet" {
  name                 = "my-vnet"
  resource_group_name  = "my-resource-group"
}

output "my-subnets-ids" {
  value = "${data.azurerm_virtual_network.vnet.subnets.id}"
}

I am receiving the following error when I execute.

output.my-subnets: Resource 'data.azurerm_virtual_network.vnet' 
does not have attribute 'subnets.id' for variable
'data.azurerm_virtual_network.vnet.subnets.id'

Upvotes: 5

Views: 22324

Answers (5)

David Sampson
David Sampson

Reputation: 39

If you want to be able to reference the result using the subnet names rather than an arbitrary index you can use the following:

data "azurerm_virtual_network" "vnet_ski_01" {
  name                 = module.vnet_ski_01.name
  resource_group_name  = module.azurerm_resource_group_net_01.name
}

data "azurerm_subnet" "vnet_ski_01_subnets" {
  for_each            = toset(data.azurerm_virtual_network.vnet_ski_01.subnets)
  name                 = each.value
  virtual_network_name = "${data.azurerm_virtual_network.vnet_ski_01.name}"
  resource_group_name  = "${data.azurerm_virtual_network.vnet_ski_01.resource_group_name}"
}

You can then refer to your subnets by name for example (AzureBastionSubnet is the subnet name):

output "subnet_bastion_address_space" {
     value = data.azurerm_subnet.vnet_ski_01_subnets["AzureBastionSubnet"].address_prefix
 }

I used this approach to pass all my subnets into an NSG module so I could reference subnet address spaces in my NSG rules

Upvotes: 4

Jamie
Jamie

Reputation: 3372

I would combine this with the subnet data resource and use it to get all your ids. This code is close, I don't have time to pull it up and work out the full syntax.

data "azurerm_subnet" "test" {
    name                 = "${data.azurerm_virtual_network.vnet.subnets[count.index]}"
    virtual_network_name = "${data.azurerm_virtual_network.vnet.name}"
    resource_group_name  = "${data.azurerm_virtual_network.vnet.resource_group_name}"
    count = "${count(data.azurerm_virtual_network.vnet.subnets)}"
}

 output "subnet_ids" {
     value = "${data.azurerm_subnet.test.*.id}"
 }

Upvotes: 4

SNielsen
SNielsen

Reputation: 13

I've implemented this based on Jamies proposed solution and this code works :)

data "azurerm_subnet" "virtualSubnets1" {
    name                 = data.azurerm_virtual_network.virtualNetwork1.subnets[count.index]
    virtual_network_name = data.azurerm_virtual_network.virtualNetwork1.name
    resource_group_name  = data.azurerm_virtual_network.virtualNetwork1.resource_group_name
    count                = length(data.azurerm_virtual_network.virtualNetwork1.subnets)
}


output "virtualnetwork_subnets_ids" {
  value = data.azurerm_subnet.virtualSubnets1.*.id
}

...and then you can retrieve the subnets using something like this

resource "azurerm_subnet_network_security_group_association" "nsg_mapping1" {
  subnet_id                 = data.terraform_remote_state.networking.outputs.virtualnetwork_subnets_ids[1]
  network_security_group_id = azurerm_network_security_group.nsg.id
}

Upvotes: 1

CuongLc92
CuongLc92

Reputation: 11

You can get it by:

data.azurerm_virtual_network.vnet.subnet.*.id

It will be a list, to get the first member, use:

data.azurerm_virtual_network.virtualNetwork1.subnet.*.id[0]

Upvotes: 1

4c74356b41
4c74356b41

Reputation: 72191

according to this it only contains list of names of the subnets, not their ids, so you would need to construct those manually. easiest way - take vnet.id and add '/subnets/${each subnet name goes here}'

Upvotes: 2

Related Questions