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.

    広告ここから
    広告ここまで

    Random posts

    Home
    Search
    Bookmark