AlexaスキルのデプロイがAWSだけで完結できるようになったのでやってみる

2019/2/23 デプロイに時間がかかる場合の対処方法を記載しました。

## はじめに
CloudFormationとCodePipelineがAlexaスキルをサポートし、AWS側の操作のみで
スキルのデプロイが完結できるようになりました。
更にCodeStarにAlexaスキル用のプロジェクトテンプレートが用意されているので
サンプルスキル&デプロイパイプラインの作成が超速で行えます。

**Quickly Create, Build, and Deploy Amazon Alexa Skills from AWS**
https://aws.amazon.com/jp/about-aws/whats-new/2018/12/quickly-create-build-and-deploy-amazon-alexa-skills-from-aws/
**Build and Deploy Alexa Skills Faster with New AWS Integration**
https://developer.amazon.com/ja/blogs/alexa/post/997dff67-2d0e-4403-aa74-8aef7ca4c432/build-and-deploy-alexa-skills-faster-with-new-aws-integrations

## やってみる
用意されているプロジェクトテンプレートからサンプルスキルをデプロイして
スキルを日本語対応するところまでやってみたいと思います。
コードの編集にCloud9を使用したいため、この記事内では東京リージョンではなく
バージニア北部リージョンで作業していますが、Alexaスキル用のプロジェクトテンプレートは
東京リージョンのCodeStarでも利用可能です。

### CodeStar新規プロジェクトの作成
CodeStarコンソールから新規プロジェクトを追加します。
テンプレートの選択画面のアプリケーションのカテゴリでAlexaスキルにチェックを入れます。
node.jsとPython用のテンプレートが用意されています。ここではPythonを選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/d1ef86df-1978-fde1-9312-af30f2b4648f.png)
プロジェクトの詳細でプロジェクト名を設定します。
ここではレポジトリはCodeCommitを使用します。
AWS側から対話モデルのデプロイを行うためにAmazon Developer Accountへの接続が必要です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/fc83e315-3d7c-3801-92f4-0243198528fb.png)
Amazon Developer Accountのログイン画面が表示されるので、認証情報を入力します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/3cb5866a-3b20-a18d-c751-373413d96dfd.png)

アクセス権限に関する確認画面が表示されますので、許可します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/8e6e4774-2bc0-d09f-725e-e90b16efb17a.png)
接続が完了したら次へを押して、プロジェクト詳細を確認し、プロジェクトの作成を行います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/d66724d8-4db8-e8e8-2eac-1122785cf825.png)
コードの編集方法の選択では AWS Cloud9を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/eef36850-dcc4-3b63-cfc4-3b57de5b6498.png)
Cloud9の環境のセットアップは全てデフォルトのまま次へ進みます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/70eea5d9-b0be-cbd3-d512-5677bb3128a1.png)
CodeStarプロジェクトとIDEのセットアップが完了するまで、ちょっとだけ待ちます。
プロジェクトの作成が完了するとCodePipelineによって対応モデルのデプロイと
Lambda関数の初回デプロイが自動で行われます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/60dc894a-8ad7-040d-f03f-d5e33f303169.png)
Amazon Developer Consoleを確認すると、hello pythonがデプロイされています！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/8873e45f-3ab1-9924-37b1-46a707e58e31.png)

### サンプルスキルの日本語化～デプロイまで
せっかくなのでサンプルスキルを日本語化してみましょう。
ダッシュボードの上部からコーディングの開始を選択するとCloud9が開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/5eb23a9c-32b8-d72d-d60c-f5052ddb11ab.png)

自動的にCodeCommit上のレポジトリがCloud9のローカルにcloneされます。
#### ステップ1 localeの変更
skill.jsonを開いてlocalesの en-US を ja-JP に修正します。

```skill.json
{
  "manifest": {
    "publishingInformation": {
      "locales": {
        "ja-JP": {
          "summary": "A basic skill made from Alexa Skills Kit template",
          "examplePhrases": [
            "Alexa open hello python",
            "Alexa tell hello python hello",
            "Alexa ask hello python say hello"
          ],
          "name": "hello python",
          "description": "A basic skill made from Alexa Skills Kit template"
        }
      },
      "isAvailableWorldwide": true,
      "testingInstructions": "Sample Testing Instructions.",
      "category": "EDUCATION_AND_REFERENCE",
      "distributionCountries": []
    },
    "apis": {
      "custom": {
      }
    },
    "manifestVersion": "1.0"
  }
}
```
次に interactionModels/custom/en-US.json を
interactionModels/custom/ja-JP.jsonにリネームします。
更に ja-JP.json を開いて、invocation Name を任意に設定します。
サンプル発話も適当に設定しちゃいます。

```ja-JP.json
{
    "interactionModel": {
        "languageModel": {
            "invocationName": "こんにちぱいそん",
            "intents": [
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.HelpIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.StopIntent",
                    "samples": []
                },
                {
                    "name": "HelloWorldIntent",
                    "slots": [],
                    "samples": [
                        "hello",
                        "こんにちは",
                        "こんにちぱいそん"
                    ]
                }
            ],
            "types": []
        }
    }
}
```

次にlambda/custom/hello_world.py のメッセージを日本語化します。
各Handler の spech_testの内容を日本語に書き換えます。
以下はLaunchRequestHandlerの例です。

```（一部抜粋）hello_world.py
class LaunchRequestHandler(AbstractRequestHandler):
    """Handler for Skill Launch."""
    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool
        return is_request_type("LaunchRequest")(handler_input)

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response
        speech_text = "ようこそ、こんにちはと言ってみてください。"
        handler_input.response_builder.speak(speech_text).ask(speech_text)
        return handler_input.response_builder.response
```

#### ステップ2 変更の反映
Cloud9上のbashターミナルで以下のようにgitを操作し、変更をCodeCommitへpushします。

```bash

$ cd alexa-helloworld
$ git add .
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        renamed:    interactionModels/custom/en-US.json -> interactionModels/custom/ja-JP.json
        modified:   lambda/custom/hello_world.py
        modified:   skill.json
$ git commit -m "hello python の日本語化"
$ git push
```

#### ステップ3 動作確認
CodeCommitへのpushが成功すれば自動的にPipelineが起動して
対話モデルとLambda関数のデプロイまでおこなってくれます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/37ee0da5-68d3-ef9f-1aff-a92b9ec0c591.png)
デプロイが成功したらAmazon Develper Consoleを再度確認してみましょう。

hello python の言語が日本語に変わっています。
対話モデルのビルドも成功しているようです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/cf7c0363-29b5-2884-436d-58af24e6ee2f.png)
hello python 開いてシミュレーターでテストしてみます。
デフォルトではテストが無効になっているので開発中に変更します。
うまくいきました！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/f528c0e9-22cd-b17e-3602-e772418b95b3.png)

## デプロイに時間がかかる場合の対処方法
HelloWorldスキルのプロジェクトテンプレートは1回のデプロイに
**10分以上**時間がかかる場合があります。
CodeDeployのデプロイ設定がデフォルトで CodeDeployDefault.LambdaCanary10Percent5Minutes
（最初の増分でトラフィックの 10 パーセントを移行し、残りの 90 パーセントは 5 分後にデプロイされる）
に設定されているためです。
特に開発中などは デプロイ設定を CodeDeployDefault.LambdaAllAtOnce とすることで
5分ほどデプロイ時間を短縮可能です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/aad5863b-3ef2-1321-31d3-64c63b7301c5.png)

コードデプロイのアプリケーションから、対象プロジェクトのLambdaを選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/43f509bd-9bcd-5d6f-d012-78def47a51c8.png)

デプロイグループの詳細から編集をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/5dd2083b-c6d9-36be-8c65-7d4c30778182.png)

デプロイグループの編集でデプロイ設定を CodeDeployDefault.LambdaAllAtOnce に
変更し、保存します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/b3d26106-6ee1-82e4-216c-089fce6a2223.png)





## ドキュメント
**CloudFormation - Alexa Resource Types Reference**
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-reference-alexa.html
**Tutorial: Create a Pipeline that Deploys an Amazon Alexa Skill**
https://docs.aws.amazon.com/codepipeline/latest/userguide/tutorials-alexa-skills-kit.html

以上です。
参考になれば幸いです。