Open11

公式ドキュメントからCDK for Terraformに入門する

nakaakistnakaakist

https://developer.hashicorp.com/terraform/cdktf

概要

  • 開発の流れは、1. アプリを作る。2. インフラを定義する。3. cdktfコマンドでデプロイ
  • cdktfでは、terraform registryに存在するすべてのproviderとmoduleを利用可能
  • cdktfを使うべき時
    • 手続き言語でインフラ定義したい強いニーズがある
    • 複雑なインフラを抽象化したいとき。(汎用言語の方がモジュールつくりやすい)
    • v1.0に達してなくても使う先進的なマインドを持っているとき
nakaakistnakaakist

https://developer.hashicorp.com/terraform/cdktf/concepts/cdktf-architecture

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つまたは複数のインフラオブジェクトを表す。
    • constructは、任意の単位でモジュール化して使い回すことができる。
nakaakistnakaakist

https://developer.hashicorp.com/terraform/cdktf/concepts/providers

providers

  • terraformが外部APIを管理するためのプラグイン。
  • AWSなどのAPIとterraformを繋ぐ役割を果たす。resourceをprovisionするために使われる。
  • よくあるproviderに関しては、npm install @cdktf/provider-awsなどでpre-builtのものがインストールできる。もしくは、cdktf.jsonterraformProvidersに手動追加することもできる。
nakaakistnakaakist

https://developer.hashicorp.com/terraform/cdktf/concepts/modules

modules

  • terraformのmoduleとは、一つ以上の設定ファイルを含んだディレクトリ。
  • cdktfでは、terraform registryなどに存在するmoduleを使うことができる。cdktf.jsonterraformModulesに追加してcdktf getコマンドを打つことで、そのmoduleのcdktfのコードが生成され、利用可能になる。
nakaakistnakaakist

https://developer.hashicorp.com/terraform/cdktf/concepts/resources

resources

  • 一つのresourceが1つ以上のinfrastructure object (e.g., VPC, VM,...)に対応する。
  • scope
    • 親elementを共有するresourceは同じスコープにあるとみなされる。その場合は、同種のresourceの場合は違う名前にしないといけない
  • references
    • 他のresourceのプロパティは、<resource名>.<プロパティ名>の形で参照可能
  • resourceの名前を変えたくなったとき、new <リソース>.moveTo("<新しいリソース名>")とすると既存リソースを破壊することなく名前変更できる
  • 既存のリソースを新たにcdktf制御にしたい場合は、new <リソース>.importFrom("<既存のリソースのID>")でインポートできる。
nakaakistnakaakist

https://developer.hashicorp.com/terraform/cdktf/create-and-deploy/best-practices

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を使うと楽
nakaakistnakaakist

https://developer.hashicorp.com/terraform/cdktf/create-and-deploy/deployment-patterns

デプロイパターン

  • 色々な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を使っている。