ChaliceとCloud9の連携方法について記載してみます（AWS）

# はじめに
みなさんChaliceはご存知でしょうか？AWSでサーバレスアプリケーションを構築する際に、爆速の開発効率を誇るフレームワークです。
今回はこのChaliceを使い、AWS謹製のIDEであるCloud9上で開発を行うための手順について記載したい思います。

# Chaliceとは何か？
上にも記載していますが、ChaliceはAWSが開発したサーバレスアプリケーション向けのフレームワークです。Python向けのライブラリとして提供されており、pipでインストールができます。
サーバレスフレームワークと言えばSAMやAmplifyなんかもありそれぞれ一長一短ありますが、こと開発効率においてはChaliceの右に出るものはいないと思います。（たぶん。。）
Chaliceはコマンド一発でAPI Gateway + Lambdaの環境を構築できてしまう優れものです。ゴチャゴチャ書く前にまずはサンプルコードを見て頂きましょう。

```python
from chalice import Chalice
app = Chalice(app_name='example')

@app.route('/')
def index():
    return {'hello': 'world'}
```

Chaliceでプロジェクトを作成した際に自動生成される、HELLO WORLD用のサンプルアプリケーションです。エンドポイント（/）にアクセスすると簡単なJSONを返してくれます。
このアプリケーションのデプロイ方法ですが、以下の通りコマンド一発でできてしまいます。（Linuxコンソールでの例です）

```
$ chalice deploy
```

これだけで必要なLambda関数だけでなく、API Gatewayまで勝手に作ってくれます。感激です。
エンドポイントを複数切りたい場合はこんな感じに書きます。

```python
from chalice import Chalice
app = Chalice(app_name='example')

@app.route('/')
def index():
    return {'hello': 'world'}

@app.route('/hoge')
def hoge():
    return {'hello': 'hoge'}

@app.route('/fuga')
def fuga():
    return {'hello': 'fuga'}
```

これだけで /、 /hoge、 /fuga という３つのエンドポイントが作れてしまいます。最高。。
というわけで、Chaliceに興味を持たれて詳しく知りたくなった方は以下AWSのBlackBeltをご覧ください。できれば動画で見るのがよいと思います。理解度が全然違いますので。

https://d1.awsstatic.com/webinars/jp/pdf/services/20190619_AWS-BlackBeltOnlineSeminar_DiveDeepIntoAWSChalice.pdf

https://www.youtube.com/watch?v=u4LKbQZawaQ


# Cloud9とは何か？
AWS謹製の統合開発環境（IDE）です。ブラウザ上で動き、AWSコンソールにログインするだけで使えてしまうので場所を選ばずに開発を行うことができます。ブラウザさえあれば何とかなるので端末も問いません。スタバでコーヒー片手にiPadで優雅にコーディング、なんてこともできてしまいます。
詳細については言わずもがなのBlackBeltを参照ください。動画も貼っておきます。

https://d1.awsstatic.com/webinars/jp/pdf/services/20180613_AWS-BlackBelt-Introducing-AWS-Cloud9.pdf

https://www.youtube.com/watch?v=3Sl6Hzcw7Bk


# Cloud9上でChaliceを動かしてしまおう
そんな素敵なChaliceとCloud9ですので、当然連携して使いたくなります。というわけで以下、手順をしたためていきたいと思います。
ちなみにこの手順はChalice + Cloud9でシステム開発案件を行った2020年7月頃の情報に基づいており、割と手探り感満載で色々調べつつ対応したものです。間違ってるよ！ とか もっといいやり方あるよ！ とかあればお気軽にご指摘頂けると助かります。


## Cloud9環境の作成
まずはCloud9環境を作成します。トップメニューからCloud9コンソールに遷移し、画面上の「Create environment」をクリックしてあとはポチポチするだけです。最初に決める名前以外は全てデフォルトでもOKなので、ここで何か迷うことはないと思います。
Cloud9環境を立ち上げると、内部的には専用のEC2インスタンスが割り当てられ、このインスタンス上でCloud9の各種処理が実行されることになります。


## Cloud9用のロール作成と付与
Cloud9にはAMTCという機能が用意されており、デフォルトでONになっています。AMTCにより、AWSコンソールにログインしたユーザと概ね同じ権限がCloud9（のEC2）に与えられるため便利なのですが、全権限が付与されるわけではなく、IAMなどの一部については制限がかかるようです。
この状態ではChaliceが使えないため、AMTCをOFFにして専用のIAMロールをEC2へ割り当てていきたいと思います。

### IAMロールの作成
IAMコンソールから新規ロールを作成します。流れは以下の通りです。

- IAMコンソールにアクセスし、左メニューの「ロール」を選択し、画面内に表示される「ロールの作成」をクリックします。
- 続いて表示される画面で「信頼されたエンティティの種類」に「AWSサービス」を、「ユースケースの選択」に「EC2」を選択して「次へ」をクリックします。
- 次の画面でロールを選択します。ここではAdministratorAccessを選択した前提で話を進めますが、必要に応じて権限レベルは見直してください。選択後「次へ」をクリックします。
- 次の画面でタグを指定します。何も入れなくてOKです。
- 最後にロール名を指定します。任意の文字列を入力後、「ロールの作成」をクリックすれば終了です。

### ロールのEC2へのアタッチ
上記で作成したロールをCloud9用のEC2インスタンスへ割り当てます。流れは以下の通りです。

- EC2コンソールにアクセスし、左メニューの「インスタンス」を選択します。
- インスタンス一覧が表示されるので、Cloud9用のEC2を選択し、「右クリック→セキュリティ→IAMロールを変更」を選択します。なおCloud9で生成したインスタンス名には「aws-cloud9-」の接頭語が割り当たるようです。
- IAMロールの割り当て画面が表示されますので、先ほど作成したロールを選択し、「保存」ボタンをクリックします。

### Cloud9でのAMTCを無効化
先程記載した通り、デフォルトONになっているAMTCを無効化します。
Cloud9のコンソールを開き、「アイコン（9の雲マーク）→Preference」を選択します。
![010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234157/90d97241-e2ae-cb75-faf3-26c54d927c8a.png)


設定画面が開くので、左メニューの「AWS Settings→AWS Resources」を選択。「AWS managed temporary credentials」をOFFにします。
![020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234157/87abe799-3c49-cfe4-1868-f24f0b2084b7.png)


### Cloud9に対し、デフォルトリージョンを設定
AMTCを無効化すると、リージョンの設定もなくなってしまうようなので、以下の手順に従い設定を入れます。
まずは左メニューからトップ階層のディレクトリを右クリックし、「Open Terminal Here」を選択します。これによりCloud9コンソールからEC2インスタンスに対してSSHアクセスできます。超便利。
![030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234157/79c14070-b48c-69cc-6739-daa8d6e21c98.png)

コンソールはこんな感じです。
![040.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234157/127a39a8-2acd-a65b-f5f6-0282f32ac7f5.png)


コンソール上で「aws configure list」を実行します。以下の通り、リージョンの割り当てはありません。

```
$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************V6LL         iam-role    
secret_key     ****************PW2P         iam-role    
    region                <not set>             None    None
```

設定ファイルの有無を確認します。初期状態であればたぶん存在しないはずです。

```
$ ll -a ~/.aws/
total 4
drwxr-xr-x  2 ec2-user ec2-user    6 Mar 29 01:52 .
drwx------ 13 ec2-user ec2-user 4096 Mar 29 01:36 ..
```

というわけで作成します。

```
$ vi ~/.aws/config
※以下入力して保存（:wq）
[default]
region = ap-northeast-1

$ ll ~/.aws/
total 4
-rw-rw-r-- 1 ec2-user ec2-user 36 Mar 29 02:01 config

$ cat ~/.aws/config 
[default]
region = ap-northeast-1
```

リージョン設定が完了しましたので、再確認します。ちゃんと入ってくれたようです。

```
$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************V6LL         iam-role    
secret_key     ****************PW2P         iam-role    
    region           ap-northeast-1      config-file    ~/.aws/config

```


## Chaliceのインストール
引き続きCloud9のターミナルで作業していきます。
カレントディレクトリを確認します。/home/ec2-user/environment にいなければ移動してください。

```
$ pwd
/home/ec2-user/environment
```

ChaliceをEC2インスタンスへインストールします。

```
$ pip install chalice
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip install --user` instead.
Collecting chalice
  Downloading https://files.pythonhosted.org/packages/26/de/79e471e7eb590586880b0e90f29742881eb60dffdc2fcb3e340db5f13367/chalice-1.22.3-py2.py3-none-any.whl (384kB)
～～～（略）～～～
Installing collected packages: wcwidth, blessed, readchar, python-editor, inquirer, attrs, click, wheel, typing, mypy-extensions, chalice
Successfully installed attrs-20.3.0 blessed-1.17.6 chalice-1.22.3 click-7.1.2 inquirer-2.7.0 mypy-extensions-0.4.3 python-editor-1.0.4 readchar-2.0.1 typing-3.6.4 wcwidth-0.2.5 wheel-0.36.2
```

無事インストールされました。続けてChalice用のプロジェクトを作成します。以下のコマンドをコンソール上で実行するだけでOKです。
　chalice new-project [プロジェクト名]
ここでのプロジェクト名はとりあえず helloworld にしました。

```
$ chalice new-project helloworld
Your project has been generated in ./helloworld
```

プロジェクトができました。フォルダ構成とデフォルトで作成されるサンプルアプリ（app.py）はこんな感じです。
![050.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234157/432ba9bd-3687-29c5-aefb-a382eeeb53e8.png)


サンプルアプリをデプロイしてみます。以下の通り、コマンド一発でAPI GatewayとLambdaが自動作成されます。ステキ。。なお、デプロイ前にコンソール上でプロジェクトフォルダへ移動する必要があるのでご注意ください。

```
$ cd helloworld/
$ chalice deploy
Creating deployment package.
Reusing existing deployment package.
Creating IAM role: helloworld-dev
Creating lambda function: helloworld-dev
Creating Rest API
Resources deployed:
  - Lambda ARN: arn:aws:lambda:ap-northeast-1:123456789:function:helloworld-dev
  - Rest API URL: https://xxxxxx.ap-northeast-1.amazonaws.com/api/
```

上記結果の最終行にAPIのURLが記載されています。このURLからAPIをキックすることができるので、コンソールからCurlコマンドで試してみます。

```
$ curl https://xxxxxx.execute-api.ap-northeast-1.amazonaws.com/api/
{"hello":"world"}
```

無事JSONが返却されました。とても楽ちんで素晴らしいですね。
テストが終わったらAPI GatewayとLambdaは消しておきましょう。これもコマンド一発です。

```
$ chalice delete
Deleting Rest API: xxxxxxxxxx
Deleting function: arn:aws:lambda:ap-northeast-1:123456789:function:helloworld-dev
Deleting IAM role: helloworld-dev
```

# 最後に
Cloud9＋Chaliceの連携方法と簡単な使い方だけ記載しました。Cloud9を使えばコーディングはもちろんコード補完やステップ実行なんかもできますので、これで一通りの開発はできるかと思います。
次回はChaliceを使ったクラス設計やCloud9上でのソース管理方法など、もうちょっと踏み込んだ内容を解説できればと考えています。

今回の記事が誰かのお役に立てると幸いです。