Azure Automation API Integration using REST and OAuth 2.0
Update: There is now an app in the ServiceNow store that provides integration to Azure Automation. The below still works, but if you prefer a supported solution, you should check out the app here.
There is also a video explaining how to set this up, which can be located here.
I needed to setup integration between ServiceNow an Microsoft Azure with the goal of having ServiceNow provision and maintain Servers in Microsoft Azure. To do so I have previously been using webhooks in Azure to facilitate the integration, but decided to try to use the Azure Automation API instead, as this gives more options and seems like a more secure approach. I however quickly found that there was not much documentation on the topic available which is why I decided to write this guide on my findings.
This document is split in two steps. The first step will setup everything needed in Azure and the second will configure ServiceNow. Following step two I will provide two examples of first starting a job by running runbook in Azure and secondly how to get the status of the job.
For ServiceNow to be able to integrate to Azure there is some configuration that is needed to be done on the Azure side. Go to portal.azure.com and login with your azure credentials.
To complete this guide you need to have sufficient rights in your Azure platform. First check that "App Registration" is activated. Click on "Azure Active Directory" in the menu to the left and then select "User Settings". Ensure that the option "Users can register applications" is set to yes.
If this is set to "No" you need to be "Global Administrator" in order to register an app. Either ensure that you have this access or ask your administrator to enable app registration.
Next verify that you have sufficient rights for the subscription in Azure. Again select "Azure Active Directory" in the menu to the left then click "Users & Groups" - "All Users". Click on your own user and then click "Azure resources". Verify that you have at least the "Contributor" role for the subscription that you wish to integrate to. In below picture I have the "Owner" role so I am good to go.
Now we are ready to configure Azure. Go to "Azure Active Directory" in the menu to the left. Then click on "App registrations". This will give you a list of registered Apps. If ServiceNow is already on this list, simply click on it to open it. If not you can add it by clicking the little "+ Add" in the top left of the list.
Under "Name" you enter "ServiceNow" or something that makes sense to you. Under the "Application Type" you must select "Web app / API". Under sign-on URL add the link to your instance followed by "/login.do". Ex. https://myinstance.service-now.com/login.do. Then click the "Create" button at the bottom.
Once the Application is created you will see a page that looks like below. If the menu to the right is not visible, click the "Settings" button in the upper left corner.
Copy and store the "Application ID" as you will need this later to configure ServiceNow. Then click the "Keys" under "API Access".
Enter something meaningful in the "Description" field and select an expiration date. For ease of use I selected "Never". Then click "Save".
Once you click "Save" a key will be generated. This is the only time that you will be able to see this key, so make sure that you copy it and store it somewhere safe.
Now we need to obtain your Subscription ID and the name of the Resource Group in which your runbooks are stored. To find this go to "Resource groups" in the menu to the left, then click on the name of the Resource Group in which you have placed your runbooks.
In the upper right corner you can see the Subscription ID. Copy this and save it somewhere safe. We will need this later to Configure ServiceNow. Also copy the name of the Resource Group. In this case "SNOW-TEST". Scroll down the list to the right and copy the name of the "Automation Account" in which you runbooks are stored. Then click the "Access control (IAM)" link in the menu to the left.
Click the "+ Add" icon the the top left to give ServiceNow access.
Since I need to have ServiceNow both read and update objects in Azure I select the "Contributor" role. If you only need read access, then consider using the "Reader" role. Then click "Select" at the bottom of the page.
Search for the ServiceNow application that we previously created and select it. Then click "Select" followed by "OK".
Lastly we need to copy your tenant ID. There are multiple ways to get this, but go to https://portal.azure.com/#blade/Microsoft%5FAAD%5FIAM/ActiveDirectoryMenuBlade/Properties and copy the ID in the "Directory ID" field.
We are now done setting up Azure and are ready to configure ServiceNow. Ensure that you have recorded the following information:
- Application ID
- Key
- Subscription ID
- Name of Azure Resource Group in which you runbooks are stored
- Name of Automation Account in which you run books are stored
- Tenant ID
In ServiceNow you need to have the "admin" role in order to configure the integration. I will be using javascript to create the connection. This can then be used in a script include, a business rule etc. Basic understanding of scripting is assumed, but please do let me know if there is anything that is unclear.
First click on "Application Registry" under "System OAuth" in the menu to the left.
Click the "New" button at the top of the list and then pick "Connect to a third party OAuth Provider"
Next fill out the form with below information.
- Name: In this example we will call the it "Azure OAuth", but you can call it something that makes for sense to you
- Client ID: Insert the "Application ID" that we saved earlier in the Azure configuration
- Client Secret: Insert the "Key" that we saved earlier in the Azure configuration
- Default Grant type: Set this to "Client Credentials"
- Refresh Token Lifespan: You can leave this at the default of 8.640.000.
- Token URL: Set this to "https://login.microsoftonline.com//oauth2/token" where is the tenant ID that we saved in the Azure configuration
- Redirect URL: Set this to "https://.service-now.com/oauth_redirect.do" where is the name of your ServiceNow instance.
Click "Submit" to save the OAuth Provider. We are now ready to start scripting.
First we will create a new OAuth object
var oAuthClient = new sn_auth.GlideOAuthClient();
Next we will set the params for the OAuth object
var params = {grant_type:"client_credentials",resource:"<https://management.azure.com/>"};
We will then get the token response by specifying the name of the OAuth Provider we created earlier and add the parameters
var tokenResponse = oAuthClient.requestToken('Azure OAuth',global.JSON.stringify(params));
From this we will extract the token
var token = tokenResponse.getToken();
We will then create a REST object to start querying the Azure API. In this example we will do a simple GET to get the status of a given job. First we create the object
var r = new sn_ws.RESTMessageV2();
Next we add the token that we just acquired
r.setRequestHeader('Authorization','Bearer ' + token.getAccessToken());
You are now ready to start constructing your request.
Step 2.1 Start a new job in Azure using a PUT request.
In this example we will continue to build on the script defined in step 2 start a new job in Azure. You need to know the name of the runbook that you wish to start as well as the Subscription ID, Resource Group and Account Name that you noted down earlier in the Azure configuration step. I will refer to them as:
runbook, subscription_id, resource_group, account_name
Firstly we need to generate a GUID for the new job. I use the below code to do so.
var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {var r = Math.random()*16|0,v=c=='x'?r:r&0x3|0x8;return v.toString(16);});
I will then create the URL which will be the endpoint that we will communicate with.
var url = '<https://management.azure.com/subscriptions/>' + subscription_id + '/resourceGroups/' + resource_group + '/providers/Microsoft.Automation/automationAccounts/' + account_name + '/jobs/' + guid + '?api-version=2015-10-31';
Then we need to specify the runbook and set the parameters that the runbook needs in order to execute. In the below example we set the name to the value of the variable 'runbook' and set two parameters called 'var1' and 'var2'. Change this so that it suits your needs.
var aRequest = { 'properties' : { 'runbook' : { 'name' : runbook }, 'parameters' : { 'var1' : 'some value', 'var2' : 'some other value' } } };
Next we add the above to the request body.
r.setRequestBody(global.JSON.stringify(aRequest));
Secondly set the http method to "put".
r.setHttpMethod('put');
Next you need to set the content type in the header for Azure to understand your request. Eg:
r.setRequestHeader('Content-Type','application/json;odata=verbose');
We then add the URL to the REST object. I like to strip all white spaces just in case somebody accidentally added a whitespace somewhere, since this will break the URL. Alternative url_encode can be used.
r.setEndpoint(url.replace(/\s+/g,''));
Execute the REST object to get the response.
var response = r.execute();
Next I add the response to the work_notes of the current record (current), but this can also be logged with gs.info().
current.work_notes = 'Return message: ' + response.getBody() + '\nHTTP response: ' + response.getStatusCode(); current.update();
Finally, since I usually work on a table that is extended from the task table of ServiceNow I like to save the guid to the correlation_id of the table. This makes it easy to later check for the status os the job that we have now started.
current.correlation_id = guid;
Update the record to save the work_notes and the correlation_id
current.update();
Step 2.2 Do a GET request to get the status of a job
In this example we will query Azure to get a status of a job, that we have already started. We will start with the script defined in step 2 and need the following variables to be filled out.
subscription_id, resource_group, account_name, guid
The subscription_id, resource_group and account_name you already noted down earlier in the Azure Configuration part of this guide. The guid is the guid of the job that you wish to get the status of. If you followed step 2.1 to start the job, then this is saved in the correlation_id field of the record.
Then we construct the URL used as the endpoint.
var url = '<https://management.azure.com/subscriptions/>' + subscription_id + '/resourceGroups/' + resource_group + '/providers/Microsoft.Automation/automationAccounts/' + account_name + '/jobs/' + guid + '?api-version=2015-10-31';
Next we set the HTTP method. In this example we will do a simple "GET":
r.setHttpMethod('get');
Next add the URL to the REST object. I like to strip all white spaces just in case somebody accidentally added a whitespace somewhere, since this will break the URL. Alternative url_encode can be used.
r.setEndpoint(url.replace(/\s+/g,''));
Execute the REST object to get the response.
var response = r.execute();
Next I add the response to the work_notes of the current recored (current), but this can also be logged with gs.info().
current.work_notes = 'Return message: ' + response.getBody() + '\nHTTP response: ' + response.getStatusCode(); current.update();
You are now done and can take further actions with the response. To work with the response I usually convert the response to an object like so:
var resObject = global.JSON.parse(this.response.getBody());
In the above example we are getting the status of a job, so I would then subsequently look for the status property in the response object:
if(('properties' in resObject)) { if(('status' in resObject.properties)) { if(resObject.properties.status == 'Completed') // The job has completed else if(resObject.properties.status == 'Failed') // The job has failed } }
You can find a complete list of Azure endpoints that you can use here: Operations on Automation. I hope that you will find this helpful. If you have any input, suggestions or comments please let me know ![]()
https://www.servicenow.com/community/developer-articles/azure-automation-api-integration-using-rest-and-oauth-2-0/ta-p/2326346