title: Ansible loops and Azure resource dependencies
body: <p>I'm using Ansible to provision resources to Azure. I'd like to have one task for each type of resource I want to deploy to Azure which loops through a list of dictionaries, so I can just add more dicts in case I want more resources provisioned. I'd like to define each resource variable only once.</p>
  
  <p>The problem that arises with this is dependencies to other resources. Resource groups need to be provisioned before virtual networks, virtual networks before subnets and so on. Yet the information of the top level resources is still needed when provisioning the bottom level ones.</p>
  
  <p>Here's the first attempt, with all of the required top level resource vars defined in the bottom level resource vars as well:</p>
  
  <pre><code>- hosts: localhost
    connection: local
    vars:
  
      resourcegroups:
      - name: "eh_test_rg01"
        location: "westeurope"
  
      - name: "eh_test_rg02"
        location: "eastus"
  
     virtualnetworks:
     - name: "eh_test_vn01"
       cidr: 10.15.0.0/22
       resource_group: "eh_test_rg01"
  
     - name: "eh_test_vn02"
       cidr: 10.15.4.0/22
       resource_group: "eh_test_rg02"
  
      DMZ_subnets:
      - name: "eh_test_dmzsn01"
        cidr: 10.15.1.0/24
        vnet: "eh_test_vn01"
        location: "westeurope"
        resource_group: "eh_test_rg01"
  
      - name: "eh_test_dmzsn02"
        cidr: 10.15.5.0/24
        vnet: "eh_test_vn02"
        location: "eastus"
        resource_group: "eh_test_rg02"
  
      app_subnets:
      - name: "eh_test_appsn01"
        cidr: 10.15.2.0/24
        vnet: "eh_test_vn01"
        location: "westeurope"
        resource_group: "eh_test_rg01"
  
      - name: "eh_test_appsn02"
        cidr: 10.15.6.0/24
        vnet: "eh_test_vn02"
        location: "eastus"
        resource_group: "eh_test_rg02"
  
      gateway_subnets:
      - name: "GatewaySubnet"
        cidr: 10.15.0.0/24
        vnet: "eh_test_vn01"
        resource_group: "eh_test_rg01"
        location: "westeurope"
  
      - name: "GatewaySubnet"
        cidr: 10.15.4.0/24
        vnet: "eh_test_vn02"
        resource_group: "eh_test_rg02"
        location: "eastus"
  
    tasks:
    - name: Create resource Group
      azure_rm_resourcegroup:
        name: "{{ item.name }}"
        location: "{{ item.location }}"
      with_items:
       - "{{ resourcegroups }}"
      tags: resourcegroups
  
    - name: Create vnet
      azure_rm_virtualnetwork:
        name: "{{ item.name }}"
        resource_group: "{{ item.resource_group }}"
        address_prefixes_cidr: "{{ item.cidr }}"
      with_items:
       - "{{ virtualnetworks }}"
      tags: vnets
  
    - name: Create subnets
      azure_rm_subnet:
        name: "{{ item.name }}"
        resource_group: "{{ item.resource_group }}"
        address_prefix: "{{ item.cidr }}"
        virtual_network: "{{ item.vnet }}"
      with_items:
       - "{{ DMZ_subnets }}"
       - "{{ app_subnets }}"
       - "{{ gateway_subnets }}"
      tags: subnets
  </code></pre>
  
  <p>As can be seen from above example, by the subnets dicts there's already 2 vars I have defined before. The deeper we go into the hierarchy, the more excess dict entries will come into play.</p>
  
  <p>I tried to build the relationships into the variable structure, but ran into issues looping though the new variable structure. With_subelements worked fine for looping two lists of dictionaries, but it can't handle 3 or more.</p>
  
  <pre><code>- hosts: localhost
    connection: local
    vars:
  
      resourcegroups:
      - name: "eh_test_rg01"
        location: westeurope
        virtualnetworks:
        - name: "eh_test_vn01"
          cidr: 10.15.0.0/22
          subnets:
          - name: GatewaySubnet
            cidr: 10.15.0.0/24
          - name: eh_test_dmzsn01
            cidr: 10.15.1.0/24
          - name: eh_test_appsn01
            cidr: 10.15.2.0/24
  
      - name: "eh_test_rg02"
        location: westeurope
        virtualnetworks:
        - name: "eh_test_vn02"
          cidr: 10.15.4.0/22
          subnets:
          - name: GatewaySubnet
            cidr: 10.15.4.0/24
          - name: eh_test_dmzsn02
            cidr: 10.15.5.0/24
          - name: eh_test_appsn02
            cidr: 10.15.6.0/24
    tasks:
    - name: Create resource Group
      azure_rm_resourcegroup:
        name: "{{ item.name }}"
        location: "{{ item.location }}"
      with_items:
       - "{{ resourcegroups }}"
      tags: resourcegroups
  
    - name: Create vnet
      azure_rm_virtualnetwork:
        name: "{{ item.1.name }}"
        resource_group: "{{ item.0.name }}"
        address_prefixes_cidr: "{{ item.1.cidr }}"
      with_subelements:
       - "{{ resourcegroups }}"
       - virtualnetworks
      tags: vnets
  
  # Blows up at this point, with_subelements does not support more lists than 2
    - name: Create subnets
      azure_rm_subnet:
        name: "{{ item.2.name }}"
        resource_group: "{{ item.0.name }}"
        address_prefix: "{{ item.2.cidr }}"
        virtual_network: "{{ item.1.vnet }}"
      with_subelements:
       - "{{ resourcegroups }}"
       - virtualnetworks
       - subnets
      tags: subnets
  </code></pre>
  
  <p>What would be the best way to approach this problem? Do I need to define the vars differently, make some kind of helper tasks to create variable structures before running the task itself, use different loops or..? </p>
  
  <p>As far as I know, I can't make references to other dict values which are contained in a list of dictionaries using YAML.</p>