In this blog post I’ll walk through creating a Microsoft Flow flow for starting (and another for stopping) a set of Azure Resource Manager (ARM) VMs. Note that this is not my own original work. I implemented this based on the work of someone else I found online but can no longer find the original owner’s reference. If you do find this elsewhere please feel free to let me know in the comments.
Background
While it is possible to start and stop Azure VMs from the newly released Azure mobile app, most time I need to start up a set (3-5) VMs at a time for a SharePoint farm / app dev environment / etc. I was able to find a sample someone wrote in Microsoft Flow to trigger the start / stop from the Flow mobile app. The flow calls Azure AD to get an access token using an Azure AD app that has permissions to start / stop VMs. The access token is then passed into a series of REST calls to start up VMs in order (usually domain controller, database server, app server, web front end, etc.) Finally the flow will send a mobile push notification letting me know that the VMs have started.
Word of caution
This solution embeds the client ID and client secret (essentially user name and password) for the Azure AD app which has permissions to the Azure VM. This could be a security risk and as such should be cautioned from doing this. Treat this sample as a proof of capability for development purposes only. I’m continuing to explore alternatives (ex. Managed Service Identity, Azure connector in Microsoft Flow) which would increase security for this solution. If anyone has any suggestions please feel free to let me know in the comments.
Solution – Start Azure VMs
I won’t go into detail on each and every step as some of these are self explanatory or a repeat of others (ex. 2nd and 3rd VM to be started.) Before going into the flow to be created, ensure you have an Azure AD app registered with permissions on the desired VMs to be started / stopped.
Register Azure AD App
Log into the “new” Azure portal (portal.azure.com) and go into the Azure AD screen. First click on Properties to view the directory ID. Make note of this for future use.
Click App registrations and create a new app of type “Web app / API”.
Make note of the application ID (also known as client ID).
Go into the Required Permissions setting for the app. Add a permission for the “Windows Azure Service Management API”. Choose the permission “Access Azure Service Management as organization users” which is currently in preview.
Create a key for the Azure AD app and write this down. You will only get to see this key once and cannot retrieve it at a later time. If you lose the key value you will need to create a new one.
Assign access control to resource group
Now that the Azure AD App has been registered it will need access control to the resource group (or individual Azure VMs, more administration if this option) so that the app can start / stop the desired VMs. I granted Virtual Machine Contributor role to the Azure AD App but more fine grained controls might be possible if security concerns are a factor.
Microsoft Flow sample
- Manually trigger a flow
- Get access token for Azure
- Parse JSON to extract access token
- Start VMs (in series)
- Push notification if successful
Manually trigger a flow
This is self explanatory. This will let you initiate the flow from Flow web portal or the Flow mobile app.
Get access token for Azure
This step will use an HTTP POST action to the Azure AD directory where the Azure AD app is registered. Ideally you should send a request to this URI using Postman or a similar REST endpoint testing tool to get a sample of the JSON response to be used in the following step.
- Method: POST
- Uri: https://login.microsoftonline.com/<directoryID from previous step>/oauth2/token
- Headers
- Content-Type: application/x-www-form-urlencoded
- Body: resource=https://management.azure.com/&client_id=<client ID from previous step>&grant_type=client_credentials&client_secret=<client secret from previous step>
Example JSON response using Postman:
{
“token_type”: “Bearer”,
“expires_in”: “3599”,
“ext_expires_in”: “0”,
“expires_on”: “1508115492”,
“not_before”: “1508111592”,
“resource”: “https://management.azure.com/”,
“access_token”: “<removed value>”
}
Parse JSON
Either using the sample JSON response above or your own you can define the schema of the JSON to be parsed. Specify the “Body” of the JSON response from the prior HTTP POST action. The important element to parse out is “access_token”.
{
“type”: “object”,
“properties”: {
…<other properties here>…,
“access_token”: {
“type”: “string”
}
}
}
Start VM REST call
Add another HTTP POST action this time specifying the following configuration.
- Method: POST
- Uri: https://management.azure.com/subscriptions/<Azure subscription ID>/resourceGroups/<resource group name>/providers/Microsoft.Compute/virtualMachines/<Azure VM name>/start?api-version=2016-04-30-preview
- Headers
- Authorization: Bearer <insert the bearer token “input” from prior Parse JSON step>
Note that I used an older version for the “api-version=” portion of query string (highlighted in green). A newer version might also be available and compatible but I haven’t tested anything newer.
Create as many additional HTTP POST actions that call off to additional VMs as needed. I hand coded the Uri for each as Microsoft Flow didn’t yet support expressions and other dynamic variables when this solution was first created. You may want to investigate those to reduce repeated syntax if possible.
Notify when VMs started
Straight forward action with a simple notification to let me know when flow has completed.
Solution – Stop Azure VMs
The steps for stopping a set of Azure VMs will be identical to the “start” flow except that stopping VMs can be done in parallel as the order is not as important. In your own scenario the order may be important so consider that when creating your own solution.
- Manually trigger a flow
- Get Access Token for Azure
- Parse JSON to extract access token
- Stop VMs (in parallel)
- Push notification if successful
The other important difference will be to call to “deallocate” (highlighted in red) the VM rather than “start” using the Azure Service Management API. See example below for the HTTP POST to a VM.
- Uri: https://management.azure.com/subscriptions/<Azure subscription ID>/resourceGroups/<resource group name>/providers/Microsoft.Compute/virtualMachines/<Azure VM name>/deallocate?api-version=2016-04-30-preview
Sample Execution
As you can see from the below sample executions of both flows the start and stop of each VM can take some time (2-3 minutes) but is still an easier process of clicking one button rather than multiple clicks within the Azure Portal or mobile app.
Conclusion
Hopefully this walkthrough will help others who are interested in automating Azure VMs to start and stop (or any other authenticated actions against Azure resources). I’m hoping to try out additional options to remove the need to store client ID and secret within the flow. For the time being try out this process and let me know if you have any issues.
-Frog Out
Great blog I enjooyed reading
LikeLike