Edited at

Terraformのコンポーネント分割について検討する

image.png


はじめに

こんにちわ。Wano株式会社エンジニアのnariと申します。

前回のmoduleの記事に引き続き、terraformの話を記事にしたいと思います。

今回はtfstateをどの単位で分割し管理するか、というコンポーネント分割問題に関して書いていきます。

ただし、今回の記事の構成はプロジェクトの一旦の落とし所であって、ベストな構成とは限らないのでご了承ください。


対象読者


  • モノシリックなtfstateの管理が辛い方

  • コンポーネント分割の粒度に同じく悩んでいる方


前提


  • 筆者のプロジェクトのサービスはAWS上で構築しているため、providerはAWS


何故コンポーネントを分割するのか



  • terraformの結果ファイル(tfstate)をモノシリックにするのは怖い


    • 変更の影響範囲が読めない

    • ファイル自体の可読性が終わる




  • かといってawsサービスごとに分けると、細かくなりすぎて運用がかなり煩雑になる(makefileやterragruntなどのツールでカバーしても)


分割する際の視点


  • 安定度

  • ステートフル

  • 影響範囲

  • 組織のライフサイクル

  • 関心ごとの分離

  • 依存関係の制御


(Pragrmatic Terraform on AWS 17章より)


コンポーネント分割の全体像

スクリーンショット 2019-08-04 00.31.42.png


どのように上記の分割に行き着いたか

分割する際の視点を利用し、現実的に分割粒度を検討していった


  • 安定度 高



    • network(vpc,subnet周辺)



  • 安定度 低



    • routing(route53,alb,acm)



  • 関心ごとの分離


    • services ecsのサービス単位(ecs cluster,taskdifinition,service,それに付随するec2系リソース ecr pipeline系)


    • opsserver(session manager,ec2)

    • events やりたい処理単位(lambda cloudwatchEvents ここはApex+Terraform)


      • モニタリングとかもここに



    • state machine(step function) 



  • ステートフル



    • storage(s3)


      • 依存関係を制御できる自信がない+複数の関心ごとの対象となるストレージが出てこなさそうなので、backend以外全て他のコンポーネントに寄せることとする(今回はコンポーネントとして登場させない) 




    • datastore(elasticache,RDS)


      • elasticache,RDSを別々に管理する(それぞれクラスターごとに)






  • 組織のライフサイクル


    • iam user




  • 依存関係の制御


    • コンポーネント図を起こし、terragrunt.hclのdependenciesでしっかり管理する




terragrunt.hcl

dependencies {

paths = ["../../network","../../routing"]
}


課題


  • iam roleやpolicyの管理をそれぞれのコンポーネントに寄せてしまっているので、同じようなpolicyが量産されてしまう

  • ストレージはステートフルとは言え、それぞれ独立したコンポーネントで管理すると、今度は依存関係の管理でかなり疲弊することになるので、個別管理できていない


  • そもそもここまで厳密にコンポーネントを分割して運用している例を見ない(メルカリさんなどの例でも、マイクロサービス毎くらいにしか管理していないぽい)


その他


Q.こんなに分割するとデプロイの運用がめんどくさいのでは?


A.そこまで面倒臭くはない。



  • terragruntというツールを使うと、それぞれのサブディレクトリでplanやapplyを打ってくれるplan-allやapply-allが使えるようになるので、コマンド一発の運用に集約できる

  • 前述したterragrunt.hclという設定ファイルでコンポーネント間の依存関係も管理できる

  • CIでもterragrunt plan-allをdindで唱えて差分チェックをしている(sampleのdockerfileはこちら)

  • codebuildでのdindの設定に関してはこちらの記事参照


終わりに

皆さんのプロジェクトでのコンポーネント分割粒度についても教えていただけると大変嬉しいです。

よろしくお願いいたします。


参考文献

terraformはどの単位で分割すべきか - Qiita

オレオレterraformディレクトリ構成ベストプラクティス - Qiita

Terraformにおけるディレクトリ構造のベストプラクティス | DevelopersIO

Terraform Best Practices in 2017 - Qiita

Terraform 運用ベストプラクティス 2019 ~workspace をやめてみた等諸々~ - 長生村本郷Engineers'Blog