[AWS] Cloud9でモブプログラミングの環境を作ってみる

# Cloud9とは
AWSが提供するクラウドベースのIDEです。
操作はすべてブラウザで完結させることができ、AWS上で実行するサービスの開発や、各種サービスとの親和性も、当然ながら非常に高いのが特徴です。

## 料金
Cloud9そのものに関しては特別な料金はかかりませんが、Cloud9が接続するEC2と、EC2のストレージであるEBSに対して課金が発生します。
当然、インスタンスタイプが高性能なものほど、料金は高くなります。
しかし、一定の時間が経つとEC2インスタンスを停止させるオプションなどもあるので、使い方を工夫することで料金を抑えることはできそうです。

# モブプログラミングとは
モブプログラミングは、簡単に書くと、複数人で同じ画面をみながらコーディングを進める開発手法です。
役割として、ドライバー（コードを書く人）と、ナビゲーター（指示者）にわかれ、ナビゲーターの指示や意見を元に、ドライバーがコードを書いていきます。
また、役割は10分や15分といった、時間を決めて持ち回るため、タイムキーパーや、モブプログラミング向けのツール（時間計測）を用いることがあります。

モブプログラミング、つまりコードをシェアしながら編集するIDEは、MicrosoftのVisual Studio Live Shareが有名ですが、今回は、AWSのCloud9でも出来るんだよ、というこをお伝えしたいと思います。

# 環境設定
## モブプログラミングに参加するアカウントの作成
まず、IAMユーザで作成する必要があります。
今回は、わかりやすく「SubProgrammer」という名前のIAMユーザを作成してみます。

<img width="1304" alt="iam.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/4f780c0d-710a-0b8b-ea56-70b440dde70b.png">

そしてポリシーには既存の「AWSCloud9User」をセットしてください。

<img width="1052" alt="role.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/4aef516d-6ac8-43d8-982f-d3423f3547e6.png">

## Cloud9の環境作成
続いてメインアカウント側で、Cloud9の環境を作成します。
まずは、サービス一覧より「Cloud9」を選択します。
そして「Create environment」ボタンを押します。

<img width="1247" alt="cloud9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/ea613310-1a52-b312-ee9a-6faa4608fe51.png">

環境名を設定します。

<img width="1007" alt="Cloud9-1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/66c93ef0-a010-538a-4ce6-a05cdb47aa61.png">

続いて、接続・動作確認のためのEC2インスタンスの情報を入力します。
ここはいったん、デフォルトのままで進めます。

<img width="1004" alt="cloud9-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/14ac8d72-8c11-dcd1-4cfc-47261b329083.png">

確認画面で確認して、環境を作成します。

<img width="1004" alt="cloud9-3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/ede6220b-60c2-b58c-56e7-0a8be888c90b.png">

ECインスタンスを生成するので、少し時間がかかります。

<img width="1321" alt="cloud9-4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/4b71b8ee-3b93-ac96-b539-84d37ebb2b32.png">

## プロジェクトに参加するユーザを追加する
画面右上にある「Share」リンクをクリックします。

<img width="1330" alt="share1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/04fc83db-638e-8ef2-a093-36bc098e757f.png">

ここで、モブプログラミングに参加させたいアカウントを追加します。
実際にコードを書かせないユーザには、権限を「R」のみにして書き込み権限を与えないようにしましょう。

<img width="564" alt="share2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/4e7f6a7c-ae71-c7c2-8d4c-1a04e6ae7468.png">

確認画面が表示されるので、そのまま「OK」を押すと、ユーザが自身のCloud9環境に参加できるようになります。

<img width="740" alt="share3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/fb866f59-9c81-9081-090b-6f4d7308d56a.png">

## プロジェクトの初期化
このCloud9に接続されるEC2は、Amazon Linuxで、開発に必要なコマンドが予めインストールされています。

```bash
Admin:~/environment $ aws --version
aws-cli/1.18.104 Python/3.6.10 Linux/4.14.186-110.268.amzn1.x86_64 botocore/1.17.27
Admin:~/environment $ sam --version
SAM CLI, version 0.38.0
Admin:~/environment $ cdk --version
1.54.0 (build c01b9b9)
Admin:~/environment $ 
```

さらにはgitも。

```
Admin:~/environment $ git --version
git version 2.14.5
```

で、今回は、SAMでHello Worldな環境を作成しようと思います。

```bash
Admin:~/environment $ sam init
       :
-----------------------                                                                                                                   
Name: sam-app                                                                                                                             
Runtime: python3.7                                                                                                                        
Dependency Manager: pip                                                                                                                   
Application Template: hello-world                                                                                                         
Output Directory: .                                                                                                                       
                                                                                                                                          
Next steps can be found in the README file at ./sam-app/README.md
```

これで、SAMの環境ができました。

## 参加アカウント側の操作
続いて、参加するアカウント（SubProgrammer）ですが、まずは普通にマネジメントコンソールにログインします。
そして、サービスより「CLoud9」を選択します。

ここで、左側のメニューより「Shared with you」を選択します。

<img width="1281" alt="share4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/91a1315e-5418-a901-f61a-2d8ff2e53325.png">

メインアカウントより追加された環境が表示されるので、その環境の「Open IDE」ボタンを押します。

<img width="1278" alt="share5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/e6ca7069-304b-1b7f-3d82-e250d68d2872.png">

すると、メインアカウントで先ほど追加したSAMのプロジェクトファイルが追加された状態の画面が表示されます。

<img width="1277" alt="share6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/3f57c9f7-da99-c8a9-8619-579f967f1523.png">

## 画面の同期
通常のままだと、個々に画面が表示されているだけの状態になります。
そこで、まずメインアカウント側で`MobProDemo / sam-app / hello_world / app.py`を開いてみましょう。

<img width="1028" alt="main1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/66b3cbec-7353-76a8-2e01-fcf3af0f5e8a.png">

実は、このままの状態だと、サブアカウント側で同じファイルが画面に表示されません。
サブアカウント側では、画面丈夫にある「A」（これはユーザの頭文字を表すもので「A」は「Admin = 管理者」、「S」は「SubProgrammer = 自分」を意味します。
この「A」をクリックして、「Open Active File」を選択します。

<img width="290" alt="sub1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/5b36a4b3-92a7-1d58-2e4c-72a45e544ee2.png">

すると、メインアカウントで開いていた操作中のファイルが表示されます。

<img width="1277" alt="sub2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/31c5069c-88c5-635e-60d4-b4a01909bc9b.png">

今回は、SubProgrammerにも書き込み権限を与えているので、SubProgrammerの画面でファイルを修正すると、リアルタイムに、メインアカウントの画面上で入力内容が反映されるようになります。
その逆もしかりです。

# まとめ
SAMや、CDKのコードをモブプログラミングで開発して、そのままCodeCommitにpushして、パイプライン経由でデプロイやプロビジョニングを走らせて、などといった一気通貫なAWS開発環境を作れるのは、なかなか魅力的だと思います。
それが、さらに画面を共有できることや、各種開発ツールのバージョンも、開発者全員で同期がとれるため、統一性のある開発環境を簡単に構築するためにも活用できるのではないかと思います。

ブラウザのみで動作することが前提であるため、クライアント環境に依存しにくい一方で、インターネット回線が必要であったり、ブラウザによって動作が異なったり、あるいはネイティブアプリでないがゆえの高度な機能への対応が若干不足している感は否めません。
が、まだまだ延びしろの大きいIDEであると思いますので、今後の同行に注目してみましょう。