Create a new Alexa Custom skill by using ask-cli v2 with AWS CloudFormation
In 2020, ASK CLI version 2 has been published by Alexa team. We can manage our skill backend by using AWS Clou […]
目次
In 2020, ASK CLI version 2 has been published by Alexa team. We can manage our skill backend by using AWS CloudFormation.
Let’s get start!
Create a new Project
We can create a new project from ask new
. It’s same as v1.
Step1: Select language
% ask new
Please follow the wizard to start your Alexa skill project ->
? Choose the programming language you will use to code your skill: (Use arrow keys)
❯ NodeJS
Python
Java
Step2: Select backend resources
This step is the most important update of v2. I think.
We can select backend resource type from Hosted
/ AWS CloudFormation
/ AWS Lambda
/ self-hosted
. Version 1 can select only AWS Lamda
.
? Choose a method to host your skill's backend resources: (Use arrow keys)
❯ Alexa-hosted skills
Host your skill code by Alexa (free).
AWS with CloudFormation
Host your skill code with AWS services and provision with AWS CloudFormation (requires AWS account)
AWS Lambda
Host your skill code on AWS Lambda (requires AWS account).
──────────────
self-hosted and manage your own hosting
Step3: Select template
Now we can select three type of example. Probably these example number will be increased.
? Choose a template to start with: (Use arrow keys)
❯ Hello world Alexa's hello world skill to send the greetings to the world!
Fact skill Quick sample skill to manage a collection of voice data.
High low game Guess a number high or low using persistent attributes. Make sure your AWS account has the permission to manage DynamoDB!
Step4: Put project information
Finally, we can put the skill name and project directory name.
? Please type in your skill name: example-skill
? Please type in your folder name for the skill project (alphanumeric): exampleSkill
We can get the following files in the project directory.
% tree
.
├── LICENSE.txt
├── ask-resources.json
├── infrastructure
│ └── cfn-deployer
│ └── skill-stack.yaml
├── lambda
│ ├── index.js
│ ├── package.json
│ └── util.js
└── skill-package
├── assets
│ ├── en-US_largeIcon.png
│ └── en-US_smallIcon.png
├── interactionModels
│ └── custom
│ └── en-US.json
└── skill.json
7 directories, 10 files
How can we customize the project?
The project seems to be a separate directory per feature.
- ask-resources.json: Skill configuration (CloudFormation props / Code URI etc…)
- infrastructure: backend resources definition.
( In this case, placed CloudFormation stack template) - lambda: Lambda source code
- skill-package: Skill configurations. ( Interaction Model / assets / publication information / etc..)
We can go to these directory and edit these files for own skill style.
Deploy it
Deployment workflow is same as v1. Just run ask deploy
command.
Then, the CLI will deploy entire resources by SMAPI and AWS CloudFormation.
How can we check the created resources from AWS CloudFormation
We can check the deployed skill information from .ask/ask-states.json
.
So we can check the skill’s CloudFormation by the following command.
% aws cloudformation describe-stack-resources --stack-name $(cat .ask/ask-states.json | jq ".profiles.default.skillInfrastructure[\"@ask-cli/cfn-deployer\"].deployState.default.stackId" -r) | jq .
{
"StackResources": [
{
"StackName": "example-skill-default-skillStack-1587380830650",
"StackId": "arn:aws:cloudformation:us-east-1:99999999:stack/example-skill-default-skillStack-1587380830650/1e4f54f0-82f7-11ea-86a4-0eb40de15aba",
"LogicalResourceId": "AlexaSkillFunction",
"PhysicalResourceId": "example-skill-default-skillSt-AlexaSkillFunction-19SAEJO5SZMBP",
"ResourceType": "AWS::Lambda::Function",
"Timestamp": "2020-04-20T11:07:47.639Z",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "example-skill-default-skillStack-1587380830650",
"StackId": "arn:aws:cloudformation:us-east-1:99999999:stack/example-skill-default-skillStack-1587380830650/1e4f54f0-82f7-11ea-86a4-0eb40de15aba",
"LogicalResourceId": "AlexaSkillFunctionEventPermission",
"PhysicalResourceId": "example-skill-default-skillStack-1587380830650-AlexaSkillFunctionEventPermission-14T7X7Q1K8HFM",
"ResourceType": "AWS::Lambda::Permission",
"Timestamp": "2020-04-20T11:08:00.883Z",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "example-skill-default-skillStack-1587380830650",
"StackId": "arn:aws:cloudformation:us-east-1:99999999:stack/example-skill-default-skillStack-1587380830650/1e4f54f0-82f7-11ea-86a4-0eb40de15aba",
"LogicalResourceId": "AlexaSkillIAMRole",
"PhysicalResourceId": "example-skill-default-skillSta-AlexaSkillIAMRole-YFXEA2L5SOA4",
"ResourceType": "AWS::IAM::Role",
"Timestamp": "2020-04-20T11:07:44.055Z",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
}
]
}
Customize AWS CloudFormation
We can customize our Alexa Skill backend more easily. Because we can use AWS CloudFormation (and AWS SAM) !
This example code is add S3:GetObject
action to your S3 buckets.
AWSTemplateFormatVersion: 2010-09-09
Parameters:
SkillId:
Type: String
LambdaRuntime:
Type: String
LambdaHandler:
Type: String
CodeBucket:
Type: String
CodeKey:
Type: String
CodeVersion:
Type: String
Resources:
AlexaSkillIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: /
Policies:
- PolicyName: alexaExternalPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- s3:GetObject
Resource: arn:aws:s3:::*
- PolicyName: alexaSkillExecutionPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:*
Resource: arn:aws:logs:*:*:*
AlexaSkillFunction:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref CodeBucket
S3Key: !Ref CodeKey
S3ObjectVersion: !Ref CodeVersion
Handler: !Ref LambdaHandler
Runtime: !Ref LambdaRuntime
Role: !GetAtt AlexaSkillIAMRole.Arn
MemorySize: 512
Timeout: 60
AlexaSkillFunctionEventPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:invokeFunction
FunctionName: !GetAtt AlexaSkillFunction.Arn
Principal: alexa-appkit.amazon.com
EventSourceToken: !Ref SkillId
Outputs:
SkillEndpoint:
Description: LambdaARN for the regional endpoint
Value: !GetAtt AlexaSkillFunction.Arn
Conclusion
By using ASK CLI (version2), we can maintain more scalable Alexa skill using various AWS resources more easily.