EC2/Laravel+Code4兄弟による継続的デプロイ環境のCloudFormationをAWS CDKに置き換えてみました

AWS CDKGAになったので前回記事で構築したEC2/Laravel+Code4兄弟による継続的デプロイ環境をAWS CDK化して試してみました。

今回のコード

下記、タグv0.0.0になります。

github.com

CloudFormation環境も残しておきたかったので前回のリポジトリとは別にしています。言語は普段使いで型の恩恵が受けられるTypeScriptを選択しました。

環境構成

前回の記事の「環境構成」と同じなので省略します。

コードのディレクトリ構成は下記です。

.
├── Dockerfile_ecr
├── appspec.yml
├── aws_deploy.sh
├── buildspec.yml
├── buildspec_ecr.yml
├── infra
│   ├── bin
│   │   └── laravel-ec2-cdk-sample.ts ... エントリポイント
│   ├── cdk.json
│   ├── lib
│   │   ├── build-env-stack.ts        ... BuildEnvスタック
│   │   ├── code-store-stack.ts       ... CodeStoreスタック
│   │   ├── deploy-pipeline-stack.ts  ... DeployPipelineスタック
│   │   ├── ec2-stack.ts              ... EC2スタック
│   │   └── network-stack.ts          ... Networkスタック
│   ├── package-lock.json
│   ├── package.json
│   ├── setup_ec2.yml
│   ├── templates
│   │   ├── laravel.env.j2
│   │   └── nginx.conf.j2
│   └── tsconfig.json
└── laravel

基本的には下記などを参照したり cdk synth して infra/cdk.out/ にできたCloudFormationテンプレートファイルを確認しながら置き換え作業をしていきました。

docs.aws.amazon.com

docs.aws.amazon.com

github.com

構築手順

README.mdの通りです

CodeCommitを構築

前回の記事の「CodeCommitを構築」です。

コード管理の場所を用意してGitHubから取り込みます。

git clone https://github.com/nihemak/laravel-ec2-cdk-sample.git
cd laravel-ec2-cdk-sample/infra
npm install
npm run build
./node_modules/aws-cdk/bin/cdk deploy CodeStore --require-approval never
git push ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/laravel-ec2-sample --all

Laravelプロジェクトのビルドに必要なECR環境を構築

前回の記事の「Laravelプロジェクトのビルドに必要なECR環境を構築」です。

Laravelプロジェクトのビルドで使用するEC2インスタンスと同じ環境のdockerイメージが登録されたECRリポジトリを用意します。

./node_modules/aws-cdk/bin/cdk deploy BuildEnv --require-approval never
CODEBUILD_ID=$(aws codebuild start-build --project-name laravel-ec2-sample-ecr --source-version master | tr -d "\n" | jq -r '.build.id')
echo "started.. id is ${CODEBUILD_ID}"
while true
do
  sleep 10s
  STATUS=$(aws codebuild batch-get-builds --ids "${CODEBUILD_ID}" | tr -d "\n" | jq -r '.builds[].buildStatus')
  echo "..status is ${STATUS}."
  if [ "${STATUS}" != "IN_PROGRESS" ]; then
    if [ "${STATUS}" != "SUCCEEDED" ]; then
      echo "faild."
    fi
    echo "done."
    break
  fi
done

VPC/サブネット環境とECインスタンスを構築

前回の記事の「VPC/サブネット環境とECインスタンスを構築」です。

まずEC2インスタンスへのSSHアクセスの為にキーペア/pemを作成します。

key_pair=$(aws ec2 create-key-pair --key-name test-laravel)
echo $key_pair | jq -r ".KeyMaterial" > test-laravel.pem
chmod 400 test-laravel.pem

そしてVPC/サブネット環境とLaravelプロジェクトを動かすECインスタンスを用意します。

./node_modules/aws-cdk/bin/cdk deploy Network --require-approval never
./node_modules/aws-cdk/bin/cdk deploy EC2 --require-approval never

デプロイのパイプラインを構築

前回の記事の「デプロイのパイプラインを構築」です。

CodePipelineおよびCodeBuildとCodeDeploy、CodeCommitを監視してCodePipelineを実行するCloudWatch Eventsを用意します。

./node_modules/aws-cdk/bin/cdk deploy DeployPipeline --require-approval never

使い方

README.mdの通りです。前回の記事の「使い方」と同じなので省略します。

まとめ

今回はAWS CDKを試してみました。

  • プログラミング言語で構成を定義できるので共通化などを使えるのは利点だと思います。反面、あまり凝りすぎると分かりづらくなってインフラ構成の仕様としての利点が薄れる気がします。そのため、構成定義ファイルと割り切ったある程度の冗長な書き方にして後から構成仕様がすぐわかるようにしておくことが大切だと感じました。*1
  • 構成がブラックボックスのままプロビジョニングするのは事故につながるので生成されるCloudFormationテンプレートファイルがどうなるか注意して使う必要があると感じます。そう考えると意外と導入の敷居は高いかもと思いました。*2

*1:この辺はユニットテストコードとかと同じと思いますが

*2:逆にCloudFormationテンプレートファイルに慣れているプログラマならすんなり使えるかも