AWS CDKメモ: ディレクトリ構造、CI/CD、共通コンポーネント

AWS CDKのディレクトリ構造についての備忘録。マルチリージョン、マルチアカウントで管理する必要があったが今のところ安定して運用できている方法を記す。

前提

  • CDK version: 1.94.1
  • マルチリージョン e.g, ap-northeast-1, ap-southeast-2など
  • マルチアカウント e.g., productionアカウント、stagingアカウントなど

マルチリージョンではない場合は以下でも良いと考えている

github.com

構造

bin/
  ▸ serviceA/
      jp-production.ts
      jp-staging.ts
      au-production.ts
      au-staging.tsserviceB/
▾ lib/
  ▸ serviceA/
    ▾ policies/
          policyA.ts
          policyB.ts
      buildApp.ts (or index.ts)
      stackA.ts
      stackB.ts
      IAMStack.tsserviceB/
▸ test/
  ▸ serviceA/
      buildApp.test.ts
      stackA.test.ts
      stackB.test.ts
      IAMStack.test.tsserviceB/
  • lib AppとApp内のStackを定義。IAMのStackは複雑になりがちなので policies ディレクトリに各policyを定義。buildAppでAppを返す関数を定義する
  • testテストを定義
  • bin buildAppで定義された関数をステージ、リージョンの引数を与えて呼び出し、App#synth()を呼び出す

CI, CD

  • PRが送られてきた際にはcdk diffを呼び出しdiffがわかるようにする
  • production, stagingブランチにPRがマージされた際 cdk deployを呼ぶようにする。App内のStackの依存関係はCDKに自動解決してもらいたいので、-no-executeオプションをつけChangeSetを作るとChangeSetの管理や実行順序の管理が難しくなる。そのためCircleCIやGitHubActionsのapprovalステップを追加すると良いと思う。
  • マルチアカウントの切り替えはAssumeRoleを使って頑張る。自分の場合はよりアクセス権の厳しいRoleを各アカウント下にプロジェクトごとに用意してAssumeRoleするようにし影響範囲を狭めている。

共通コンポーネント

同一ディレクトリで管理しても良いが、自分の場合は複数レポジトリで管理する必要があったためCDK Construct Libraryとして単独レポジトリで管理している。その際projenのAWSCDKConstructLibraryを用いた。

projen/projen

projenはjsiiを使い多言語でのライブラリを提供することを想定しているため一部のTypeScriptのシンタックスが使えなくなる点に注意。

共通コンポーネントして自分の場合は以下を定義している

  • enum...アカウント、ステージ、国などをenumで定義
  • BaseStack...会社の基本Stackを用意。会社のStackを使うと自動的に会社標準のtagが付与されるようにしていたり、Aspects を利用して会社のデフォルトのセキュリティバリデーションがかかるようにしている。

改善点

  • プロジェクトに関わらずCDK bootstrapをしているがプロジェクトごとに—toolkit-stack-nameをすると各プロジェクトごとのChangeSetの管理用のRoleが作成され、よりセキュアなChangeSetの管理ができるようになる。

f:id:koyamay:20210620185126p:plain