Open davejdeemer opened 2 years ago
Any thoughts about this? Is there additional information that I can provide to help describe what I'm running into?
@davejdeemer I'm sorry, but I'm really confused by your above information. The value defined by your Playbook is “"route_table": "/ subscriptions/dde8 / resourceGroups/rg-subnet/providers/Microsoft.Net work/routeTables/rt - northcentralus - 1", But the result of the update is "id": "/ subscriptions/c123 / resourceGroups/rg-subnet/providers/Microsoft.Net work/routeTables/rt - northcentralus - NPD - 1", Have you mixed up the information? Thank you very much!
@Fred-sun Appreciate you taking a look at this, thank you!
That is the challenge I've bumped into. The invocation uses the expected subscription id (dde8**) yet the state is actually using the subscription id defined from within my credentials file (c123). As a test, changing my credentials file to specify the subscription id of dde8 will result in the state reflecting subscription id dde8**. This is a challenge because we are operating across multiple subscriptions. Does that help clarify?
@davejdeemer I tested it again locally, but still could not reproduce your problem. The most important thing is that the routing table associated with the subnet must be from the same subscription, thank you!
I'll dig around more on my side. Both a co-worker and I have bumped into this but maybe I've got something not quite right with the code, the example or both.
@Fred-sun An interesting item that I observed is that setting the subscription_id for the route table dict in the example vNet group vars, then building the subnet yields the expected behavior in using the expected subscription_id rather then using what is defined in the credentials file. Here is an update to the example:
---
vnets:
- name: vnet-northcentralus-1
region: northcentralus
subscription: MY-SUBCRIPTION
resource_group: rg-subnet
address_space:
- "xx.xxx.xx.x/25"
subnets:
- name: subnet-northcentralus-1
address_space: "xx.xxx.xx.x/25"
private_endpoint_network_policies: Disabled
route_table:
name: rt-northcentralus-1
resource_group: rg-subnet
subscription_id: dde8**** <<--- New; added as part of the routing table config
In the collection documentation it doesn't mention the dict can (perhaps should?) contain the subscription_id. When supplied, the invocation results in the expected output. Otherwise, the route table will reference the subscription_id defined within the credentials file.
Here's the output from running the example with that modification:
ok: [azure-sbx] => (item=[{'name': 'vnet-northcentralus-1', 'region': 'northcentralus', 'subscription': 'MY-SUBSCRIPTION', 'resource_group': 'rg-subnet', 'address_space': ['xx.xxx.xx.x/26'], 'peered_to_core': True, 'subnets': [{'name': 'subnet-northcentralus-1', 'address_space': 'xx.xxx.xx.x/26', 'private_endpoint_network_policies': 'Disabled', 'route_table': {'name': 'rt-northcentralus-1', 'resource_group': 'rg-subnet', 'subscription_id': 'dde8****'}}]}, {'name': 'subnet-northcentralus-1', 'address_space': 'xx.xxx.xx.x/26', 'private_endpoint_network_policies': 'Disabled', 'route_table': {'name': 'rt-northcentralus-1', 'resource_group': 'rg-subnet', 'subscription_id': 'dde8****'}}]) => {
"ansible_loop_var": "item",
"changed": false,
"invocation": {
"module_args": {
"ad_user": null,
"address_prefix_cidr": "xx.xxx.xx.x/26",
"address_prefixes_cidr": null,
"adfs_authority_url": null,
"api_profile": "latest",
"auth_source": "auto",
"cert_validation_mode": null,
"client_id": null,
"cloud_environment": "AzureCloud",
"delegations": null,
"log_mode": null,
"log_path": null,
"name": "subnet-northcentralus-1",
"password": null,
"private_endpoint_network_policies": "Disabled",
"private_link_service_network_policies": "Enabled",
"profile": null,
"resource_group": "rg-subnet",
"route_table": {
"name": "rt-northcentralus-1",
"resource_group": "rg-subnetworking",
"subscription_id": "dde8****"
},
"secret": null,
"security_group": null,
"service_endpoints": null,
"state": "present",
"subscription_id": "dde8****",
"tenant": null,
"virtual_network_name": "vnet-northcentralus-1"
}
},
"item": [
{
"address_space": [
"xx.xxx.xx.x/26"
],
"name": "vnet-northcentralus-1",
"peered_to_core": true,
"region": "northcentralus",
"resource_group": "rg-subnet",
"subnets": [
{
"address_space": "xx.xxx.xx.x/26",
"name": "subnet-northcentralus-1",
"private_endpoint_network_policies": "Disabled",
"route_table": {
"name": "rt-northcentralus-1",
"resource_group": "rg-subnet",
"subscription_id": "dde8****"
}
}
],
"subscription": "MY-SUBSCRPTION"
},
{
"address_space": "xx.xxx.xx.x/26",
"name": "subnet-northcentralus-1",
"private_endpoint_network_policies": "Disabled",
"route_table": {
"name": "rt-northcentralus-1",
"resource_group": "rg-subnet",
"subscription_id": "dde8****"
}
}
],
"state": {
"address_prefix": "xx.xxx.xx.x/26",
"address_prefixes": null,
"id": "/subscriptions/dde8****/resourceGroups/rg-subnet/providers/Microsoft.Network/virtualNetworks/vnet-northcentralus-1/subnets/subnet-northcentralus-1",
"name": "subnet-northcentralus1",
"network_security_group": {},
"private_endpoint_network_policies": "Disabled",
"private_link_service_network_policies": "Enabled",
"provisioning_state": "Succeeded",
"route_table": {
"id": "/subscriptions/dde8****/resourceGroups/rg-subnet/providers/Microsoft.Network/routeTables/rt-northcentralus-1",
"name": "rt-northcentralus-1",
"resource_group": "rg-subnet"
}
}
}
Note the change in result for invocation; specifically the route_table -> id. Now it correctly references the expected subscription_id of dde8****
.
I understand you are not seeing the same behavior in your tests. A co-worker of mine runs into the same thing I am describing, perhaps it's something within our environment or a nuance with the test case as described. Hopefully the observation noted above will help.
Updated "build subnets" task (the original example was altered during testing of this case):
- name: Build subnets
azure.azcollection.azure_rm_subnet:
address_prefix_cidr: "{{ item.1['address_space'] }}"
name: "{{ item.1['name'] }}"
private_endpoint_network_policies: "{{ item.1['private_endpoint_network_policies'] }}"
resource_group: "{{ item.0['resource_group'] }}"
route_table: "{{ item.1['route_table'] }}"
subscription_id: "{{ subscription_map[item.0['subscription']] }}"
virtual_network_name: "{{ item.0['name'] }}"
loop: "{{ vnets|subelements('subnets') }}"
It appears that when no subscription_id is provided for for the route_table dict, the module will use the subscription_id provided in the credential file.
@davejdeemer Although you can specify subscription_id, subnets under different subs cannot be directly associated with routing tables. Thanks!
"Error creating or updating subnet foobar - (LinkedAuthorizationFailed) The client has permission to perform action 'Microsoft.Network/routeTables/join/action' on scope '/subscriptions/xxxxxxxx/resourceGroups/v-xisuRG01/providers/Microsoft.Network/virtualNetworks/My_Virtual_Network07/subnets/foobar', however the current tenant 'yyyyyyyy' is not authorized to access linked subscription 'zzzzzzzzzzz'.\nCode: LinkedAuthorizationFailed\nMessage: The client has permission to perform action 'Microsoft.Network/routeTables/join/action' on scope '/subscriptions/xxxxxxxxxxxx/resourceGroups/v-xisuRG01/providers/Microsoft.Network/virtualNetworks/My_Virtual_Network07/subnets/foobar7', however the current tenant 'yyyyyyyyyyy' is not authorized to access linked subscription 'zzzzzzzzzzzzzz'.
@Fred-sun Understood. The interesting thing is that the subscription_id defined for the subnet isn't being used for the route table reference in this case. Instead, it is using the subscription_id defined within the credentials file. When explicitly setting the subscription_id in the route-table dict (duplicating the subscription set for the subnet), the route-table reference is as expected.
Here are a few observations from the code:
Hi,
Do you know if this bug has been fixed? I'm runnig into the same problem:
Thanks for your help.
fatal: [localhost]: FAILED! => { "changed": false, "invocation": { "module_args": { "ad_user": null, "address_prefix": "192.168.100.0/24", "address_prefix_cidr": "192.168.100.0/24", "address_prefixes_cidr": null, "adfs_authority_url": null, "api_profile": "latest", "auth_source": "auto", "cert_validation_mode": null, "client_id": null, "cloud_environment": "AzureCloud", "delegations": null, "disable_instance_discovery": false, "log_mode": null, "log_path": null, "name": "subProdeastus-Test-Networking01", "nat_gateway": null, "password": null, "private_endpoint_network_policies": "Enabled", "private_link_service_network_policies": "Enabled", "profile": null, "resource_group": "rgProdeastus-Test-Networking01", "route_table": "/subscriptions/ef94xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/resourceGroups/rgProdeastus-Test-Networking01/providers/Microsoft.Network/routeTables/rtProdeastus-Test-Networking01", "secret": null, "security_group": null, "service_endpoints": null, "state": "present", "subscription_id": "ef94xxxxxxxxxxxxxxxxxxxxxxxxxxx", "tenant": null, "thumbprint": null, "virtual_network": "vnProdeastus-Test-Networking01", "virtual_network_name": "vnProdeastus-Test-Networking01", "x509_certificate_path": null } }, "msg": "Error creating or updating subnet subProdeastus-Test-Networking01 - (InvalidResourceReference) Resource /subscriptions/ca81180xxxxxxxxxxxxxxxxxxxxxxxxxxx/resourceGroups/RGPRODEASTUS-TEST-NETWORKING01/providers/Microsoft.Network/routeTables/RTPRODEASTUS-TEST-NETWORKING01 referenced by resource /subscriptions/ef94bbd9-34e4-4b85-b4bc-b40d07d3791f/resourceGroups/rgProdeastus-Test-Networking01/providers/Microsoft.Network/virtualNetworks/vnProdeastus-Test-Networking01/subnets/subProdeastus-Test-Networking01 was not found. Please make sure that the referenced resource exists, and that both resources are in the same region.\nCode: InvalidResourceReference\nMessage: Resource /subscriptions/ca81180xxxxxxxxxxxxxxxxxxxxxxxxxxx/resourceGroups/RGPRODEASTUS-TEST-NETWORKING01/providers/Microsoft.Network/routeTables/RTPRODEASTUS-TEST-NETWORKING01 referenced by resource /subscriptions/ef94bbd9-34e4-4b85-b4bc-b40d07d3791f/resourceGroups/rgProdeastus-Test-Networking01/providers/Microsoft.Network/virtualNetworks/vnProdeastus-Test-Networking01/subnets/subProdeastus-Test-Networking01 was not found. Please make sure that the referenced resource exists, and that both resources are in the same region.\nException Details:\t(NotFound) Resource /subscriptions/ca81180xxxxxxxxxxxxxxxxxxxxxxxxxxx/resourceGroups/RGPRODEASTUS-TEST-NETWORKING01/providers/Microsoft.Network/routeTables/RTPRODEASTUS-TEST-NETWORKING01 not found.\n\tCode: NotFound\n\tMessage: Resource /subscriptions/ca81180xxxxxxxxxxxxxxxxxxxxxxxxxxx/resourceGroups/RGPRODEASTUS-TEST-NETWORKING01/providers/Microsoft.Network/routeTables/RTPRODEASTUS-TEST-NETWORKING01 not found." }
Thanks
SUMMARY
When building/updating subnets, the route_table parameter is not using the value given for the subscription_id. Instead, the subscription_id provided in the credentials file is used (as observed by the state change after apply).
ISSUE TYPE
COMPONENT NAME
azure.azcollection.azure_rm_subnet
ANSIBLE VERSION
COLLECTION VERSION
CONFIGURATION
OS / ENVIRONMENT
Micorsoft Azure
STEPS TO REPRODUCE
AZURE_PROFILE=default
Resource groups sample group vars
vNet sample group vars
Inventory hosts
Playbook
Stub credentials file
Run command
ansible-playbook -C site.yaml --limit nonprod -i hosts -vvv
EXPECTED RESULTS
Given that the subnet exists in our Azure tenant, expected result is no change when applying the Ansible playbook.
ACTUAL RESULTS
Apply of ansible playbook flags a change for the "Build subnets" task. Review of the -vvv output, the invocation shows that the route_table resourceID, specifically the subscription_id, is as expected. Yet review of the state shows that the route_table reference is using the subscription_id defined within the credentials file and not what was gathered in the first task of the playbook.
Subscription info from the first playbook task: "Get subscription facts for all rg subscriptions"
Subnet task invocation and state (-vvv output)
Unexpected result is here where the ID should be
dde8****
for the target subscription but instead isc123****
from the credentials file:As a test, update of the credentials file specifying the target subscription yields the expected results in the example above.