If you’ve done any experimentation with the Amazon Alexa voice service, you’ve probably learned that you can use AWS Lambda to write functions that can be executed from Alexa. As a developer, what’s exciting about this is that you can create your own custom Alexa skills to perform anything suited for voice-based computing.
You’ll probably also learn that there are numerous manual actions for integrating the various tools and code to deploy an Alexa skill. Once you create the Lambda function, you need to create a zip file with any packages that the function requires and upload it to Amazon S3. Moreover, you need to store code assets somewhere and then orchestrate the build and deployment of the function(s) that are run by your Alexa skill. Finally, you need to configure the Alexa skill itself using the Alexa Skills Kit (ASK).
In this post, you will learn how to orchestrate the deployment of an Alexa skill (written in AWS Lambda) using the AWS Developer Tools suite – including AWS CodeCommit, AWS CodeBuild, and AWS CodePipeline. The provisioning of all of the AWS resources is defined in an AWS CloudFormation template. By automating many of the actions and stages into a deployment pipeline, you can release changes to users in production whenever you choose to do so. You’ll see an example that walks you through the deployment process.
Figure 1 shows this deployment pipeline in action.
Figure 1: Deployment Pipeline in CodePipeline to deploy a Lambda function
Here are the prerequisites for this solution:
- AWS account – Follow these instructions to create an AWS Account: Creating an AWS Account
- Amazon developer account – Sign up for a developer account by visiting the Amazon Developer Service website.
Architecture and Implementation
All code assets are stored in AWS CodeCommit. We define a deployment pipeline in AWS CodePipeline to orchestrate the solution by configuring a Source action for CodeCommit, a build action with CodeBuild, and deploy actions for a CloudFormation changeset. The provisioning of AWS resources is defined in CloudFormation.
In Figure 2, you see the architecture for provisioning an infrastructure that launches a deployment pipeline to orchestrate the build and deployment of a Lambda function. You can click on the image to launch the template in CloudFormation Designer.
Figure 2: CloudFormation Template for provisioning AWS resources
The components of this solution are described in more detail below:
- AWS CloudFormation: All of the resource generation of this solution is described in CloudFormation which is a declarative code language that can be written in JSON or YAML
- AWS CodePipeline: The CodePipeline stages and actions are defined in a CloudFormation template. This includes CodePipeline’s integration with CodeCommit, CodeBuild, and CloudFormation (For more information, see Action Structure Requirements in AWS CodePipeline).
- AWS CodeCommit: Creates a CodeCommit Git repository using the AWS::CodeCommit::Repository
- AWS CodeBuild: Creates a CodeBuild project using the AWS::CodeBuild::Project to package and store the Lambda function
- AWS IAM: An Identity and Access Management (IAM) Role is provisioned using the AWS::IAM::Role resource which defines the resources that the pipeline, CloudFormation, and other resources can access.
- AWS SNS: Provisions a Simple Notification Service (SNS) Topic using the AWS::SNS::Topic resource. The SNS topic is used by the CodeCommit repository for notifications.
- Serverless Application Model (SAM): “The AWS Serverless Application Model (AWS SAM) extends AWS CloudFormation to provide a simplified way of defining the Amazon API Gateway APIs, AWS Lambda functions, and Amazon DynamoDB tables needed by your serverless application.” [Source]
- Amazon Alexa: the voice service that powers Amazon Echo, provides capabilities, or skills, that enable users to interact with devices in a more intuitive way using voice.
- AWS Lambda: The serverless function run by the Alexa skill.
The index.js file stored in CodeCommit is based on the alexa-skill-kit-sdk-factskill blueprint. As part of the deployment pipeline, the Node.js function gets packaged by CodeBuild and stored in S3. In the Deploy stage, it generates a CloudFormation template based on the Serverless Application Model and executes a change set on this template. The purpose of the generated template is to provision the Lambda function from the source in S3. Figure 3 illustrates how the Alexa skill interfaces with Lambda.
Figure 3: Alexa Skills Kit and Lambda
In this section, I’ll highlight a few code snippets from the CloudFormation template that automates the provisioning of the AWS Developer Tools stack along with other resources including S3, IAM, and SNS.
There are several IAM roles that are provisioned in the CloudFormation template. The code shown in this section is for an IAM role that is used by the AWS Serverless Application Model for deploying the Lambda function run by the Alexa skill.
LambdaTrustRole: Description: Creating service role in IAM for AWS Lambda Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Path: "/" Policies: - PolicyDocument: Statement: - Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Effect: Allow Resource: "*" Version: '2012-10-17' PolicyName: MyLambdaWorkerPolicy RoleName: !Ref AWS::StackName CodePipeline
The CodePipeline pipeline CloudFormation snippet shown below defines the three stages and four actions that orchestrate the deployment of the Lambda function used by the Alexa skill. The pipeline provisions a CodeCommit source action called Source. This repository is provisioned as part of the CloudFormation template. The TemplatePath: alexa-BuildArtifact::template-export.json property definition in the GenerateChangeSet deploy action configures the name of the SAM file that is generated to provision the Lambda function that was packaged and stored in the PackageExport build action. This file is used by SAM to transform into a CloudFormation template that is executed by the ExecuteChangeSet action.
CodePipelineStack: Type: AWS::CodePipeline::Pipeline DependsOn: - CodeBuildWebsite - LambdaTrustRole Properties: RoleArn: Fn::Join: - '' - - 'arn:aws:iam::' - Ref: AWS::AccountId - ":role/" - Ref: CodePipelineRole Stages: - Name: Source Actions: - InputArtifacts:  Name: Source ActionTypeId: Category: Source Owner: AWS Version: '1' Provider: CodeCommit OutputArtifacts: - Name: MyApp Configuration: BranchName: Ref: RepositoryBranch RepositoryName: Ref: AWS::StackName RunOrder: 1 - Name: Build Actions: - InputArtifacts: - Name: MyApp Name: PackageExport ActionTypeId: Category: Build Owner: AWS Version: '1' Provider: CodeBuild OutputArtifacts: - Name: alexa-BuildArtifact Configuration: ProjectName: Ref: CodeBuildWebsite RunOrder: 1 - Name: Deploy Actions: - InputArtifacts: - Name: alexa-BuildArtifact Name: GenerateChangeSet ActionTypeId: Category: Deploy Owner: AWS Version: '1' Provider: CloudFormation OutputArtifacts:  Configuration: ActionMode: CHANGE_SET_REPLACE ChangeSetName: pipeline-changeset RoleArn: Fn::GetAtt: - CloudFormationTrustRole - Arn Capabilities: CAPABILITY_IAM StackName: Fn::Join: - '' - - "" - Ref: AWS::StackName - "-" - Ref: AWS::Region - "" TemplatePath: alexa-BuildArtifact::template-export.json RunOrder: 1 - ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: 1 Configuration: ActionMode: CHANGE_SET_EXECUTE ChangeSetName: pipeline-changeset StackName: Fn::Join: - '' - - "" - Ref: AWS::StackName - "-" - Ref: AWS::Region - "" InputArtifacts:  Name: ExecuteChangeSet OutputArtifacts:  RunOrder: 2 ArtifactStore: Type: S3 Location: !Ref ArtifactBucket
Serverless Application Model
With the AWS Serverless Application Model (SAM), you can simplify the process of packaging a serverless application and deploying it with CloudFormation. The sam-template.yml below is a file that uses the SAM to define an Alexa skill function. Using the CloudFormation generate and execute change set defined in the CodePipeline provisioning in CloudFormation, this file transforms to a CloudFormation template. Fn::ImportValue pulls the export value from main CloudFormation template that provisions this solution.
AWSTemplateFormatVersion: 2010-09-09 Transform: - AWS::Serverless-2016-10-31 Resources: AlexaSkillFunction: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs4.3 Role: Fn::ImportValue: !Join ['-', [!Ref 'AWS::StackName', 'LambdaTrustRole']] Events: AlexaSkillEvent: Type: AlexaSkill
Since costs can vary as you use certain AWS services and other tools, you can see a cost breakdown and some sample scenarios to give you an idea of what your monthly spend might look like. Note this will be dependent on your unique environment and deployment, and the AWS Cost Calculator can assist in establishing cost projections.
- CloudFormation: No additional cost.
- CodeBuild: CodeBuild charges per minute used. It comes with 100 minutes per month at no charge. For a simple execution of this demo, you can stay within the limits of the AWS Free Tier – please read about the Free Tier here. For more information, see AWS CodeBuild pricing.
- CodeCommit: If used on a small project of less than six users, there’s no additional cost. See AWS CodeCommit Pricing for more information.
- CodePipeline: Customers can create new pipelines without incurring any charges on that pipeline for the first thirty calendar days. After that period, the new pipelines will be charged at the existing rate of $1 per active pipeline per month. For more information, see AWS CodePipeline pricing.
- Lambda: Considering you likely won’t have over 1M requests for this particular solution, there’s no cost. The Lambda free tier includes 1M free requests per month and 400,000 GB-seconds of compute time per month. For more information, see AWS Lambda Pricing.
- Alexa: There is no direct cost associated with using the Alexa service. If you’re using an Amazon Echo device, there is a one-time payment for the hardware and you’re charged every time your Lambda function is run (once it exceeds 1M free requests per month).
- IAM: No additional cost.
- SNS: Considering you likely won’t have over 1 million Amazon SNS requests for this particular solution, there’s no cost. For more information, see AWS SNS Pricing.
There are three main steps in launching this solution: preparing an AWS account, launching the stack, and testing the deployment. Each is described in more detail in this section. Please note that you are responsible for any charges incurred while creating and launching your solution.
Step 1: Prepare an AWS Account
- If you don’t already have an AWS account, create one at http://aws.amazon.com by following the on-screen instructions. Part of the sign-up process involves receiving a phone call and entering a PIN using the phone keypad. Be sure you’ve signed up for the CloudFormation service.
- Use the region selector in the navigation bar of the console to choose the Northern Virginia (us-east-1) region
Step 2: Launch the Stack
Click on the “Launch Stack” button below to launch the CloudFormation stack. Before you launch the stack, review the architecture, configuration, and other considerations discussed in this post. To download the template, click here.
Time to deploy: Approximately 5 minutes
The template includes default settings that you can customize by following the instructions in this post.
Step 3: Test the Deployment
To test the deployment, you will need to configure the Alexa skill using the Amazon Developer Portal. You can use the Amazon Alexa Developer portal, a tool called Echosim, or an actual Amazon Echo device to test your skill.
Upload Code Assets to CodeCommit
- Once the CloudFormation stack is complete, select checkbox next to the stack and go to the Outputs tab
- Click on the PipelineUrl link to launch the CodePipeline pipeline. The Source action will be in a failed state.
- From the pipeline, click on the CodeCommit link and copy the command under “Clone your repository to your local computer and start working on code” to your clipboard.
- From your Terminal, paste the command contents to a computer for which you have configured a git client.
- Copy all the files from your locally-cloned Git repository (for https://github.com/stelligent/devops-essentials/tree/master/samples/serverless/alexa) to the CodeCommit repository you just cloned.
- From your Terminal, type
git add .
- From your Terminal, type:
git commit -am "add new files" && git push
- Go back to your pipeline in CodePipeline and see the changes successfully flow through the pipeline.
Configure and Test Your Alexa Skill
At this time, you can’t just click a “Launch Stack” button to deploy an Alexa skill. Separately, you need to configure the Alexa skill to define the intent schema, sample utterances and, most relevant, the Lambda function ARN that was deployed as part of the CodePipeline pipeline. To configure and test your Alexa skill, follow the steps defined below.
- Once your pipeline has successfully completed, go to https://developer.amazon.com/alexa and click the Sign In link
- Use your Amazon credentials to login to the Amazon Developer portal
- Select Alexa
- Under Alexa Skills Kit select Get Started
- Click Add a New Skill
- Enter a Name and Invocation Name and Choose Save
- Click Next
- In the Intent Schema text area, enter the contents from IntentSchema.json.
- In the Sample Utterances text area, enter the contents from SampleUtterances_en_US.txt.
- Click Next
- Choose the AWS Lambda ARN (Amazon Resource Name) radio button in the Service Endpoint Type section.
- Choose the North America checkbox
- Go to the Lambda console and choose the radio button next to the function that the CodePipeline pipeline generated. Then, choose the Actions button and select the Show ARN item and copy the contents that are displayed to your clipboard.
- Go back to the Amazon Developer Portal and paste your clipboard contents to the North America text box.
- Click Next
- In the Service Simulator section, enter “tell me a space fact” in the Enter Utterance text box and click Ask (the name of your skill). You should see a valid response in the Lambda Response text area. Go to SampleUtterances_en_US.txt for some other examples to simulate.
There are three stages and four actions that compose the pipeline that orchestrates the deployment of the Lambda function used by the Amazon Alexa service.
- Source: In the single Source action, it uses the CodeCommit source action type to store all the code assets for the Alexa skill, infrastructure, and deployment pipeline
- Build: In the single PackageExport action, it uses the CodeBuild build action type to package and store the Lambda function and associated files
- GenerateChangeSet: Uses the CloudFormation deploy action type to generate a change set for a CloudFormation template that defines the Lambda function
- ExecuteChangeSet: Uses the CloudFormation deploy action type to generate a change set on the CloudFormation template to deploy the Lambda function
Figure 4 illustrates annotates the stages and actions of this deployment pipeline.
Figure 4: Annotated Deployment Pipeline for Solution
DevOps Essentials on AWS Complete Video Course
This and many more topics are covered in the DevOps Essentials on AWS Complete Video Course (release date: August 2017). In it, you’ll learn how to automate the infrastructure and deployment pipelines using AWS services and tools so if you’re some type of software or DevOps-focused engineer or architect interested in learning how to use AWS Developer Tools to create a full-lifecycle software delivery solution, it’s the course for you. The focus of the course is on deployment pipeline architectures and its implementations.
Here are some of the supporting resources discussed in this post:
- DevOps Essentials on AWS Course Website
- Source code for this post
- Alexa Skill Sample Node.js fact
- GitHub: Open Source Examples from the Course
Did you find this post interesting? Are you passionate about working with the latest AWS technologies? If so, Stelligent is hiring and we would love to hear from you!