cazureazure-sdk

List resources by from Azure by tag


I have the following simple piece of code for listing resources by tag from Azure, but I cannot get filter working. What am I doing wrong?

using Azure.Core;
using Azure.Identity;
using Azure.ResourceManager;
using Veeam.Core.Extensions;

string clientId = "...";
string tenantId = "...";
var clientSecret = "...";
string subscriptionId = "...";

// the code works with and operator but not works with or operator var filterTags = "tagName eq 'asdf' or tagValue eq '1234'";

var e = ArmEnvironment.AzurePublicCloud;
var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
var armClient = new ArmClient(credential);
var subscription = armClient.GetSubscriptionResource(new ResourceIdentifier("/subscriptions/" + subscriptionId));
var resourcesPageable= subscription.GetGenericResourcesAsync(filter: filterTags);
var tempResources = await resourcesPageable.ToListAsync();
Console.WriteLine(tempResources.Count);

The response from server is:

Status: 400 (Bad Request)
ErrorCode: InvalidFilterInQueryString

Content:                                                                                                                                          
{"error":{"code":"InvalidFilterInQueryString","message":"Invalid $filter 'tagName eq 'asdf' and tagValue '1234'' specified in the query string."}}

IntelliSense documentation says:

//For example, to filter for a tag name and value, use $filter=tagName eq 'tag1' and tagValue eq 'Value1'. When you filter by a tag name and value, the tags for each resource are not returned in the results.

Is it really the or operator not supported?


Solution

  • Is it really the or operator not supported?

    Yes, only and operations are allowed in $filter tag to list the resources but not or operation. Refer MSDOC.

    Try below operations to list the resources with tagname/tagvalue:

    $filter=tagname eq '{tagname}'
    $filter=tagname eq '{tagname}' and tagvalue eq '{tagvalue}'
    $filter=startswith(tagname, '{tagname prefix}')
    

    I have implemented the same with the below code:

    using System;
    using System.Threading.Tasks;
    using Azure.Core;
    using Azure.Identity;
    using Azure.ResourceManager;
    using Azure.ResourceManager.Resources;
    using Azure.ResourceManager.Resources.Models;
    using System.Data.Entity.Repository;
    
    class Program
    {
        static async Task Main(string[] args)
        {
            string clientId = "<Client_ID>";
            string tenantId = "<Tenant_ID>";
            var clientSecret = "<Client_secret>";
            string subscriptionId = "<Subscription_ID>";
            string filterTags = "tagname eq 'abc' and tagvalue eq '123'"; 
    
            var e = ArmEnvironment.AzurePublicCloud;
            var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
            var armClient = new ArmClient(credential);
            var subscription = armClient.GetSubscriptionResource(new ResourceIdentifier("/subscriptions/" + subscriptionId));
            var resourcesPageable = subscription.GetGenericResourcesAsync(filter: filterTags);
            var tempResources = new List<GenericResource>();
    
            await foreach (var resource in resourcesPageable)
            {
                tempResources.Add(resource);
            }
    
            Console.WriteLine($"Number of resources: {tempResources.Count}");
    
            foreach (var resource in tempResources)
            {
                Console.WriteLine($"Resource ID: {resource.Id}, Resource Name: {resource.Data.Name}, Resource Type: {resource.Data.ResourceType}");
            }
    
        }
    }
    

    Console Output:

    enter image description here