The logic app and the resource graph query



A nice simple example of how to utilize azure resource graph from a logic app. In this case we have a use case from some of our alerting definitions to be able to work out from a resource id value of a virtual machine if that machine is running Linux or windows (as there is some further processing based on that)

So some sort of alerting rule as created an alert against a resource id something like this

/subscriptions/subid/resourcegroups/rgname/providers/microsoft.compute/virtualmachines/servername

I can't tell from that if the machine is Linux or windows so I want to be able to a simple logic app passing that resource id and get the logic app to tell me if that's Linux or windows - this will enable some further logic down the line

The process is therefore split into these 3 simple steps:


The first step defines a http endpoint that can be called that takes a resourceid value as an input parameter.

This is then followed by a second http step - this is a rest api call to the resource graph service which will allow me to find out the os of the target resource.

The final step is just arbitrary here - it will just email a value of Linux/windows just to prove the thing is working as expected (the actual logic of what happens next would be something entirely different)

Lets go through each of those bit by bot so we can see how this is built.

Step 1 - create the thing listening for requests

So first things first lets create a new logic app, pretty basic stuff just give it a name and some other basics and away we go


Review the settings and then create


Once it's created then we need to define the trigger - in this basic example it's just when it receives a call via http - so I pick the option below.


I then click on that object


Then click on the link (that's not obviously a link...) and define what my basic input will look like


In my case I just want to pass a single parameter called resid containing the resource id - so I just define my example input like below


When I save that in then builds that in the proper json definition for me and saves me some effort.


When I now save it the endpoint that is callable is generated - so I could call it at this point but it's not going to actually do anything (well other than reply that it got the request OK - but it actually has no further steps to do yet)


Step 2 - define the resource graph bit

So next is to do the call out to resource graph - first up we want to add an action to follow after the original http request comes in.


Here I choose http


Which then opens up this screen


Now we want to populate some values here - so we need to:

change the method to POST
enter the uri for resource graph which is (at the time of writing)  https://management.azure.com/providers/Microsoft.ResourceGraph/resources?api-version=2021-03-01
And then the clever bit for the resource graph query - in my simple case I just return the os based on the input of a resource id - the code for that is as follows:

{
  "query": "Resources | where type == 'microsoft.compute/virtualmachines' and id =~'@{triggerBody()?['resid']}'|project properties.storageProfile.osDisk.osType"
}

Note the 'resid' part is then the variable that is passed through from the original call


You can see that resid is then the special variable in the screen and is obviously different from the rest of the text.

Note here that I haven't included any kind of subscription filter so the query will run against everything in your tenant.


If you run the code now you'll find that it fails - as it's not authorized to run against resource graph yet - it's essentially an anonymous request that will fail. To do this in the simplest way I'm going to use a managed identity - i.e. the logic app itself gets an identity and we assign that permissions to be able to run resource graph. First step in that is to enable a managed identity in this screen:


We click it on and we see the message below


Now when we save the identity is created in Azure AD.


Now we just have to assign that identity permissions. In my case I want to give read access to everything in the entire tenant. To do that I go to my tenant root group in management groups and assign it the reader role - the final screen of that is shown below. I won't show the whole process as it's fairly straightforward and may vary depending on if you want to just grant access to only some subscriptions.


Once that's in place we just need to make use of it - so we choose the add new parameter option and choose the authentication option.

From the drop down choose 'managed identity' - i.e. the thing we created a minute ago


Now things should work - so we save it and then run it. Note to choose the with payload option so we can pass the resource id value in



The screen then pops open and we just need to pass in the value in the following format:
{
    "resid" : "full-res-id-here-with-slashes////"
}



Now when it runs and we navigate to look at the output of the run - we can see the returned value of 'Windows' in the screenshot below.


Step 3 - email it

To complete things off and show how we reference the returned value I add a simple send email step as the last action


The only clever bit here is the syntax for referencing the variable - that looks like this:

body('HTTP')?['data'][0]?['properties_storageProfile_osDisk_osType']

Which if you paste it in then looks like this on screen


If i now trigger it again with the payload i get a nice email through in my inbox looking like this:


And that's it job done - a nice basic example to show you how resource graph can be called - hope that's useful!


Comments

  1. Thanks for the blog on The logic app and the resource graph query.

    i enabled the managed identity on logic app, still im getting the error unauthorised.

    can you please help me with the detailed steps on authorization process.

    ReplyDelete
  2. Hi Kesav,
    Sorry long delay in replying - i don't check the comments too often.

    I think your issue will be that the function needs read access to everything you have - if you just have a single subscription then just grant read access at the subscription level and it should work. If you have a complex setup with many subscriptions you should grant the read access at the tenant root group level in the management groups blade

    Thanks,
    Rich

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete

Post a Comment