azure-active-directoryappinsightsazure-monitor

Issue granting consent to access AppInsights Data


We have too many instances of AppInsights configured, so I am trying to determine the most-recent log entry in each instance to learn which are no longer being used. Here is my code.

namespace EnumerateAppInsights
{
    using Azure;
    using Azure.Core;
    using Azure.Identity;
    using Azure.Monitor.Query;
    using Azure.Monitor.Query.Models;
    using Azure.ResourceManager;
    using Azure.ResourceManager.ApplicationInsights;
    using System;
    using System.Net;
    using System.Threading.Tasks;

    class Program
    {
        static async Task Main()
        {
            var credentials = new UsernamePasswordCredential(username, password, tenantId, clientId);

            try
            {
                var armClient = new ArmClient(credentials);

                var subscriptionCollection = armClient.GetSubscriptions();
                foreach (var subscriptionResource in subscriptionCollection.GetAll())
                {
                    foreach (var resourceGroup in subscriptionResource.GetResourceGroups())
                    {
                        var appInsightsCollection = resourceGroup.GetApplicationInsightsComponents();
                        foreach (var appInsightsComponentResource in appInsightsCollection.GetAll())
                        {
                            var queryClient = new LogsQueryClient(credentials);

                            string resourceId =    
                                $"/subscriptions/{subscriptionResource.Data.SubscriptionId}" +
                                $"/resourceGroups/{resourceGroup.Data.Name}" +
                                $"/providers/Microsoft.Insights/AppInsights" +
                                $"/{appInsightsComponentResource.Data.Name}";

                            Response<LogsQueryResult> results = await queryClient.QueryResourceAsync(
                                new ResourceIdentifier(resourceId),
                                WebUtility.UrlEncode("traces | top 1 by timestamp desc | project timestamp"),
                                new QueryTimeRange(TimeSpan.FromDays(1)));
                                ...
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
            Console.ReadLine();
        }
    }
}

And here is the output.

Error: UsernamePasswordCredential authentication failed: 
AADSTS65001: The user or administrator has not consented to use the application with 
ID '3d5d70e8-2249-4979-b5ea-6892e9a7ce4e' named 'EnumerateAppInsights'. 
Send an interactive authorization request for this user and resource.

I was originally receiving this exception from the ArmClient() but solved that problem by adding Api Permissions & Admin Consent for Azure Server Management to the App Registration.

But now I am getting it from the LogsQueryClient() and even after adding permissions/consent for:

it's still happening. Anyone have any thoughts to share?

Adding the missing permissions - Log Analytics API - solved this problem. But now I am getting "SEM0100": Failed to resolve table expression named 'traces'". Is it possible this is because we have not yet updated to Workspace-based Application Insights?


Solution

  • The error usually occurs if the service principal does not have required permissions or roles to perform the operation.

    I registered one Azure AD application and added below API permissions by granting admin consent like this:

    enter image description here

    When I ran your code in my environment, I too got same error as you like below:

    namespace EnumerateAppInsights
    {
        using Azure;
        using Azure.Core;
        using Azure.Identity;
        using Azure.Monitor.Query;
        using Azure.Monitor.Query.Models;
        using Azure.ResourceManager;
        using Azure.ResourceManager.ApplicationInsights;
        using System;
        using System.Net;
        using System.Threading.Tasks;
    
        class Program
        {
            static async Task Main()
            {
                var credentials = new UsernamePasswordCredential(username, password, tenantId, clientId);
    
                try
                {
                    var armClient = new ArmClient(credentials);
    
                    var subscriptionCollection = armClient.GetSubscriptions();
                    foreach (var subscriptionResource in subscriptionCollection.GetAll())
                    {
                        foreach (var resourceGroup in subscriptionResource.GetResourceGroups())
                        {
                            var appInsightsCollection = resourceGroup.GetApplicationInsightsComponents();
                            foreach (var appInsightsComponentResource in appInsightsCollection.GetAll())
                            {
                                var queryClient = new LogsQueryClient(credentials);
    
                                string resourceId =    
                                    $"/subscriptions/{subscriptionResource.Data.SubscriptionId}" +
                                    $"/resourceGroups/{resourceGroup.Data.Name}" +
                                    $"/providers/Microsoft.Insights/AppInsights" +
                                    $"/{appInsightsComponentResource.Data.Name}";
    
                                Response<LogsQueryResult> results = await queryClient.QueryResourceAsync(
                                    new ResourceIdentifier(resourceId),
                                    WebUtility.UrlEncode("traces | top 1 by timestamp desc | project timestamp"),
                                    new QueryTimeRange(TimeSpan.FromDays(1)));
                                    ...
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error: {ex.Message}");
                }
                Console.ReadLine();
            }
        }
    }
    

    Response:

    enter image description here

    To resolve the error, you need to add Log Analytics API permission in your application as below:

    enter image description here

    Make sure to grant admin consent to added API permissions as below:

    enter image description here

    When I ran the same code again after granting consent to above permission, I got response like this:

    enter image description here

    In your case, make sure to add Log Analytics API permission and grant admin consent for it to resolve the error.

    Reference: API access and authentication - Azure Monitor | Microsoft