Using Amazon Alexa to turn off your EC2 instances

Introduction

rav3n
7 min readJan 6, 2019

In this article, I’ll walk through the process of setting up an Alexa skill to check if any EC2 instance are running. If so, she’ll be able to turn them off. I mean… I suppose you could use to the EC2 Scheduler but where is the fun in that?

Setup:

You will need the following to get started:

  • Alexa Developer Account, create one @ https://developer.amazon.com
  • Some AWS Knowledge such as basic navigation around console, launching EC2 instances
  • Code link right here for files.
  • There may be some region limitations so for this project I worked out of ‘us-west-2’ region aka Oregon for the Lambda part.

1st Component: Alexa Portal

First, I logged into the Alexa Developer Portal, selected Create Skill, and used the Start from scratch template.

Under Invocation, the name used to start the Alexa skill, I decided to change it to bob after the Overwatch character.

I added three Intents — these are actions that fulfills a user’s spoken request (if you want to follow along, there is a JSON in the Github repo):

  • GatherServerIntent, used to gather a total number of running instances, utterance = status report
  • TurnOffInstanceIntent, used to turn off the instances (obviously), utterance = turn off everything
  • HelloWorldIntent, used to ensure we’ve hard coded friendliness into our future AI overlords? I personally like having a test intent while I’m adding additional intents, utterance = howdy

Add more utterances if you’d like!

After these were created, I saved the model. The next point required adding an Endpoint, located on the left-side menu, after Interfaces.

Your Alexa Skill ID will be displayed here (remember this, you will need it soon). I paused here and switched over to the AWS Console to set up the Lambda function.

2nd Component: Lambda Function (switch to Lambda in the console)

I created a function using the following settings:

The role, lambda_basic_execution, was created after I selected Created Custom Role. It popped-up another window which allowed me to create the role without having to switch over to IAM.

After it was created, I copied and pasted the whole ARN (Amazon Resource Name) of the function located in the top-right corner over to the Default Region section under the Endpoint tab in the Alexa’s Developer Portal.

Then I copied the Skill ID and jumped back over to the Lambda Function in the AWS Console. I added an Alexa Skills Kit Trigger, pasted the Skill ID, and clicked Add. Now these are connected.

Since I already know that getting an instance state for all ec2 instances across all regions takes more than 3 seconds, I updated the Timeout setting from 3 to 30 seconds. If this was not set, Alexa would timeout after 3 seconds while the script was running and say “There was a problem with ….”

The last part of the lambda function is to upload the code. Since I was using the ask-sdk library, I needed to upload the code in a special packaged kind of zip. These are the steps I use to create lambda packages. First, I started by creating my project folder.

mkdir medium-alexa-assistant-tutorialcd medium-alexa-assistant-tutorial

I created a virtual environment but within the project folder (notice the ‘.’ at the end on the next command) using a specific version of python.

virtualenv --python=/usr/local/bin/python3.7 .

Activate. Install your dependencies. Deactivate.

source bin/activate
pip install boto3
pip install ask-sdk
deactivate

I changed into the site-packages directory to create my python file — which will contain all the code for this project.

cd lib/python3.7/site-packages
vi lambda_function.py

The code follows the classes style of development. More information about the classes vs decorator style found here.

Under the hood

I left this part of the code alone but line 16 is important. We will need to “add any intent” created to the SkillBuilder instance. This will make more sense later.

As requests (intents) come in, the handlers will check the request type, and if its the correct type, perform the action.

For example, invoking bob, will triggers the default LaunchRequestHandler. Alexa will respond with the speech text listed on Line 29.

NOTE: On Line 32–33, you will that set_should_end_session is set to False, so the skill will not close after the intent is fulfilled.

For the next class, we can trigger this intent by saying the utterance mentioned earlier. Remember what it was? What do you think Alexa will respond for this intent?

answers: howdy, line 44

Here is the super, fun part. This code gathers all the possible AWS regions and adds them to a list. Taking this list, it iterates over all regions to count all instances that are running. If the total instance count was zero, no instances were found to be running.

This intent will be similar to the last except instead of responding with a count, the lambda running in the background, using the IAM policy created earlier, will stop those instances — obviously don’t use this in production systems.

NOTE: The very last line of the script is super important.

The name lambda_handler (above, last line of script) needs to match exactly to the Handler info in lambda function from the AWS console (screenshot below).

NOTICE: Every intent needs to be added to SkillBuilder instance created at the top of the script; including the custom ones. If the code looks good, we need to package it and upload it.

While the name of the python file itself (lambda_function.py) that contains all the code is named lambda_function as like in the screenshot above.

From inside the directory where the python file is located (lib/python3.7/site-packages), run this command (assuming you are on MacOS or Linux). Remember the ‘.’ at the end of the next command.

# under lib/python3.7/site-packages
zip -r9 lambda_package.zip .

Upload lambda_package.zip to the lambda function and save. You can configure Alexa test events here if you wanted.

3rd Component: IAM Policy

One last setting to ensure the Lambda Function has correct authorization to describe my ec2 instances and stop the running ones. I created a new policy with the following settings (this is in the Github repo):

I took this policy and added it lambda_basic_execution role created earlier.

Bringing it all together

Now to jump back over to the Alexa Developer Portal and select Build Model.

If all is working, we should be able to type open bob to launch our skill but go launch an ec2 instance first, then come back. :)

Instance was on…. and now it’s off.

You can also test with other Amazon IOT devices registered to you. Should there be any errors (what are the chances?) I would check CloudWatch log streams.

Thanks for taking the time to read and extra kudos if you got it working. Please let me know if you run into any issues, if you have any feedback. Or maybe you’d be curious for a few more tutorials like this?

--

--

Responses (1)