There’s a pretty comprehensive set of APIs available for interacting with Azure resources but unfortunately these seem to be so new that there’s not really much documentation around on how to use them.

For an example of the information that can be returned by these APIs you can use the Azure Resource Explorer preview to explore the resources that are available to you.

There’s also a .NET library provided by Microsoft to make interacting with these APIs easier, this can be used via the following NuGet packages.

Microsoft.Azure.Management.Fluent
Microsoft.Azure.Management.ResourceManager.Fluent

The following code retrieves details of all web apps in all subscriptions belonging to a given tenant. This initially gets the web app and then gets the configuration for it and maps it to the web app.

public async Task GetWebAppDetails()
{
	string clientId = "clientId";
	string clientSecret = "clientSecret";
	string tenantId = "tenantId";
	string subscriptionId = "subscriptionId";

	AzureCredentials credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(
		clientId, 
		clientSecret, 
		tenantId, 
		AzureEnvironment.AzureGlobalCloud).WithDefaultSubscription(subscriptionId);

	RestClient restClient = RestClient
		.Configure()
		.WithEnvironment(AzureEnvironment.AzureGlobalCloud)
		.WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
		.WithCredentials(credentials)
		.Build();

	var creds = new AzureCredentialsFactory().FromServicePrincipal(
		clientId, 
		clientSecret,
		tenantId, 
		AzureEnvironment.AzureGlobalCloud
		);

	var azure = Azure.Authenticate(creds);

	// Get all subscriptions in tenant
	foreach (var subscription in await azure.Subscriptions.ListAsync())
	{
		// Get all resource groups in subscription
		ResourceManagementClient resourceManagementClient = new ResourceManagementClient(restClient);
		resourceManagementClient.SubscriptionId = subscription.SubscriptionId;

		foreach (var resourceGroup in await resourceManagementClient.ResourceGroups.ListAsync())
		{
			// Get web app details
			WebSiteManagementClient webSiteManagementClient = new WebSiteManagementClient(restClient);
			webSiteManagementClient.SubscriptionId = subscription.SubscriptionId;

			foreach (var webApp in await azure.WithSubscription(subscription.SubscriptionId).WebApps.ListByResourceGroupAsync(resourceGroup.Name))
			{
				SiteConfigResourceInner siteConfigResourceInner = await webSiteManagementClient.WebApps.GetConfigurationAsync(resourceGroup.Name, webApp.Name);
				webApp.Inner.SiteConfig = new SiteConfig();

				foreach (PropertyInfo propertyInfo in webApp.Inner.SiteConfig.GetType().GetProperties())
				{
					var value = siteConfigResourceInner.GetType().GetProperty(propertyInfo.Name).GetValue(siteConfigResourceInner, null);
					propertyInfo.SetValue(webApp.Inner.SiteConfig, siteConfigResourceInner.GetType().GetProperty(propertyInfo.Name).GetValue(siteConfigResourceInner));
				}
			}
		}
	}
}

Strangely, the SiteConfig object returned as part of the IWebApp object by the management API is always null so if you want to retrieve any application settings such as minimum TLS version then you need to make a separate call to get the configuration. This configuration is of type SiteConfigResourceInner rather than SiteConfig although they appear to be identical, hence the foreach loop in the code above to match properties from the SiteConfigResourceInner to the SiteConfig.


2 Comments

Fred · 2nd April 2021 at 8:21 pm

Hi, thanks for the post, helped me a lot understanding but I’m still trying to figure out what are the clientId, clientSecret and tenantId and what I need to configure on the Azure Portal.

I’ve added an app registration in ADD and I’ve added an API permission to Azure Service Management to that new App Registration.

I assume the clientId, clientSecret and tenantId from your exemple are taken from that App Registration?

And what about the subscriptionId?

Also, do I need to provide the currently logged user credentials in my request?
The API permission that I’ve configured is of type “Delegated Permission: Your application needs to access the API as the signed in user”
I can’t seem to be able to change the type to : “Application permission”

I still get no result at all from await azure.Subscriptions.ListAsync().

I suspect it might have something to do with the API permission type?

    Shinigami · 7th April 2021 at 2:35 pm

    Yep, clientId, clientSecret and tenantId all come from the the AAD App Registration.

    subscriptionId is the ID of the subscription of the subscription your resource exists in. You can get this from the Subscriptions blade in the portal (https://portal.azure.com/#blade/Microsoft_Azure_Billing/SubscriptionsBlade).

    The credentials of the App Registration should be sufficent to authenticate the API calls without passing in the logged in users credentials. My use case was fetching details of resources using a console app so there was no logged in user. If you wanted to have an interactive login with the logged in users credentials being used to authenticate I think you’d need to create the credentials differently, not using “FromServicePrincipal”. Though I’m not sure what exactly you’d need to do.

Leave a Reply to Fred Cancel reply

Your email address will not be published. Required fields are marked *