見出し画像

Visual Studio Code Dev ContainerでAWS CDKの開発環境を作ってみた

みなさんこんにちは! 第4開発事業部のAKIHISAです!

AWS CDKの開発環境をサクッと作ってみたくないですか?
今回は、Visual Studio Codeの機能であるDev Containerを使って、CDKのサンプルプロジェクトをデプロイできる開発環境を紹介します!

【ライターの紹介】
 AKIHISA
第4開発事業部所属のAWSがちょっと得意な開発エンジニア
食べることが大好きで、初めて挑戦したおせちの出来が良くて幸せ


前提条件

環境

  • macOS

  • Docker Desktop for Mac 4.11.1

  • Visual Studio Code 1.85.1

事前準備

VSCodeの拡張機能のインストール

お手元のVSCodeでDev Container拡張機能をインストールしてください

AWS認証情報の設定

AWS CLIを使えるようにするため、AWS認証情報を設定しておきます

設定手順は以下のページに記載があるので、ご確認ください

Dev Containerの設定

サンプルリポジトリはこちらです

迷った時は、こちらのリポジトリをご確認ください

セットアップ

VSCode内でShift + Cmd + P(Windowsなら Shift + Ctrl + P)を押下してコマンドパレットを開き、を実行します

TypeScriptを用いてAWS CDKプロジェクトを作成するため、 Node.js & TypeScriptを選択します

バージョンは、既定となっているものを選択します

追加機能は、AWS CLIだけ選択してOKを押下します

devcontainer.jsonが作成され、開発コンテナが立ち上がります
(コメントアウト部は削除しています)

.devcontainer/devcontainer.json

{
 "name": "Node.js & TypeScript",
 "image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bullseye",
 "features": {
  "ghcr.io/devcontainers/features/aws-cli:1": {}
 }
}

各パラメータの詳細については、以下のページを参考にしてください

AWS CDKのインストール

コンテナにはAWS CDKがインストールされていません

$ cdk --version
bash: cdk: command not found

コンテナ起動時にCDKをインストールするスクリプトを書きます

.devcontainer/postCreateCommand.sh

#!/bin/bash
set -ex

# AWS CDKのインストール
npm install -g aws-cdk

devcontainer.jsonにスクリプトを使用する設定を追加します

.devcontainer/devcontainer.json

+ "postCreateCommand": "bash .devcontainer/postCreateCommand.sh"

コンテナの再構築を行いましょう(Shift + Command + P -> Dev Containers:Rebuild)
コンテナが起動後にスクリプトが動作し、CDKのインストールが実行されています

Running the postCreateCommand from devcontainer.json...

[10950 ms] Start: Run in container: /bin/sh -c bash .devcontainer/postCreateCommand.sh
+ npm install -g aws-cdk

added 1 package in 4s
npm notice 
npm notice New major version of npm available! 9.8.1 -> 10.2.5
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.2.5
npm notice Run npm install -g npm@10.2.5 to update!
npm notice 
任意のキーを押してターミナルを終了します。

CDKがインストール済みであることも確認できました

$ cdk --version
2.118.0 (build a40f2ec)

AWS認証情報の共有

AWS認証情報はローカルに設定されています(事前設定より)が、コンテナには設定されていません

$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key                <not set>             None    None
secret_key                <not set>             None    None
    region                <not set>             None    None

ローカルディレクトリにあるAWS認証情報を、コンテナにマウントする設定を追加します

参考

.devcontainer/devconatiner.json

+ "mounts": [
+ "source=${localEnv:HOME}${localEnv:USERPROFILE}/.aws/,target=/home/node/.aws/,type=bind,consistency=cached"
+ ]

コンテナを再構築すると、コンテナ上でもAWS認証設定が確認できました

$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ******************** shared-credentials-file    
secret_key     ******************** shared-credentials-file    
    region           ap-northeast-1      config-file    ~/.aws/config

Git資格情報も欲しくなるところですが、こちらはDev Container標準でコンテナに共有される仕組みになっています

参考

VSCodeの設定

コンテナ上で稼働しているVSCodeの設定を追加します

拡張機能のインストール

VSCodeの拡張機能をコンテナ起動時にインストールします

プロジェクト推奨の拡張機能を設定する.vscode/extentions.jsonと同様の設定を行えます

.devcontainer/devcontainer.json

+ "customizations": {
+   "vscode": {
+    "extensions": [
+   "esbenp.prettier-vscode",
+   "amazonwebservices.aws-toolkit-vscode",
+   "editorconfig.editorconfig",
+   "dbaeumer.vscode-eslint",
+   "eamodio.gitlens"
+    ]
+  }
+}

使う拡張機能はBLEAを参考にしました

コンテナの再構築を行うと、指定した拡張機能がコンテナ上にインストールされています

設定

VSCodeの設定をコンテナ上のVSCodeに適用します

ワークスペース用の.vscode/settings.jsonと同様の設定を行えます

先ほど追加した拡張機能と同列に設定します

.devcontainer/devcontainer.json

 "customizations": {
  "vscode": {
   "extensions": [
    "esbenp.prettier-vscode",
    "amazonwebservices.aws-toolkit-vscode",
    "editorconfig.editorconfig",
    "dbaeumer.vscode-eslint",
    "eamodio.gitlens"
   ],
+  "settings": {
+   "[typescript]": {
+    "editor.formatOnSave": true,
+    "editor.defaultFormatter": "esbenp.prettier-vscode"
+   }
+  }
  }
 },

AWS CDKのお試し

サンプルプロジェクトの作成

いよいよCDKのサンプルプロジェクトを作成していきます

CDKプロジェクトを作ったことがない方は、CDKワークショップも参考にしてみてください

ターミナルからCDKのサンプルプロジェクトを作成します

cdk init sample-app --language typescript

問題なく完了しました

$ cdk init sample-app --language typescript

〜中略〜

Initializing a new git repository...
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint:   git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint:   git branch -m <name>
Executing npm install...
✅ All done!

色々なファイルが作成されています

$ ls -la
total 184
drwxr-xr-x  16 node node    512 Jan  4 08:11 .
drwxr-xr-x   3 root root   4096 Jan  4 08:01 ..
drwxr-xr-x   3 node node     96 Jan  4 08:02 bin
-rw-r--r--   1 node node   2968 Jan  4 08:01 cdk.json
drwxr-xr-x   4 node node    128 Jan  4 08:01 .devcontainer
drwxr-xr-x  14 node node    448 Jan  4 08:02 .git
-rw-r--r--   1 node node     93 Jan  4 08:01 .gitignore
-rw-r--r--   1 node node    157 Jan  4 08:01 jest.config.js
drwxr-xr-x   3 node node     96 Jan  4 08:02 lib
drwxr-xr-x 220 node node   7040 Jan  4 08:11 node_modules
-rw-r--r--   1 node node     65 Jan  4 08:01 .npmignore
-rw-r--r--   1 node node    566 Jan  4 08:01 package.json
-rw-r--r--   1 node node 154530 Jan  4 08:03 package-lock.json
-rw-r--r--   1 node node    694 Jan  4 08:01 README.md
drwxr-xr-x   3 node node     96 Jan  4 08:02 test
-rw-r--r--   1 node node    663 Jan  4 08:01 tsconfig.json

環境のブートストラップ

使用するAWSアカウントでブートストラップを行っている方は、飛ばしてください

ブートストラップを行ったことがない方は、以下のコマンドにてブートストラップを行います

参考

cdk bootstrap

環境のブートストラップが行われ、AWSアカウントにCloudFormationスタックのCDK Toolkitが作成されます

作成されたスタックのステータスがCREATE_COMPLETEになっていれば成功です

$ aws cloudformation describe-stacks --stack-name CDKToolkit | jq '.Stacks[].StackStatus'
"CREATE_COMPLETE"

デプロイ

AWSアカウント上でサンプルプロジェクトをデプロイします

参考

cdk deploy

途中で(y/n)を確認されますが、を入力するとデプロイが実行されます

$ cdk deploy

〜 中略 〜

Do you wish to deploy these changes (y/n)? y
DevcontainerCdkForTypescriptStack: deploying... [1/1]
DevcontainerCdkForTypescriptStack: creating CloudFormation changeset...

 ✅  DevcontainerCdkForTypescriptStack

✨  Deployment time: 21.83s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXXX:stack/DevcontainerCdkForTypescriptStack/XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

✨  Total time: 41.24s

以下のURLにアクセスしCloudFormationのコンソールを確認すると、サンプルプロジェクトがデプロイされています

リソースタブを見ると、サンプルプロジェクトで使用しているリソースがデプロイされています

詳細な説明はCDKワークショップをご確認ください

スタックの削除

サンプルプロジェクトがデプロイできることは確認できたので、ターミナルからスタックを削除します

参考

cdk destroy

途中で(y/n)を確認されますが、yを入力するとスタックの削除が実行されます

$ cdk destroy

〜 中略 〜

Are you sure you want to delete: DevcontainerCdkForTypescriptStack (y/n)? y
DevcontainerCdkForTypescriptStack: destroying... [1/1]

 ✅  DevcontainerCdkForTypescriptStack: destroyed

スタックの削除が完了しました

Dev Containerの改善

ディスクパフォーマンスの改善

Dev Conatainerではワークスペースのファイルに対して、デフォルトでローカル環境とコンテナのバインドマウントを行っています
ゆえにコンテナ内から、マウント元(ローカル)を呼び出すと、ディスクパフォーマンスが低下する可能性があります

コンテナ内のファイルシステムであるDockerボリュームを使うことで、ディスクパフォーマンスが改善されます

参考

今回はCDK for TypeScriptプロジェクトで容量の大きなnode_modulesを名前付きボリュームにマウントします

mountsの下に設定を追加します

.devcontainer/devcontainer.json

 "mounts": [
  "source=${localEnv:HOME}${localEnv:USERPROFILE}/.aws/,target=/home/node/.aws/,type=bind,consistency=cached",
+ "source=${localWorkspaceFolderBasename}-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume"
 ]

コンテナを再構築してDocker Desktopを確認すると、ボリュームが追加されています

ただし、作成したボリュームはrootユーザーによって作成されているのでnpmパッケージのインストールが行えません

$ ls -la |grep node_modules
drwxr-xr-x  2 root root   4096 Jan  4 07:42 node_modules

また、Dockerボリュームを新しく作成してコンテナにマウントしているので、node_modulesの中身が空になっています

$ ls -la node_modules
total 4
drwxr-xr-x  2 root root 4096 Jan  4 07:42 .
drwxr-xr-x 17 node node  544 Jan  4 08:56 ..

なので、起動時に実行されるスクリプト(postCreateCommand.sh)にオーナーの変更及び、npmパッケージのインストールを追加します

.devcontainer/postCreateCommand.sh

# npmパッケージのインストール
sudo chown node:node node_modules
npm ci

コンテナを再構築すると、npmパッケージがnode_modulesに問題なくインストールされています

Running the postCreateCommand from devcontainer.json...

[11386 ms] Start: Run in container: /bin/sh -c bash .devcontainer/postCreateCommand.sh
+ npm install -g aws-cdk

added 1 package in 3s
npm notice 
npm notice New major version of npm available! 9.8.1 -> 10.2.5
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.2.5
npm notice Run npm install -g npm@10.2.5 to update!
npm notice 
+ sudo chown node:node node_modules
+ npm ci

added 319 packages, and audited 354 packages in 24s

34 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
任意のキーを押してターミナルを終了します。

まとめ

Dev Containerを使ってCDKの開発環境を構築することができました

コンテナを使うことでローカル環境を汚すことなく、誰でも同じ環境で開発を行うことができるようになります
Dev Containerによって、それがより宣言的に書くことができるようになりました

ハードルの下がったコンテナ環境を使って、みなさんもCDKで開発してみませんか?

ALHについて知る



↓ ↓ ↓ 採用サイトはこちら ↓ ↓ ↓


↓ ↓ ↓ コーポレートサイトはこちら ↓ ↓ ↓


↓ ↓ ↓ もっとALHについて知りたい? ↓ ↓ ↓