Amazon SageMaker エンドポイント用のサーバーレスフロントエンドを構築する(開発環境: Cloud9版)

# はじめに
本記事は[Amazon SageMaker エンドポイント用のサーバーレスフロントエンドを構築する](https://aws.amazon.com/jp/blogs/news/build-a-serverless-frontend-for-an-amazon-sagemaker-endpoint/)を一部変更して実施したものです。

変更内容は、開発環境をEC2からCloud9に変えた事です。

リージョンは「バージニア北部(us-east-1)」でお願いします。

# ゴール
機械学習を使って、Sepal Length（がく片の長さ）、Sepal Width（がく片の幅）、Petal Length（花びらの長さ）、Petal Width（花びらの幅）の値からアヤメの品種(Setosa, Versicolor, Virginica)を特定するWebアプリの構築。

![iris.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/6a0f5215-a09c-48e4-1e74-17359b9d7a10.png)

# SageMaker - モデル作成～エンドポイント作成
コンソールのTOPページからSageMakerの画面に移動。

## モデルの作成
左側のメニューの中の「モデル」をクリックして、「モデルの作成」をクリック。
![sagemaker-01.png](https://qiita-image-store.s3.amazonaws.com/0/128060/ccffed1c-a5e4-b035-9a15-d154c01df259.png)

「モデル名」に`decision-trees`を入力して、IAM ロールは「新しいロールの作成」を選択して、下図設定に合わせて「ロールの作成」をクリック。
![sagemaker-02.png](https://qiita-image-store.s3.amazonaws.com/0/128060/89075771-6fa9-e336-302e-a48d681bb80a.png)

下図画面の様になります。（IAMロール名は若干違いあり）
![sagemaker-03.png](https://qiita-image-store.s3.amazonaws.com/0/128060/5eb2f0da-02f7-93f2-2987-2b3a24f6d3e2.png)

そのまま下にスクロールして、「コンテナの定義1」に下記内容を入力して「モデルの作成」をクリック。
- 推論コードイメージの場所: `305705277353.dkr.ecr.us-east-1.amazonaws.com/decision-trees-sample:latest`
- アーティファクトの場所 - オプション: `s3://aws-machine-learning-blog/artifacts/decision-trees/model.tar.gz`

## エンドポイント設定の作成
左側のメニューの中の「エンドポイント設定」をクリックして、「エンドポイント設定の作成」をクリック。
![sagemaker-04.png](https://qiita-image-store.s3.amazonaws.com/0/128060/281f0afc-8993-c92b-7f7e-7197c39d3dc6.png)

「エンドポイント設定名」に`decision-trees`を入力して、「モデルの追加」をクリック。
![sagemaker-05.png](https://qiita-image-store.s3.amazonaws.com/0/128060/2ca96bc1-a2d9-3695-ac8a-f94efd5c27f9.png)

`decision-trees`を選択して、「保存」をクリック。
![sagemaker-06.png](https://qiita-image-store.s3.amazonaws.com/0/128060/e371d99e-e316-375e-1444-de709e143ef1.png)

元の画面に戻ったら下にスクロールして「エンドポイント設定の作成」をクリック。

## エンドポイントの作成
左側のメニューの中の「エンドポイント」をクリックして、「エンドポイントの作成」をクリック。
![sagemaker-07.png](https://qiita-image-store.s3.amazonaws.com/0/128060/306d9ab8-cd9d-272f-36cb-a895e21e3ec2.png)


エンドポイントの設定を下記の通りに入力して、「エンドポイント設定の選択」をクリック。
- エンドポイント名: `decision-trees`
- エンドポイント設定のアタッチ: `既存のエンドポイント設定の使用`
- エンドポイント設定: `decision-trees`

![sagemaker-08.png](https://qiita-image-store.s3.amazonaws.com/0/128060/d6f29664-8212-5870-0e84-feda5b4d7c8f.png)

「新しいエンドポイントの設定」が表示されるので内容を確認して、「エンドポイントの作成」をクリック。
![sagemaker-09.png](https://qiita-image-store.s3.amazonaws.com/0/128060/adf9651f-8285-f12a-835b-578a2ba38458.png)


# IAM - Credentials(AdministratorAccess)の取得
Cloud9のターミナルでCLIによる操作を実行するための権限を持ったユーザーを作成。

## アクセスキーIDとシークレットアクセスキーの取得

コンソールのTOPページからIAMの画面に移動。

左のメニューから「ユーザー」をクリックして、「ユーザーを追加」をクリック。
![iam-02.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/b96228c6-3259-b7a3-8054-8c85b571782c.png)

任意のユーザー名(画面は`admin`)を入力して、「アクセスの種類」-「プログラムによるアクセス」にチェックをいれて「次のステップ: アクセス権限」をクリック。
![iam-03.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/49bf51d9-8cb6-0b79-6ace-67f65c372e0b.png)

「既存のポリシーを直接アタッチ」をクリックして、「AdministratorAccess」にチェックをつけて「次のステップ: タグ」をクリック。
![iam-04.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/8ba6a78e-b102-2e32-6afc-63771e397d6f.png)

何も入力せずに「次のステップ: 確認」をクリック。

設定内容を確認して「ユーザーの作成」をクリック。

アクセスキーIDとシークレットアクセスキーをメモして「閉じる」をクリック。（注. シークレットアクセスキーは後で確認できません）

![iam-05.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/42705971-2ee7-410a-2632-134ac3ae7637.png)


# Cloud9
開発環境を構築。

## Cloud9の環境構築・設定

コンソールのTOPページからCloud9の画面に移動して、「Create Envionment」をクリック。
![cloud9-00.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/48fb7440-591c-adf1-ace9-c173227334e5.png)

任意の名前(画面は`jaws-ug-ehime20`)を入力
![cloud9-01.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/14737818-00cf-861f-491b-50383a0462c8.png)

デフォルトのまま「Next Step」をクリック
![cloud9-02.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/a89f68fc-cff9-7234-fc7d-9ce950646f3d.png)

確認画面が出るので、内容を確認して「Create Environment」をクリック
![cloud9-03.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/1d9238d9-3ef9-c240-c7a5-65db5b16cb6e.png)

画面右上の「Preferences（歯車のアイコン）」をクリックして、Preferences画面が出現したら、「Python Support」をクリックして、「Python Version」を`Python 3`に変更。
![cloud9-04.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/f6602cdc-c17f-dcf7-8a7f-69419853edcf.png)

画面下のコンソール画面から呼び出すpythonを3系に変更

画面下のコンソール画面で下記コマンドを実行。

```
alias python=python36
```

```
alias pip=pip-3.6
```
![cloud9-05.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/83c7dc5c-42fb-52c3-afea-9d10c416a39e.png)

リージョンを設定
「AWS SETTINGS」をクリックして、「AWS Region」をSageMakerのエンドポイントのリージョンに合わせる
![cloud9-06.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/bcb00452-5874-e80d-1a0b-4efbbb165422.png)

# Chaliceのセットアップ
Chaliceとは: AWS Lambda & API Gatewayを使ったPythonサーバーレスフレームワーク
Chaliceのメリット:ソースコードを解析して、必要なポリシーを特定、作成・更新・削除を自動的に行ってくれる。

## Chaliceのインストール・設定
ChaliceとAWS SDK for Python (Boto3) をインストール

画面下のコンソール画面で下記コマンドを実行

```
sudo pip install chalice boto3
```

アプリケーションのリージョンをモデルと同じリージョンにする為とアクセス権限を設定する為に、次のコマンドで環境変数を設定

`<YOUR_ACCESS_KEY>`と`<YOUR_SECRET_ACCESS_KEY>`には「AdministratorAccess - Credentialsの取得」でメモした、アクセスキーIDとシークレットアクセスキーをそれぞれ入力

```
export AWS_ACCESS_KEY_ID=<YOUR_ACCESS_KEY>
```

```
export AWS_SECRET_ACCESS_KEY=<YOUR_SECRET_ACCESS_KEY>
```

```
export AWS_DEFAULT_REGION=us-east-1
```

# サンプルアプリケーションデータの作成

画面下のコンソール画面で下記コマンドを実行。

```
wget https://s3.amazonaws.com/aws-machine-learning-blog/artifacts/decision-trees/decision-trees.tgz
```

取得した圧縮データを解凍。

```
tar xzvf decision-trees.tgz --warning=no-unknown-keyword
```

プロジェクトフォルダに移動。

```
cd decision-trees
```

# サンプルアプリケーションのデプロイ

画面下のコンソール画面で下記コマンドを実行。

```
chalice deploy
```

※`chalice delete`で削除可能

デプロイ後に表示される「Rest API URL」をメモしておくこと。

# HTMLユーザーインターフェースの作成
ユーザーがSageMakerを使用するためのHTMLフォームを作成。

## Webサイトホスティング用のS3バケットの作成
画面下のコンソール画面で下記コマンド（`<bucket name>`は任意の値を入力。）を実行。

```
aws s3api create-bucket --bucket <bucket name> --region us-east-1
```

```
aws s3 website s3://<bucket name>/ --index-document index.html --error-document error.html
```

## index.htmlファイルの作成
画面下のコンソール画面で下記コマンドを実行。

```
wget https://s3.amazonaws.com/aws-machine-learning-blog/artifacts/decision-trees/index.html
```

`<your rest api URL>`にはデプロイしたときに記録したURLを入力（index.html内の`<your rest api URL>`を置換しているだけ）

```
sed -i s@CHALICE_ENDPOINT@<your rest api URL>@g index.html
```

## S3にアップロード
画面下のコンソール画面で下記コマンドを実行。

```
aws s3 cp index.html s3://<bucket name>/index.html --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
```

# 機械学習アプリを使ってみる
`http://<bucket_name>.s3.amazonaws.com/index.html`にアクセスすると、冒頭のゴールで記載した通りの4項目が表示されるので、適当な値を入力して、「Submit」ボタンをクリック。
![app-01.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/b59de905-4a95-b201-43ba-e0c36b721434.png)


アヤメの品種が表示されたら完成です！
![app-02.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/0cea8ad7-ae94-90d4-bb5a-c7ad73e15b1d.png)