Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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

fukubaka0825
Site Reliability Engineer at eureka, Inc. devops/AWS/IaC/Terraform/コンテナ/サーバレス/Go/DDD
https://www.fukubaka0825.dev/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away