AWS CloudShell で Amazon EKS の作業環境を整える

[AWS その2 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/aws2) の10日目が空いていたので登録させていただきました。

## はじめに
AWS re:Invent 2020 の Werner Vogels Keynote で AWS CloudShell が発表されました。

:rocket: **AWS CloudShell – Command-Line Access to AWS Resources**
https://aws.amazon.com/jp/blogs/aws/aws-cloudshell-command-line-access-to-aws-resources/

AWS CloudShellは　AWS マネジメントコンソールから直接起動可能なブラウザベースのシェルです。
シェルとしては Bash, PowerShell, Z shell が使用でき、AWS CLI やその他の主要な開発言語を
サポートするツール類が事前セットアップされています。

他社クラウドサービスでは既に同様の機能が提供されていたので、
待望のサービスだった方も多いのではないでしょうか。

事前セットアップ済みツールについては以下のドキュメントに記載がありますが、
kubectl 等がセットアップされていないため、EKS 用の作業環境を
自分で準備しようという内容になります。

**AWS CloudShell compute environment: specifications and software**
https://docs.aws.amazon.com/cloudshell/latest/userguide/vm-specs.html

シェル環境への追加ソフトウェアのインストール自体はサポートされますが、
責任共有モデルに則り、ユーザー自身の責任で管理する必要があります。

## 各種ツールのインストール
CloudShell の起動はマネージドコンソール上の ClouShell アイコンをクリックするだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/4f8caf8f-52b0-3e16-1e8c-4dcbcb31c6ac.png)

* とりあえず、ぱっと思いついたものを入れています
* バージョンなどは適宜読み替えてください。
* クラスターと IAM ユーザー/ロールの紐付けは事前に設定されている前提で割愛します。
* Docker が使いたい場合は、素直に Cloud9 にしましょう。

インストール先は `$HOME/.local/bin` としています。
セッション間で保持される永続ストレージが、$HOMEであるためです。
(詳細は後半の CloudShell の注意点を参照)

```shell-session
# ディレクトリ作成
mkdir -p $HOME/.local/bin
cd $HOME/.local/bin

# kubectl
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.13/bin/linux/amd64/kubectl
chmod +x kubectl

# context の作成
aws eks update-kubeconfig --name <YOUR_CLUSTER_NAME>

# eksctl
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl $HOME/.local/bin

# helm
export VERIFY_CHECKSUM=false
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
sudo mv /usr/local/bin/helm $HOME/.local/bin
```

yum でインストールするパッケージなどは永続ストレージ (`$HOME`)に配置できないため、
新規セッションの都度、インストールする必要があります。
`.bash_profile` にコマンドを書いておくことで CloudShell 起動時に
自動でインストールすることは可能です。

kubectl completion を使いたいので `bash-completion` をインストールします。

```$HOME/.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH

# 起動時にインストール
sudo yum install -y bash-completion > /dev/null 2>&1
```

kubectl completion の設定は永続ストレージに保存できます。

```shell-session
kubectl completion bash >  $HOME/.bash_completion
```

これで CloudShell でも補完がききます！

## CloudShell の注意点
使用にあたっていくつか注意点を記載します。

### 永続ストレージ
CloudShell はリージョン毎に 1 GB の永続ストレージを使用することができます。
永続ストレージはホームディレクトリ ($HOME) にあり、プライベートです。
(ユーザー間で共有されません。）
この領域のみがセッション間で保持されることが保証されています。
ホームディレクトリ以外に保存したソフトウェア等は、セッション終了時に維持さません。
また最後のセッション終了後から 120 日経過すると永続ストレージのデータは削除されます。 

### CloudShell にアクセスするための権限
他のサービス同様、対象の IAM ユーザー/ロールに CloudShell のアクセス権限を
明示的に付与する必要があります。
AWS 管理ポリシーの `AWSCloudShellFullAccess` を使用するのが最も簡単ですが、
CloudShell 経由のファイルアプロード/ダンロードを制限したい場合などは
以下のようなカスタムポリシーを使用できます。

```json
{
    "Version": "2012-10-17",
    "Statement": [{
        "Sid": "CloudShellUser",
        "Effect": "Allow",
        "Action": [
            "cloudshell:*"
        ],
        "Resource": "*"
    }, {
        "Sid": "DenyUploadDownload",
        "Effect": "Deny",
        "Action": [
            "cloudshell:GetFileDownloadUrls",
            "cloudshell:GetFileUploadUrls"
        ],
        "Resource": "*"
    }]
}
```

### CloudShell 内から AWS サービスにアクセスするための権限
AWS マネジメントコンソールのサインインに使用した IAM 認証情報を自動で利用します。
つまり、操作する IAM ユーザー (フェデレーションの場合は IAM ロール) に
対象 AWS サービスへの明示的なアクセス許可が必要です。

## 参考
**AWS CloudShell - User Guide**
https://docs.aws.amazon.com/cloudshell/latest/userguide/welcome.html

簡単ですが、以上です。