Open11
公式ドキュメントからCDK for Terraformに入門する
TypeScriptなど汎用プログラミング言語でterraformが書ける
概要
- 開発の流れは、1. アプリを作る。2. インフラを定義する。3. cdktfコマンドでデプロイ
- cdktfでは、terraform registryに存在するすべてのproviderとmoduleを利用可能
- cdktfを使うべき時
- 手続き言語でインフラ定義したい強いニーズがある
- 複雑なインフラを抽象化したいとき。(汎用言語の方がモジュールつくりやすい)
- v1.0に達してなくても使う先進的なマインドを持っているとき
インストール
-
npm install --global cdktf-cli@latest
でcliをインストール。 - あとは、
cdktf init --template=typescript --providers=kreuzwerker/docker --local
などとinitし、コードを編集してcdktf deploy
でデプロイ
cdktfのアーキテクチャ
- AWS CDKとコンセプトは似ているが別物
- jsiiというツールを使って、tsのコードベースからpythonなど他の言語向けのbindingを作っている
- cdktfは、tsなどで定義したインフラから、terraformが読めるjson configuration fileを生成(synthesize)している。下記のような流れでデプロイする
- アプリケーションアーキテクチャ
- 下記のように、app, stack, resourceという、3階層のtree状のconstructと呼ばれるパーツでアプリケーションが構成される。
- constructの使い分け
- app
- 1つのプロジェクトにつき1個以上存在。各種infra設定のコンテナ的役割を担う。
- stack
- terraformのworking directoryに相当する、インフラ定義の集まり。1つのapp内でstackを分けておくことにより、例えばtestとdevelopmentでインフラリソースを分けて管理することが可能になる。
- 例えば、stackを複数作っておくと、
cdktf deploy '<スタック名>'
で特定のスタックだけデプロイできる。そのほかにも、リージョンやドメインごとに分けたりもできる。stack分離のベストプラクティス
- resource
- 1つまたは複数のインフラオブジェクトを表す。
- app
- constructは、任意の単位でモジュール化して使い回すことができる。
- 下記のように、app, stack, resourceという、3階層のtree状のconstructと呼ばれるパーツでアプリケーションが構成される。
providers
- terraformが外部APIを管理するためのプラグイン。
- AWSなどのAPIとterraformを繋ぐ役割を果たす。resourceをprovisionするために使われる。
- よくあるproviderに関しては、
npm install @cdktf/provider-aws
などでpre-builtのものがインストールできる。もしくは、cdktf.json
のterraformProviders
に手動追加することもできる。
modules
- terraformのmoduleとは、一つ以上の設定ファイルを含んだディレクトリ。
- cdktfでは、terraform registryなどに存在するmoduleを使うことができる。
cdktf.json
のterraformModules
に追加してcdktf get
コマンドを打つことで、そのmoduleのcdktfのコードが生成され、利用可能になる。
resources
- 一つのresourceが1つ以上のinfrastructure object (e.g., VPC, VM,...)に対応する。
- scope
- 親elementを共有するresourceは同じスコープにあるとみなされる。その場合は、同種のresourceの場合は違う名前にしないといけない
- references
- 他のresourceのプロパティは、
<resource名>.<プロパティ名>
の形で参照可能
- 他のresourceのプロパティは、
- resourceの名前を変えたくなったとき、
new <リソース>.moveTo("<新しいリソース名>")
とすると既存リソースを破壊することなく名前変更できる - 既存のリソースを新たにcdktf制御にしたい場合は、
new <リソース>.importFrom("<既存のリソースのID>")
でインポートできる。
remote backend
- terraformは管理しているinfraと実世界のリソースをマッピングするstateを保持している。デフォルトではローカル保存だが、チームで作業するときなどにremote backendも使える。
configuration file (cdktf.json)
- カスタム設定を入れるファイル。
- 利用するproviderおよびmoduleに関しては、ここにすべて記述しておく必要がある。(pre-builtのproviderをnpm installした場合は不要)
cdktfのベストプラクティス
- シークレット管理
- 普通に環境変数とかからシークレットを読むようなコードをcdktfで書くと、synthしたときの成果物にシークレットが入ってしまう。(特にsynthの成果物をgitにコミットしている場合)
- これを防ぐため、
TerraformVariable
という、シークレット格納専用のリソースを作ってそこに入れると良い。 - terraform variableに値を入れるには、
TF_VAR_<variable名>
という環境変数に値をセットしておけば良い。 - terraform variableはstackレベルで作ると良い。
- provider
- 使える時は常にpre-builtのproviderを使った方が良い。都度手動でコードbindingを生成すると数分かかったりする
- 設計
- 以下の場合はstackを分ける
- eva/prodなど環境で分ける。e-commerce/blog/DWHなど目的で分ける。リージョンで分ける。networ/db/computeなど役割で分ける。プロダクトごとなどデプロイサイクルで分ける。
- 必ずしもstack分けた時に中身をduplicateする必要はない。単にstackに渡す引数を変えるでよければそうする。
- constructを作る時は、引数を渡せるようにして拡張性を持たせると良い
- 新しくプロジェクトをつくるときは
npx projen new cdktf-construct
などとprojenを使うと楽
- 以下の場合はstackを分ける
デプロイパターン
- 色々なCI/CDパターンがある
- デプロイメソッド
-
cdktf deploy
でデプロイするか、synthまでcdktfでやって、続きはterraformでやるかの選択がある。 -
cdktf deploy
をつかうべきとき- terraform apply以外にも、dockerイメージビルドなどの作業をデプロイ時に行いたい時
- 複数のstackが複雑な依存関係をもっているとき(素のterraformだと扱いが難しい)
-
cdktf synth
までやって続きはterraformでやるとき- 既存のterraformのパイプラインがあって、そことつなぎこみたいとき
-
- terraform CDK github action
- 公式が出してるactionを使うと、terraform planをPRにコメントしてくれてデプロイしてくれる。裏ではcdktf cliを使っている。