6 min read

Turning off Virtual Machines with Alexa, IFTTT and Azure Functions

Turning off Virtual Machines with Alexa, IFTTT and Azure Functions

I'm one of those people who forgets to turn off or delete resources running in Azure for development and test purposes (I know you've been there as well!). Yes, you can set a fixed time to automatically turn off things like virtual machines but often I disable that as the times I'm going on a hobby spree differ from day to day.

That is usually the result of already closing your laptop, thinking about your running resources minutes after you grab your drink and started up Netflix. My next thought "I'll do that later". Next day: VMs are still running.

How about not having to go back to your laptop and just ask Alexa to do that for you? Definitely doable!

The Requirements

In this example I'm going with Virtual Machines for simplicity. But other scenarios can also include deleting resources (because you're doing infrastructure as code) or simply stopping services. We're using an Azure Function for this but really, anything that can be called through HTTP(s) will work.

I really didn't want to build a custom Alexa skill as this usually requires running a Lambda function in AWS and ehm.. I'm all about Azure. A great alternative to trigger an HTTPS endpoint is IFTTT (If This, Then That). It allows you to trigger an HTTPS endpoint (GET or POST) and integrates with Alexa. Long story short, for this to work you need the following:

Building and configuring

First we need an Azure Function triggered by an HTTP request to shutdown the virtual machines. You can really build any logic within your function. As IFTTT also supports sending POST requests you could have one single endpoint for multiple actions including starting, stopping or even provisioning things if you feel adventurous. We're going with shutting down virtual machines for now.

Azure Function

Using the Azure Function Core tools you can create your Azure Function (func new). Name it whatever you want and choose PowerShell for the language and HttpTrigger for the trigger.

There's a lot of logic and checks you can build in but let's keep it simple for now. From the generated sample function we'll strip the parts we don't need and add our our Azure PowerShell Commands for shutting down all machines.

PowerShell Azure Function

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

$vms = Get-AzVM -status | Where-Object {$_.PowerState -eq "VM running"}

if (!$vms)
    {
        $body = "No running VMs"
    }
else 
    {
        $body = "Stopping VMs"
        foreach ($vm in $vms)
        {
            Stop-AzVM -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -Force -NoWait
        }
    }
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $body
})

As you can see we're requesting the list of Virtual Machines and store it in $vms). Additionally we're checking whether the $vms array isn't empty (nothing to shutdown if it is). If that's not the case we'll trigger the following command for each Virtual Machine that is running:

Stop-AzVM -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -Force -NoWait

Note that the -Force parameter is used because we can't provide the function with user input, if you leave this out it will come to a halt and fail. We're also using the -NoWait parameter to make sure the function finishes execution within the allowed timespan (we don't want to wait for the VM to actually have a deallocated state, we'll trust Azure that once it accepts the command it will perform the deallocation).

Deploy your function to Azure for example by using Visual Studio Code (how to here). Once the App is created, don't forget to configure Managed Identity to allow interaction between your Azure Function and the Virtual Machines. Once the Managed Identity is configured assign it the "Virtual Machine Contributor"  Role on the subscription. Note that this can also be done directly from the Function App but this feature is in preview.

Copy and paste the Azure Function URL including the function key for later use.

Setting up IFTTT

First you will need to set up your IFTTT Account at https://ifttt.com. Once you have that done,  let's go to create and create a new flow.

First let's set up the trigger: "If This".

What we want is "If I say X to Alexa, then do that". In the search bar search for "Alexa" and add the step. First you will be prompted to connect IFTTT to Alexa. Enter your credentials and allow access to your Alexa.

You will be guided to the next option, this is where we configure the phrase it has to listen to.

Choose "Say a specific phrase". You can now configure the phrase it will act upon. Please note that this phrase comes after the words "Alexa, trigger".

For this example I went with "turn off virtual machines". That means that once this is done we should be able to say "Alexa, trigger turn off virtual machines".

Once the trigger is set up you're redirected back to the first page of your If This, Then That flow. We'll now add an action for "Then That".

In the "Choose a service" window search for "Webhooks" and add it.

We can now configure the interaction with our Azure Function. In the URL paste the previously copied Azure Function URL. Set the Method to "GET" and set the Content Type to application/json. As we're doing a GET request we can leave the body empty.

Click create and everything should look similar to the image below. Both the "If This" and "Then That" are now configured.

Click continue and you're set on the IFTTT side!

Configuring Alexa

In the Alexa App set up a new routine. Give it a name and when adding an action scroll down to IFTTT. Once you add this action it should display the flow you configured on IFTTT.

Finish configuring the routine, give it a name and save it.

Time for some testing

I started a couple of Virtual Machines and the time was there:

Alexa, trigger turn off virtual machines

Alexa confirms and the speech history lists the command.

The log stream from the Azure Function also confirms the function has been triggered and the command to stop the Virtual Machines has been executed.

A quick glimpse at the Azure Portal also shows that the Virtual Machines are stopping.

Success!

Wrap-up

It takes some components but using something like IFTTT makes it really easy to integrate Alexa (or other home automation devices) without having to write a specific component for that platform, in this case "Alexa Skills". Combined with the Power of Azure Functions the possibilities are endless and we can still focus on just what we want and need; doing stuff in Azure :)

As always, if you need help or have any questions please feel free to reach out.