Visual Studio Code Remote - Containersで始めるAWS CDK

## 概要
AWSのインフラ構築は現在Terraformでやっているが、AWS CDKも気になる今日この頃。
https://aws.amazon.com/jp/cdk/

勉強がてら触ってみようと思いましたが、ローカルにNodeやらnpmでいろいろ入れないといけない・・・

そこで、**Visual Studio Code Remote - Containers**を使って開発環境ごとコンテナ化すればいいのでは？と思い、サンプルをやってみました。
そして、AWSに対してデプロイする事も考えて修正を行ってみました。

## まずはVSCodeの環境構築から
VSCode本体と、Docker環境は入っている前提で、下記拡張機能をインストールします。
https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers

こちらをインストールすると、左下に緑のマークが出るようになります。
こちらを押して、「Open Folder in Container」をクリックします。このフォルダが作業フォルダとなります。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212587/7f6638d9-407f-d99c-f4a7-ca5c6e75fc7a.png)
すると、セットアップしたい環境の一覧が出てきます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212587/264504b3-d44b-d027-219e-eb6eab6df7c7.png)
今回はAWS CDKを使いたいので、「Node.js 12 & TypeScript」を選択します。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212587/8fe38b13-af85-cc43-40a1-9d927c8f5377.png)
すると裏でコンテナの構築が始まります。完了すると、コンテナの中に入った状態でVSCodeが開かれます。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212587/d1a4709c-79bf-c072-64a2-4e625ba376cc.png)
左下の緑部分に、現在の環境が表示されており、ターミナルを開くと当然のようにコンテナ内で開かれ、きちんとNodeも入っています。

## AWS CDKをインストール
コンテナ内に入れば、あとは環境の構築です。今回はAWS CDKを使いたいので下記コマンドでインストールします。

```shell
npm install -g aws-cdk 
```

次はサンプルプロジェクトを作成してみましょう。

```shell
cdk init sample-app --language typescript
```

これでサンプルとなるプロジェクトが作成されました。後はコードを書いてインフラを構築するだけです。
ディレクトリを見てみると、`.devcontainer`というフォルダができていると思います。この中に開発環境のDockerfileが保管されています。
次回以降はフォルダを指定すると、自動でこのDockerfileに対応したコンテナが起動し、環境を構築する事ができるので、このフォルダ毎git管理してしまえば、全員が同じ開発環境を持つことができます。

しかし、このままだと欠点があります。

- Node環境はコンテナ化できるが、npmで入れたcdk等は各自で入れないといけない。
- 最終的にはAWSにデプロイするが、認証情報がない。

なのでこれを解決していきましょう。

# ここからが本編
## 開発環境の編集

まず、Nodeの環境を整えた後に別途必要なものを洗いだし、Dockerfileに記入していきます。今回のケースだと、
- aws-cdk
- pip(awscliのインストールの為)
- awscli

が必要なので追加していきましょう。
開発環境用のDockerfileを開いて修正しましょう。

```Dockerfile:.devcontainer/Dockerfile

# Configure apt and install packages
RUN apt-get update \
    && apt-get -y install --no-install-recommends apt-utils dialog 2>&1 \
    && apt-get -y install git iproute2 procps \
    #
    # 以下の3行を新たに追加（pipを入れてpip経由でawscliをインストール）
    && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \
    && python3 get-pip.py \
    && pip install awscli \
```
次に、awsの認証情報を持ってくる方法ですが、良い方法が思いつかず、gitの設定を持ってくる方法と同じく、ボリュームマウントで持ってくるようにします。

以下のようなdocker-compose.ymlを作成します。

```yml:.devcontainer/docker-compose.yml
version: '3'
services:
  dev:
    build:
      context: .
    volumes:
      - ~/.gitconfig:/root/.gitconfig
      - ~/.aws:/root/.aws
      - ..:/workspace:cached
    command: sleep infinity
```
`volumes`の解説は以下

1行目：ローカルのgitconfigを持ってくる。
2行目：awsのクレデンシャルを持ってくる。
3行目：ワークスペースとしてローカルをマウントする。

Dockerfile単体でリモート開発環境を構築すれば、3行目が自動で実行されてコード変更がローカルと連動するのですが、composeにする場合、明示的に書かないとマウントされなかったので注意です。

次に`devcontainer.json`を編集します。これはVSCodeが起動する開発環境に関する設定ファイルです。
これを編集し、Dockerfile単体ではなく、composeで実行するように変更します。

```json:.devcontainer/devcontainer.json(変更前)
{
	"name": "Node.js 12 & TypeScript",
	"dockerFile": "Dockerfile"
}
```

```json:.devcontainer/devcontainer.json（変更後）
{
    "name": "Node.js 12 & TypeScript",
    "dockerComposeFile": "docker-compose.yml",
    "service": "dev",
    "workspaceFolder": "/workspace"
}
```
`service`は、composeで動かす`services`の名前が`dev`として定義しているのでそれと同じにします。
`workspaceFolder`を指定して、ソースコードをマウントしているフォルダを指定します。
これをしないと、ルートディレクトリがVSCodeの作業フォルダになってしまって面倒です。

# まとめ
- Visual Studio Code Remote - Containersを使えば開発環境をコンテナ化できる。
- Dockerfileやdevcontainer.jsonを編集し、必要なパッケージをインストールして具体的に開発環境を作っていく。
- これをgitで管理すれば環境の差異を極限まで減らせる！