ASK CLI を使って Alexa Custom Skills をデプロイしよう (2) buildspec作成 〜 デプロイ


はじめに

前回の投稿に引き続き、本投稿ではASK CLIを利用したデプロイ方法についてご紹介します。
本投稿では、buildspecの作成〜デプロイについてをご紹介します。

前回のおさらい

buildspecを作成するにあたり、前回までに決めたことのおさらいをします。

AWS CodeBuild のビルド仕様に関するリファレンス

各フェーズについて

フェーズ 概要 やること
install インストール ask-cliインストール
pre-build ビルド前処理 AWSCLI設定、ASKCLI設定
build ビルド処理 依存解決、トランスパイル
post-build ビルド後処理 ごみファイル掃除、デプロイ

パラメータストアについて

名前 種類 キーID
alexa-aws-access-key-id SecureString alias/AlexaEncryptionKey
alexa-aws-secret-access-key SecureString alias/AlexaEncryptionKey
alexa-lwa-access-token SecureString alias/AlexaEncryptionKey
alexa-lwa-refresh-token SecureString alias/AlexaEncryptionKey

環境変数について

名前 タイプ
ALEXA_VENDOR_ID {使用しているベンダーID} プレーンテキスト
ALEXA_SKILL_ID {使用しているスキルID} プレーンテキスト
AWS_LAMBDA_FUNCTION_NAME custom-skill-sample-to-convert プレーンテキスト

buildspec.ymlを作ろう

さっそくファイルを作ります。

移動
$ cd ~/custom-skill-sample-to-convert
buildspec.ymlの作成
$ touch ./buildspec.yml

これを参考に順番に書いていきます。

AWS CodeBuild のビルド仕様に関するリファレンス

変数、パラメータストアの定義

前回作成したパラメータストアを読み込む為に以下を定義します。

コマンド

env:
  # 変数宣言
  variables:
    # AWS CLI プロファイル名
    AWS_CLI_PROFILE_NAME: alexa-custom-skill-profile
  # パラメータストア宣言
  parameter-store:
    # AWS アクセスキーID
    AWS_ACCESS_KEY_ID: "alexa-aws-access-key-id"
    # AWS シークレットアクセスキー
    AWS_SECRET_ACCESS_KEY: "alexa-aws-secret-access-key"
    # LWA アクセストークン
    LWA_ACCESS_TOKEN: "alexa-lwa-access-token"
    # LWA リフレッシュトークン
    LWA_REFRESH_TOKEN: "alexa-lwa-refresh-token"

各フェーズの定義

install

インストールでは、以下の作業を行います。

  • aws-cliのアップデート
  • ask-cliのインストール

ここはさくっといきます。

コマンド

# ビルド環境でのパッケージのインストール
  install:
    commands:
      # メッセージ
      - echo install phase...
      # 現在のディレクトリを確認
      - pwd && ls -la
      # AWS-CLI アップデート
      - pip install awscli --upgrade
      # ASK-CLI インストール
      - npm install -g ask-cli
      # 各種バージョン確認
      - npm --version && aws --version && ask -v

pre_build

ビルド前処理では、以下の作業を行います。

  • AWS CLI設定
  • ASK CLI設定

AWS CLI設定

ASK CLIはAWSアカウントの資格情報を使用します。以下は公式ドキュメントからの引用です。

CLIのインストールと使用方法

AWSアカウントの資格情報。ask-cliツールは、次の場所にある資格情報ファイルから、それらの資格情報にアクセスします。

~/.aws/credentials 

資格情報をセットアップするには、AWS CLIツールをインストールするか、手動で構成します。同じファイル内に複数の資格情報のセットを保持できますが、ask-cliツールが使用するのはデフォルトの資格情報だけです。

AWSアカウントの資格情報のセットアップはウィザード形式ではなくaws configure setを使用し、必要な設定値を設定します。

AWS CLI コマンドリファレンス - aws configure set

ASK CLIの設定

次にASK CLIの設定です。
ASK CLIの設定ファイルは以下の2種類があります。

  • ~/.ask/cli_config
  • ~/custom-skill-sample-to-convert/skill/.ask/config

Amazon開発者アカウントに関連付けられているスキルをCLIで作成および変更するための認証を設定するには、initコマンドを実行する必要があります。

これらのファイルは、前述した通りinitコマンドを実行し事前にセットアップすることで作成されます。
本投稿では、既にセットアップ済みである前提で進めます。

CodeBuild環境ではinitコマンドによるセットアップではなく、これらのファイルを手動でセットアップしてあげます。
セットアップ方法はいくつか候補があるかと思いますが、本投稿ではenvsubstコマンドを利用します。

参考 envsubstを使ってShellでテンプレートエンジン的なことをする、Dockerコンテナ起動時にファイルを生成する - Hatena Blog

envsubstコマンドを利用することで環境変数を利用したファイル出力が可能となります。

予め上記2ファイルのテンプレートファイルを準備し、envsubstコマンドを利用しセットアップを行います。

テンプレートファイルの作成
移動
$ cd ~/custom-skill-sample-to-convert/skill
ディレクトリ作成
$ mkdir -p ./templates
テンプレートファイルの作成
$ touch ./templates/cli_config.tmpl
$ touch ./templates/config.tmpl
cli_config.tmpl
{
  "profiles": {
    "default": {
      "aws_profile": "${AWS_CLI_PROFILE_NAME}",
      "token": {
        "access_token": "${LWA_ACCESS_TOKEN}",
        "refresh_token": "${LWA_REFRESH_TOKEN}",
        "token_type": "bearer",
        "expires_in": 3600,
        "expires_at": "2018-03-19T00:00:00.000Z"
      },
      "vendor_id": "${ALEXA_VENDOR_ID}"
    }
  }
}
config.tmpl
{
  "deploy_settings": {
    "default": {
      "skill_id": "${ALEXA_SKILL_ID}",
      "was_cloned": false,
      "merge": {
        "manifest": {
          "apis": {
            "custom": {
              "endpoint": {
                "uri": "${AWS_LAMBDA_FUNCTION_NAME}"
              }
            }
          }
        }
      }
    }
  }
}

endpoint -> uriでは、ファンクション名以外にARNも指定できます。

コマンド

# ビルド前処理
  pre_build:
    commands:
      # メッセージ
      - echo pre_build phase...
      # AWS-CLI 設定
      - aws configure --profile $AWS_CLI_PROFILE_NAME set aws_access_key_id $AWS_ACCESS_KEY_ID
      - aws configure --profile $AWS_CLI_PROFILE_NAME set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
      - aws configure --profile $AWS_CLI_PROFILE_NAME set default.region $AWS_REGION_NAME
      # ディレクトリ移動
      - cd ./skill
      # ASK-CLI 設定
      - mkdir -p ~/.ask && cat ./templates/cli_config.tmpl | envsubst > ~/.ask/cli_config
      # ASK-CLI スキル設定
      - mkdir -p ./.ask && cat ./templates/config.tmpl | envsubst > ./.ask/config

build

ビルドでは、以下の作業を行います。

  • モジュールの依存解決(すべて)
  • トランスパイル
  • モジュールの削除
  • モジュールの依存解決(dependenciesのみ)

ここもさくっといきます。

コマンド

# ビルド
  build:
    commands:
      # メッセージ
      - echo build phase...
      # ディレクトリ移動
      - ls -la && cd ./lambda/custom && ls -la
      # npmインストール
      - npm install --loglevel error
      # トランスパイル
      - $(npm bin)/tsc
      # node_modules削除
      - rm -rf ./node_modules
      # パッケージ復元
      - npm install --production --loglevel warn

post_build

ビルド後処理では、以下の作業を行います。

  • 不要ディレクトリ、ファイルの掃除(任意)
  • デプロイ

ここもさくっといきます。

コマンド

# ビルド後処理
  post_build:
    commands:
      # メッセージ
      - echo Build completed on
      # 不要ディレクトリ、ファイル削除
      - rm -rf coverage mytypes src tsconfig.json tslint.json
      # 2つ上のディレクトリへ移動
      - cd ../.. && ls -la
      # デプロイ
      - ask deploy

動作確認

buildspecその他ファイルをstagingブランチへプッシュします。

失敗しました\(^o^)/

Phase context status code: Variables Error Message: AccessDeniedException:
User: arn:aws:sts::{account_id}:assumed-role/code-build-typescript-de-tsukuro-service-role/AWSCodeBuild-xxxx
is not authorized to perform: ssm:GetParameters on resource:
arn:aws:ssm:us-east-1:{account_id}:parameter/alexa-aws-secret-access-key

前回の投稿で作成した暗号化キー/パラメータストアですが、図ではus-east-1に作成としていました。
が、東京リージョンに作成していました。。。(修正しておきます。)
us-east-1に作成していないのと、ポリシー設定をしていないので異常終了しました。

改めてus-east-1に暗号化キー/パラメータストアを作成し、プッシュします。

成功しました\(^o^)/

まとめ

本投稿では、以下のことを行いました。

  • buildspec.ymlの作成
  • stagingブランチへ変更をプッシュ
  • デプロイの確認

前回の投稿でお伝えした課題がありつつも、自動化することによって効率は間違いなくあがると思います。

現状はASK CLIで出来ることは限られていますが、AWS CLIや他の仕組みを組み合わせることによって
より柔軟なCI/CD環境が構築できるのではないでしょうか。

本投稿がより良いアイデアの参考になれば幸いです。