Cloud9の払い出し自動化と工夫した点 


# AWS Cloud9について
AWS Cloud9というのは、コードの記述、実行、デバッグができるクラウドベースの統合開発環境(IDE)です。
実体はEC2なので、EC2にWebからアクセスできるIDEのViewを追加したものがCloud9と捉えていただいてよいかと思います。

https://aws.amazon.com/jp/cloud9/
>AWS Cloud9 は、ブラウザのみでコードを記述、実行、デバッグできるクラウドベースの統合開発環境 (IDE) です。これには、コードエディタ、デバッガー、ターミナルが含まれています。Cloud9 には、JavaScript、Python、PHP などの一般的なプログラム言語に不可欠なツールがあらかじめパッケージ化されているため、新しいプロジェクトを開始するためにファイルをインストールしたり、開発マシンを設定したりする必要はありません。Cloud9 IDE はクラウドベースのため、インターネットに接続されたマシンを使用して、オフィス、自宅、その他どこからでもプロジェクトに取り組むことができます。また、Cloud9 では、サーバーレスアプリケーションを開発するためのシームレスなエクスペリエンスが提供されており、リソースの定義、デバッグ、ローカルとリモートの間でのサーバーレスアプリケーションの実行の切り替えを簡単に行えます。Cloud9 を使用すると、開発環境をすばやくチームと共有し、ペアプログラミングを行って互いの入力をリアルタイムで追跡できます。


# 便利な点
私が個人的に便利に感じているポイントは以下です。
- 構築の容易なうえ開発用機能が豊富なこと
AWS Consoleから画面の説明に沿ってポチポチ操作していけば構築できます。統合開発環境なので基本的なアプリケーション開発に必要な機能一式が揃っています。他IAMユーザを招待して同時並行で編集作業することもできます。
- ウェブブラウザからアクセス可能なこと
ウェブブラウザでアクセス可能なのでアプリをインストールする必要がない。プロキシ環境下でもアクセス可能
- インスタンスの自動停止機能
IDEが一定時間使われていないと自動で停止してくれるので費用が抑えられる
- AWSリソースとの相性の良さ
実体がEC2なのでVPC内通信でAWSリソースにアクセスでき踏み台として使うことができます。


# AWS Cloud9払い出し時に工夫した点

## Cloudformationテンプレート化
AWS Console上でのAWS Cloud9構築手順が簡単とはいっても、Cloudformationで構築してしまった方がより簡単です。ヒューマンエラーを抑止することもできます。以下がcloudformation templateです。
```
AWSTemplateFormatVersion : "2010-09-09"
Description: >
  create Cloud9 instance.
Parameters: 
  AWSCloud9InstanceType:
    Type: String
    Default: t3.micro
    AllowedValues:
      - t3.nano
      - t3.micro
      - t3.medium
      - t3.large
      - m5.large
  AWSCloud9SubnetId:
    Type: AWS::EC2::Subnet::Id
    Description: "The subnet in which AWS Cloud9 instance will be deployed."
  AWSCloud9OwnerARN:
    Type: String
    Description: "ARN of the owner of AWS Cloud9 instance"
Resources:
  AWSCloud9SSMInstance:
    Type: AWS::Cloud9::EnvironmentEC2
    Properties:
      AutomaticStopTimeMinutes: 30
      ConnectionType: "CONNECT_SSM"
      Description: "AWS Cloud9 instance accessible with AWS Systems Manager. Created by cfn"
      InstanceType: !Ref AWSCloud9InstanceType
      ImageId: amazonlinux-2-x86_64
      SubnetId: !Ref AWSCloud9SubnetId
      OwnerArn: !Ref AWSCloud9OwnerARN
      Tags: [ {
      "Key" : "cloud9owner",
      "Value" : !Ref AWSCloud9OwnerARN
   } ]
```
### 工夫した点
- SSM経由で実体のEC2インスタンスに接続することでインバウンドの22ポート穴あけを不要にしている。
- cloud9ownerタグをつけることで誰の持ち物か検索しやすくしている。

## EBSのサイズ拡張
AWS Cloud9に付属しているEBSの容量はデフォルト状態だと10GBです。開発をするにあたって容量が足りなくなることも多いかと思うのでEBSのサイズを拡張します。

```
CLOUD9_INSTANCE_ID="<払い出したAWS Cloud9のインスタンスID>"
SIZE="<拡張後のEBSのサイズ>"
VOLUMEID=$(aws ec2 describe-instances \
  --instance-id $CLOUD9_INSTANCE_ID \
  --query "Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.VolumeId" \
  --output text)
aws ec2 modify-volume --volume-id $VOLUMEID --size $SIZE
```
次にcloud9の内側からパーティションを拡張します。
下記URLに記載されているresize.shをcloud9上で実行してください。
https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/move-environment.html


## アウトバウンド通信の制限
AWS Cloud9ではデフォルトですべてのアウトバウンド通信が許可されていますが、セキュリティ上、アウトバウンド通信を制限したい場合もあります。今回は例としてhttp,https通信のみ許可します。
```
CLOUD9_SG_ID=`aws ec2 describe-instances --instance-id $CLOUD9_INSTANCE_ID | jq -r '.Reservations[].Instances[].NetworkInterfaces[].Groups[].GroupId'`
aws ec2 revoke-security-group-egress --group-id  ${CLOUD9_SG_ID} \
  --ip-permissions \
  "`aws ec2 describe-security-groups --output json --group-id ${CLOUD9_SG_ID}  --query "SecurityGroups[0].IpPermissionsEgress"`"

# http
aws ec2 authorize-security-group-egress --group-id ${CLOUD9_SG_ID} --protocol tcp --port 80 --cidr 0.0.0.0/0
# https
aws ec2 authorize-security-group-egress --group-id ${CLOUD9_SG_ID} --protocol tcp --port 443 --cidr 0.0.0.0/0
```