Search code examples
ansiblejmespath

Multiple searches with with json_query/jmespath filter in Ansible


I'm trying to parse out specifc subnet names in the following piece of json, while using contains_with or starts_with filters in json_query. It contains two vnets each of which has multiple subnets:

{
  "azure_virtualnetworks": [
    {
      "name": "test-vnet-172-17-0-0-19", 
      "properties": {
        "subnets": [
            {
              "name": "test-confluent-subnet-172-17-0-0-28", 
              "properties": {
                  "addressPrefix": "172.20.88.0/28", 
                  "networkSecurityGroup": {
                      "id": "/subscriptions/********/resourceGroups/test-confluent-rg/providers/Microsoft.Network/networkSecurityGroups/test-confluent-nsg"
                  }, 
                  "provisioningState": "Succeeded"
              }
            }, 
            {
              "name": "test-test-subnet-172-17-0-32-28", 
              "properties": {
                  "addressPrefix": "172.20.88.32/28", 
                  "networkSecurityGroup": {
                      "id": "/subscriptions/********/resourceGroups/test-test-rg/providers/Microsoft.Network/networkSecurityGroups/test-test-nsg"
                  }, 
                  "provisioningState": "Succeeded"
              }
            }
        ]
      } 
    },
    {
      "name": "test2-vnet-172-17-1-0-19", 
      "properties": {
        "subnets": [
            {
              "name": "test-confluent-subnet-172-17-1-0-28", 
              "properties": {
                  "addressPrefix": "172.20.88.0/28", 
                  "networkSecurityGroup": {
                      "id": "/subscriptions/********/resourceGroups/test-confluent-rg/providers/Microsoft.Network/networkSecurityGroups/test-confluent-nsg"
                  }, 
                  "provisioningState": "Succeeded"
              }
            }, 
            {
              "name": "test-qatesting-subnet-172-17-1-16-28", 
              "properties": {
                  "addressPrefix": "172.20.88.16/28", 
                  "networkSecurityGroup": {
                      "id": "/subscriptions/********/resourceGroups/test-qatesting-rg/providers/Microsoft.Network/networkSecurityGroups/test-qatesting-nsg"
                  }, 
                  "provisioningState": "Succeeded"
              }
            }
        ]
      }
    }
  ]
}

I need to search for a subnet name after searching by virtual network name.

I can filter as far down as the list of subnets without problems. e.g

azure_virtualnetworks[?contains(name,`test2-vnet`)].properties.subnets[]

returns:

 [
   {
     "name": "test-confluent-subnet-172-17-1-0-28",
     "properties": {
       "addressPrefix": "172.20.88.0/28",
       "networkSecurityGroup": {
         "id": "/subscriptions/********/resourceGroups/test-confluent-rg/providers/Microsoft.Network/networkSecurityGroups/test-confluent-nsg"
       },
       "provisioningState": "Succeeded"
     }
   },
   {
     "name": "test-qatesting-subnet-172-17-1-16-28",
     "properties": {
       "addressPrefix": "172.20.88.16/28",
       "networkSecurityGroup": {
         "id": "/subscriptions/********/resourceGroups/test-qatesting-rg/providers/Microsoft.Network/networkSecurityGroups/test-qatesting-nsg"
       },
       "provisioningState": "Succeeded"
     }
   }
 ]

However I'm having problems then searching the subnets. I had thought that some variation on following might work but haven't had any sucess:

azure_virtualnetworks[?contains(name,`test2-vnet`)].properties.subnets[?contains(name,`test-confluent`) ]

I'm struggling to figure out what the correcting syntax is here.


Solution

  • Select required subnets, stop projection with pipe expression, filter required items from the subnets list:

    azure_virtualnetworks[?contains(name,`test2-vnet`)].properties.subnets[] | [?contains(name,`test-confluent`)]