Open johnastiles opened 2 years ago
+1
I have the same problem here!
Managed to bypass this issue by below 'hack' that is exploiting the fact that backend_address_pool id (as many other azure resources) is constructed/consists backend's pool name:
resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "example" {
network_interface_id = azurerm_network_interface.example.id
ip_configuration_name = "testconfiguration1"
backend_address_pool_id = [for value in tolist(azurerm_application_gateway.network.backend_address_pool.*.id) : value if length(regexall(lower(local.backend_address_pool_name), value)) > 0][0]
}
Above code uses conditional for expression that iterates through list of backend_addres_pool id's (created with usage of splat operator) and assigns value of the only element that contains backend_addres_pool_name (used lenght(regexall(...))
to check that)
Not ideal, not clean, but working for me...
Same here.
The solution above works but it takes a long time to create.
@Loth4r do you have the same problem?
Same here.
The solution above works but it takes a long time to create.
@Loth4r do you have the same problem?
No such issue on my end.
Replicated the Cannot index a set value
issue both 3.3.0 and 3.10.0 of hashicorp/azurerm
. Workaround appears to work but I don't know about the speed yet
In 3.11.0 they updated the documentation as stated below:
resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "example" {
network_interface_id = azurerm_network_interface.example.id
ip_configuration_name = "testconfiguration1"
backend_address_pool_id = tolist(azurerm_application_gateway.network.backend_address_pool).0.id
}
In 3.11.0 they updated the documentation as stated below:
resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "example" { network_interface_id = azurerm_network_interface.example.id ip_configuration_name = "testconfiguration1" backend_address_pool_id = tolist(azurerm_application_gateway.network.backend_address_pool).0.id }
Above will most likely work, but in scenario where you have only one backend_address_pool defined on your app gateway. If you have more then in my opinion it can lead to some random results as tolist() function on a set does not guarantee order:
Pass a set value to tolist to convert it to a list. Since set elements are not ordered, the resulting list will have an undefined order that will be consistent within a particular run of Terraform.
see (https://www.terraform.io/language/functions/tolist)
What could improve setting up backend_addres_pool association here would be reconsidering how azurerm_application_gateway component should be exporting backend_address_pool block. Currently it is exporting list of backend_address_pool as follows:
A backend_address_pool block exports the following:
id - The ID of the Backend Address Pool.
Maybe changing type to map that has a name of backend address pool as a key would do the trick? Then it could look more like below:
resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "example" {
network_interface_id = azurerm_network_interface.example.id
ip_configuration_name = "testconfiguration1"
backend_address_pool_id = azurerm_application_gateway.network.backend_address_pool[<backend_pool_name>].id
}
Neither solutions is working for me:
│ Error: Incorrect attribute value type
│
│ on vmss.tf line 58, in resource "azurerm_linux_virtual_machine_scale_set" "vmss":
│ 58: application_gateway_backend_address_pool_ids = [for value in tolist(azurerm_application_gateway.network.backend_address_pool.*.id) : value if length(regexall(lower(local.backend_address_pool_name), value)) > 0][0]
│ ├────────────────
│ │ azurerm_application_gateway.network.backend_address_pool is set of object with 1 element
│ │ local.backend_address_pool_name is "vmss-vnet-beap"
│
│ Inappropriate value for attribute "application_gateway_backend_address_pool_ids": set of string required.
│ Error: Incorrect attribute value type
│
│ on vmss.tf line 58, in resource "azurerm_linux_virtual_machine_scale_set" "vmss":
│ 58: application_gateway_backend_address_pool_ids = tolist(azurerm_application_gateway.network.backend_address_pool).0.id
│ ├────────────────
│ │ azurerm_application_gateway.network.backend_address_pool is set of object with 1 element
│
│ Inappropriate value for attribute "application_gateway_backend_address_pool_ids": set of string required.
However, it works if I use:
application_gateway_backend_address_pool_ids = azurerm_application_gateway.network.backend_address_pool.*.id
We ran into the ordering issue with tolist(). In order to get around it we created a local variable. backend_nics was the output of the VM NICs we wanted in or backend pool.
locals { be_to_nic = flatten([for k in tolist(azurerm_application_gateway.app_gateway.backend_address_pool).*.id : [ for l, w in var.backend_nics : { backend_pool_id = k nic_id = w.id nic_ipconfig_name = w.ip_configuration[0].name } ] ]) }
Then in the terraform we did this.
resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "nic_app_be_association" { for_each = tomap({ for k in local.be_to_nic : "${k.backend_pool_id}${k.nic_id}" => k }) network_interface_id = each.value.nic_id ip_configuration_name = each.value.nic_ipconfig_name backend_address_pool_id = each.value.backend_pool_id }
There may be a better way, but this worked for us.
encountered this too. this workaround suggested above worked.
tolist(azurerm_application_gateway.network.backend_address_pool).0.id
You can use one function from terraform as below:
resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "nic-assoc" { backend_address_pool_id = one(azurerm_application_gateway.aggateway.backend_address_pool).id ip_configuration_name = "web-linuxvm-ipconfig" network_interface_id = azurerm_network_interface.web_linuxvm_nic.id }
@devanshujoshi139 that only works if there's a single backend address pool. As soon as there are more, that will fail.
@GeoffCraigVRU it's probably relevant that the backend address pool ID's are easy to predict. In my case, it was a lot easier to just do this:
resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "nic1" {
backend_address_pool_id = "${azurerm_application_gateway.this.id}/backendAddressPools/bapName"
ip_configuration_name = "ipConfigName"
network_interface_id = azurerm_network_interface.vm1nic1.id
}
Ideally, even though the Azure API returns the data in an unordered list (which is why the backend_address_pools
attribute is a set
) the AzureRM provider would be able to intelligently make it findable by name since it stores it as a hash (apparently) which won't change no matter what order things come out of the API in and it would be easy to parse the name off the end of those identifiers. I'm sure there's a reason they haven't done this, but a little sprinkle of syntactic sugar might be nice.
Is there an existing issue for this?
Community Note
Terraform Version
1.1.9
AzureRM Provider Version
3.6.0
Affected Resource(s)/Data Source(s)
azurerm_network_interface_application_gateway_backend_address_pool_association
Terraform Configuration Files
Debug Output/Panic Output
Expected Behaviour
Application Gateway backend pool association should be made with the virtual machine nic.
Actual Behaviour
States that backend_address_pool does not have addressable keys.
Steps to Reproduce
Terraform plan
Important Factoids
This worked as expected in Azure Provider 2.99.0
References
https://github.com/MicrosoftDocs/azure-dev-docs/issues/770 https://github.com/MicrosoftDocs/azure-dev-docs/issues/752