Reputation: 93
I want to use ansible task, to create subnets in azure, I have following playbook
---
- hosts: localhost
vars:
"vnets": [
{
"vnet_aks_re1": [
{
"region": "region1",
"resource_group_key": "aks_spoke_re1",
"specialsubnets": [
{
"AzureFirewallSubnet": [
{
"cidr": [
"10.100.83.128/26"
],
"name": "AzureFirewallSubnet"
}
],
"GatewaySubnet": [
{
"cidr": [
"10.100.83.224/27"
],
"name": "GatewaySubnet"
}
]
}
],
"subnets": [
{
"AzureBastionSubnet": [
{
"cidr": [
"10.100.83.32/27"
],
"name": "AzureBastionSubnet",
"nsg_key": "azure_bastion_nsg"
}
],
"aks_ingress": [
{
"cidr": [
"10.100.82.0/24"
],
"name": "aks_ingress",
"nsg_key": "azure_kubernetes_cluster_nsg",
"route_table_key": "default_to_firewall_re1"
}
],
"aks_nodepool_system": [
{
"cidr": [
"10.100.80.0/24"
],
"name": "aks_nodepool_system",
"nsg_key": "azure_kubernetes_cluster_nsg",
"route_table_key": "default_to_firewall_re1"
}
],
"aks_nodepool_user1": [
{
"cidr": [
"10.100.81.0/24"
],
"name": "aks_nodepool_user1",
"nsg_key": "azure_kubernetes_cluster_nsg",
"route_table_key": "default_to_firewall_re1"
}
],
"application_gateway": [
{
"cidr": [
"10.100.83.96/27"
],
"name": "agw",
"nsg_key": "application_gateway"
}
],
"jumpbox": [
{
"cidr": [
"10.100.83.64/28"
],
"name": "jumpbox",
"nsg_key": "azure_kubernetes_cluster_nsg",
"route_table_key": "default_to_firewall_re1"
}
],
"private_endpoints": [
{
"cidr": [
"10.100.83.0/27"
],
"enforce_private_link_endpoint_network_policies": true,
"name": "private_endpoints"
}
]
}
],
"vnet": [
{
"address_space": [
"10.100.80.0/22"
],
"name": "aks"
}
]
}
],
"vnet_hub_re1": [
{
"region": "region1",
"resource_group_key": "vnet_hub_re1",
"specialsubnets": [
{
"AzureFirewallSubnet": [
{
"cidr": [
"100.64.101.0/26"
],
"name": "AzureFirewallSubnet"
}
],
"GatewaySubnet": [
{
"cidr": [
"100.64.100.0/27"
],
"name": "GatewaySubnet"
}
]
}
],
"subnets": [
{
"AzureBastionSubnet": [
{
"cidr": [
"100.64.101.64/26"
],
"name": "AzureBastionSubnet",
"nsg_key": "azure_bastion_nsg"
}
],
"jumpbox": [
{
"cidr": [
"100.64.102.0/27"
],
"name": "jumpbox",
"nsg_key": "jumpbox"
}
],
"private_endpoints": [
{
"cidr": [
"100.64.103.128/25"
],
"enforce_private_link_endpoint_network_policies": true,
"name": "private_endpoints"
}
]
}
],
"vnet": [
{
"address_space": [
"100.64.100.0/22"
],
"name": "vnet_hub_re1"
}
]
}
]
}
]
tasks:
- name: Dbg variable
debug:
msg: |
Debug:
--------------------------------
Items: {{ item }}
================================
with_items:
- "{{ vnets[0] | dict2items | json_query('[].value|[*]|[].subnets') }}"
# this would be expected result
- name: Create a subnet
azure_rm_subnet:
resource_group: "{{ item.resource_group_key }}"
virtual_network_name: "{{ item.vnet[0].name }}"
name: "{{ combine(item.subnets[*].name, item.specialsubnets[*].name }}"
address_prefix_cidr: "{{ combine(item.subnets[*].cidr, item.specialsubnets[*].cidr }}"
with_items:
- "{{ vnets[0] | dict2items | json_query('[].value|[*]') }}"
In JSON variable vnet and subnet keys can have any value, so I can not access them by name, but use * to iterate through all of them. Meanwhile subnets, vnets and specialsubnets are fixed names.
To create and azure subnet I need not only content of subnets and specialsubnets, but also region and resource_group_key from the same level.
I could not find a way how to iterate through all elements of subnets and specialsubnets, using with_items, there are always two items printed, no meter what I put in json_query.
Expected result would be that loop creates 13 subnets
# Hub VNET with 5 subnets
- name: Create a subnet
azure_rm_subnet:
resource_group: "vnet_hub_re1"
virtual_network_name: "vnet_hub_re1"
name: "GatewaySubnet"
address_prefix_cidr: "["100.64.100.0/27"]"
- name: Create a subnet
azure_rm_subnet:
resource_group: "vnet_hub_re1"
virtual_network_name: "vnet_hub_re1"
name: "AzureFirewallSubnet"
address_prefix_cidr: "["100.64.101.0/26"]"
- name: Create a subnet
azure_rm_subnet:
resource_group: "vnet_hub_re1"
virtual_network_name: "vnet_hub_re1"
name: "AzureBastionSubnet"
address_prefix_cidr: "["100.64.101.64/26"]"
- name: Create a subnet
azure_rm_subnet:
resource_group: "vnet_hub_re1"
virtual_network_name: "vnet_hub_re1"
name: "jumpbox"
address_prefix_cidr: "["100.64.102.0/27"]"
- name: Create a subnet
azure_rm_subnet:
resource_group: "vnet_hub_re1"
virtual_network_name: "vnet_hub_re1"
name: "private_endpoints"
address_prefix_cidr: "["100.64.103.128/25"]"
# Spoke vnet with 8 subnets
- name: Create a subnet
azure_rm_subnet:
resource_group: "aks_spoke_re1"
virtual_network_name: "aks"
name: "AzureFirewallSubnet"
address_prefix_cidr: "["10.100.83.128/26"]"
- name: Create a subnet
azure_rm_subnet:
resource_group: "aks_spoke_re1"
virtual_network_name: "aks"
name: "GatewaySubnet"
address_prefix_cidr: "["10.100.83.224/27"]"
- name: Create a subnet
azure_rm_subnet:
resource_group: "aks_spoke_re1"
virtual_network_name: "aks"
name: "AzureBastionSubnet"
address_prefix_cidr: "["10.100.83.32/27"]"
- name: Create a subnet
azure_rm_subnet:
resource_group: "aks_spoke_re1"
virtual_network_name: "aks"
name: "aks_ingress"
address_prefix_cidr: "["10.100.82.0/24"]"
- name: Create a subnet
azure_rm_subnet:
resource_group: "aks_spoke_re1"
virtual_network_name: "aks"
name: "aks_nodepool_system"
address_prefix_cidr: "["10.100.80.0/24"]"
- name: Create a subnet
azure_rm_subnet:
resource_group: "aks_spoke_re1"
virtual_network_name: "aks"
name: "aks_nodepool_user1"
address_prefix_cidr: "["10.100.81.0/24"]"
- name: Create a subnet
azure_rm_subnet:
resource_group: "aks_spoke_re1"
virtual_network_name: "aks"
name: "agw"
address_prefix_cidr: "["10.100.83.96/27"]"
- name: Create a subnet
azure_rm_subnet:
resource_group: "aks_spoke_re1"
virtual_network_name: "aks"
name: "jumpbox"
address_prefix_cidr: "["10.100.83.64/28"]"
- name: Create a subnet
azure_rm_subnet:
resource_group: "aks_spoke_re1"
virtual_network_name: "aks"
name: "private_endpoints"
address_prefix_cidr: "["10.100.83.0/27"]"
Upvotes: 1
Views: 402
Reputation: 17007
when i have complex things to do with a file, iprefer to use a custom filter:
you create a folder filter_plugins in your playbook folder (i have named the file myfilters.py and the filter custom)
myfilters.py in folder filter_plugins:
#!/usr/bin/python
class FilterModule(object):
def filters(self):
return {
'custom': self.custom
}
def trapvalues(self, items, vnet):
result = []
virtual_network_name = vnet['vnet'][0]['name']
resource_group = vnet['resource_group_key']
for item in items:
address_prefix_cidr = items[item][0]['cidr']
name = items[item][0]['name']
result.append({'resource_group': resource_group,
'virtual_network_name': virtual_network_name,
'name': name,
'address_prefix_cidr': address_prefix_cidr})
return result
def custom(self, vnets):
result = []
for it in vnets:
special = self.trapvalues(vnets[it][0]['specialsubnets'][0], vnets[it][0])
result.append(special)
sub = self.trapvalues(vnets[it][0]['subnets'][0], vnets[it][0])
result.append(sub)
#print(result)
return result
and you call the custom filter in task:
tasks:
- name: create variable
set_fact:
result: "{{ vnets[0] | custom }}"
result displayed: its a list so you could iterate over easily...
"result": [
[
{
"address_prefix_cidr": [
"10.100.83.128/26"
],
"name": "AzureFirewallSubnet",
"resource_group": "aks_spoke_re1",
"virtual_network_name": "aks"
},
{
"address_prefix_cidr": [
"10.100.83.224/27"
],
"name": "GatewaySubnet",
"resource_group": "aks_spoke_re1",
"virtual_network_name": "aks"
}
],
[
{
"address_prefix_cidr": [
"10.100.83.32/27"
],
"name": "AzureBastionSubnet",
"resource_group": "aks_spoke_re1",
"virtual_network_name": "aks"
},
{
"address_prefix_cidr": [
"10.100.82.0/24"
],
"name": "aks_ingress",
"resource_group": "aks_spoke_re1",
"virtual_network_name": "aks"
},
{
"address_prefix_cidr": [
"10.100.80.0/24"
],
"name": "aks_nodepool_system",
"resource_group": "aks_spoke_re1",
"virtual_network_name": "aks"
},
{
"address_prefix_cidr": [
"10.100.81.0/24"
],
"name": "aks_nodepool_user1",
"resource_group": "aks_spoke_re1",
"virtual_network_name": "aks"
},
{
"address_prefix_cidr": [
"10.100.83.96/27"
],
"name": "agw",
"resource_group": "aks_spoke_re1",
"virtual_network_name": "aks"
},
{
"address_prefix_cidr": [
"10.100.83.64/28"
],
"name": "jumpbox",
"resource_group": "aks_spoke_re1",
"virtual_network_name": "aks"
},
{
"address_prefix_cidr": [
"10.100.83.0/27"
],
"name": "private_endpoints",
"resource_group": "aks_spoke_re1",
"virtual_network_name": "aks"
}
],
[
{
"address_prefix_cidr": [
"100.64.101.0/26"
],
"name": "AzureFirewallSubnet",
"resource_group": "vnet_hub_re1",
"virtual_network_name": "vnet_hub_re1"
},
{
"address_prefix_cidr": [
"100.64.100.0/27"
],
"name": "GatewaySubnet",
"resource_group": "vnet_hub_re1",
"virtual_network_name": "vnet_hub_re1"
}
],
[
{
"address_prefix_cidr": [
"100.64.101.64/26"
],
"name": "AzureBastionSubnet",
"resource_group": "vnet_hub_re1",
"virtual_network_name": "vnet_hub_re1"
},
{
"address_prefix_cidr": [
"100.64.102.0/27"
],
"name": "jumpbox",
"resource_group": "vnet_hub_re1",
"virtual_network_name": "vnet_hub_re1"
},
{
"address_prefix_cidr": [
"100.64.103.128/25"
],
"name": "private_endpoints",
"resource_group": "vnet_hub_re1",
"virtual_network_name": "vnet_hub_re1"
}
]
]
Upvotes: 1
Reputation: 68034
Q: "Iterate through all elements of subnets and specialsubnets."
A: Select the lists, e.g.
_subnets: "{{ vnets|json_query('[].*[][].subnets') }}"
_specialsubnets: "{{ vnets|json_query('[].*[][].specialsubnets') }}"
and iterate them, e.g.
- debug:
msg: "{{ item.AzureBastionSubnet.0.cidr.0 }}"
loop: "{{ _subnets|flatten }}"
gives
msg: 10.100.83.32/27
msg: 100.64.101.64/26
and
- debug:
msg: "{{ item.AzureFirewallSubnet.0.cidr.0 }}"
loop: "{{ _specialsubnets|flatten }}"
gives
msg: 10.100.83.128/26
msg: 100.64.101.0/26
Upvotes: 0