My latest project includes integration with Amazon’s Alexa voice service. My coworker Jordan already wrote an excellent post on how to get started writing your own Alexa Custom Skill. Amazon’s API makes it relatively easy to develop a new Skill, and with a number of languages to choose from (Python, Node.js, Java, C#, etc), developers can create a simple Skill in a weekend.
With longer development times and iterative updates to our Skill’s functionality, we decided to find a way to auto-deploy our Lambda code with each Git commit.
Note: this post was originally titled ‘Deploying your Alexa Skill’ and has been changed. Alexa Skills have two parts: the skill itself (consisting of a name, logo, intent schema, sample utterances, etc.), and code that executes commands based on the incoming user input. These two parts are managed separately. While you can choose to host this code by yourself (using Heroku, for example), Amazon makes it easy to host your code with Amazon Lambda, and simplifies the authentication process for you.
This post is about deploying to Amazon Lambda. Amazon does not provide a way to auto-deploy to the Alexa Skill itself. However, because that content is relatively static (with the name, logo, intents, and utterances set up at the beginning of our development cycle), I haven’t had a need to repeatedly change the Alexa Skill, only the Lambda code.
1. Install AWS CLI
First, you will need to install the Amazon Web Services command line interface (AWS CLI).
For Mac and Unix users, you will need Pip and Python installed. Then:
$ sudo pip install awscli
Note: if you get an error regarding `six` (an issue in El Capitan), use --ignore-installed option
.
Alternatively, if you use Homebrew:
$ brew install awscli
To test if your installation was successful, type:
$ aws help
For Windows, installers are available here.
2. Configure AWS CLI
Next, you will need to configure AWS CLI so it has permission to access and update your Alexa Skill code. You will need an Access Key and Secret Access Key, which can be found in the AWS Lambda portal. After you have logged in, click your name in the upper right-hand corner and select “My Security Credentials” from the dropdown menu.
Click “Access Keys” to get your AWS Access Key ID
. Your AWS Secret Access Key
cannot be retrieved from this page. If you previously created a AWS Secret Access Key
, you should have downloaded a file with both the Access Key ID
and Secret Access Key
. If you don’t have a Secret Access Key
, or you have lost yours, you can create a new one on this page. While you’re here, take note of your region name as well.
Next, open up a command line and type:
$ aws configure
This command is interactive, and it will let you input each of the following pieces of information:
$ aws configure
AWS Access Key ID [None]: [ID found on "My Security Credentials" screen]
AWS Secret Access Key [None]: [Secret Key found on "My Security Credentials" screen]
Default region name [None]: [Region found on "My Security Credentials" screen]
Default output format [None]: [Enter]
3. Deploy Your Updates
Once you have updates to your code, open up the command line and navigate to the directory where your Alexa Skill code is. Note: this assumes that you have already manually deployed your code through the AWS Lambda portal when you initially set up your Skill.
In the photo above, the name of my Skill is AlexaTest
, and the name of my handler is lambda_function
.
You will first need to zip up your directory. You can do this from the command line if you’d like:
$ zip -r -X lambda_function.zip lambda_function.py
Here, I am zipping my file into a zipped directory with lambda_function
as the name. It is important that this name matches the handler that I set up in the AWS Lambda portal. We used Python for our Alexa Skill, so all of our code is in the lambda_function.py
file.
Note: -r tells zip to recurse into directories, and -X tells zip to exclude extra file attributes.
Let’s push our (zipped) changes to AWS Lambda using the AWS CLI:
$ aws lambda update-function-code --function-name 'AlexaTest' --zip-file 'fileb://lambda_function.zip'
The function name needs to match my Skill name (Alexa Test), and again, I’m using lambda_function.zip
. I also need the fileb://
prefix.
Go to the AWS Lambda Portal to see if your code was updated.
If something went wrong, double-check your Skill and handler names, and make sure that the zip file contains the appropriate files.
4. Include Libraries
Often, you will want to include a library in your deployment. We needed to include a library to support JWT tokens. We decided to put this library in a folder called “deployment-package,” along with the Python file.
Once again, we’ll zip up our project files. Here, we’re navigating into the directory where the project files live and zipping them into a directory called lambda_function.zip
(one directory level higher). The *
grabs all the files in the deployment-package directory.
$ cd deployment-package && zip -r -X ../lambda_function.zip *
Putting this together, I have:
(cd deployment-package && zip -r -X ../lambda_function.zip *)
aws lambda update-function-code --function-name 'AlexaTest' --zip-file 'fileb://lambda_function.zip'
The parenthesis around the first line denote a subshell. In this case, it means that I don’t need a cd ..
before I make my aws
call.
5. Add to Your Deployment Workflow
Lastly, you can turn these two lines into a script. We are using CircleCI for this project, and we altered our circle.yml
file to execute our deployment script after every push to master.
deployment:
production:
branch: master
commands:
- pip install awscli
- aws configure set aws_access_key_id $AWSKEY
- aws configure set aws_secret_access_key $AWSSECRETKEY
- aws configure set default.region us-east-1
- aws configure set default.output json
- ./deploy.sh
- cp lambda_function.zip $CIRCLE_ARTIFACTS/
or as a Git hook.