Sunday, May 20, 2018

CIS Control 1 on Azure - Maintain Asset Inventory Part 4

In part 3 I talked about a high level process for responding to new events being created on the Azure platform.  One of the components involved in the process was an Azure function that would be used to process the events, and determine if further action would be required.

I decided to use this as a good excuse to play around more with Azure functions.  The goal of this post is to talk a bit about the code required to make this work.

Step 1: Get Data Object

I started off by creating an http triggered Azure function, which seemed like the easiest way to integrate the function.  When you create an HTTP triggered function, you get some access methods to get data either off of the query string or the post body.

For example, the shell code is:

                 dynamic data = await req.Content.ReadAsAsync<object>();
                name = data?.name;

In our case, we want to grab the resource ID of the resource being written to.  That would be something like data.data.resourceID based on the event hub schema.

Step 2: Getting Access to Azure

Once we have the resource ID, we would need to connect to Azure.  I am big fan of Azure MSI, and decided that this would be the best way to go forward.  In order to utilize this, I decided to use the "Microsoft.Azure.Management.ResourceManager" library, which is essentially a wrapper around the REST methods.

Please note that you will also need the "Microsoft.Azure.Services.AppAuthenticaiton" library, to facilitate the MSI interaction.  Once you get these wired into your program, connecting to Azure is as easy as:

var azureTokenProvider = new AzureServiceTokenProvider();

var serviceCreds = new TokenCredentials(await azureTokenProvider.GetAccessTokenAsync("https://management.azure.com/").ConfigureAwait(false));

var resourceManagementClient = new ResourceManagementClient(serviceCreds);


Step 3: Getting tags from an Azure resource

I found that the easiest way to get access to the resource information I needed was to use the GetByID method.  Please note that I tried to use the CheckExistence method, but if failed to return at all for the API versions that I tried.  Not sure if there is a bug in there.

During this, I fooled around with the new Azure REST API Manager preview.  Check it out here.
There is a pretty cool "try it" feature that logs you into your Azure subscription and allows you to test the calls.

Step 4: Profit

After that, getting access to the tags was pretty easy. I can now add my own logic to check for what I want (in our case, the existence/population of certain tags such as owner, department, and approved).

This was a pretty fun little foray into the world of Azure functions.