Terraform moduleスコープ設計時に役立つ3つの観点をまとめます。
はじめに
Terraformでインフラを書く際、いかにmoduleを設計するか、は最も重要なことのひとつと考えています。
インフラコードの設計は往々にして現場組織の文脈/歴史的背景を汲んだものになりがちだと思いますが、一般論としての設計プラクティスも押さえておきたいところです。
例えばHashicorpは、下記の記事でTerraform moduleの設計時の考え方をプラクティスとしてまとめています。
Module Creation - Recommended Pattern | Terraform | HashiCorp Developer
今回はこの記事をベースにしつつ、自分の理解と解釈でTerraform module設計時に考慮すべき観点をまとめていきます。
Terraform module設計の考え方
Moduleスコープ設計の3つの観点
Terraform moduleを設計する際は、下記の3つの観点を考慮します。
- Encapsulation / カプセル化
- Privileges / 特権性
- Volatility /変動性
Encapsulation / カプセル化
関連するリソースをグルーピングして抽象度を上げます。
リソースをグルーピングしておくことで、moduleのユーザーは詳細を知り尽くさずとも多くのリソースを構築できるようになります。 逆に、あまりに多くのリソースをmoduleに含めすぎてしまうと、内部構造が複雑になったりmoudleの意図が不明瞭になってしまうので注意が必要です。
この観点の確認に役立つ問い:
- Moduleの命名がパッと思い浮かぶか
- Moduleに含まれるリソースは一緒にデプロイされるべきものか
Privileges / 特権性
リソースの権限境界を揃えます。
リソースを変更できるのは誰か/どのチームなのかを考慮し、module内にあるリソースは同一チームによって管理されるようにします。 例えば、アプリチームが管理するmodule内に、本来であればアドミンチームが管理すべきリソースが含まれている場合は、責務がmoduleとして上手く分離できていません。
この観点の確認に役立つ問い:
- 単一module内に複数チームの責務が混在していないか
Volatility /変動性
Moduleに含まれるリソースの更新頻度/ライフサイクルを揃えます。
同一module内に含まれたリソースは、基本的に同じタイミングでデプロイされます。 更新頻度/ライフサイクルの異なるリソースが混在すると、変更したくないものが意図せず削除/更新されてしまう (またはそのリスクを恐れて更新したいリソースの更新頻度が下がる) という状況が発生します。
この観点の確認に役立つ問い:
- Moduleに含まれるリソースの更新頻度は揃っているか
- Moduleに含まれるリソースのライフサイクルは揃っているか
Module設計例
例として、下記のような3層構造の典型的なWebアプリケーションのインフラをTerraformで構築するケースのmodule設計を考えてみます。
Network module
Network moduleとして、VPCやSubnetなどのネットワーク関連リソースを含めます。
Module設計の観点:高い特権性と低い変動性
- ネットワークリソースは、責任を持つ単一のチームのみが作成/変更できるべきである。
- ネットワークリソースは、一度作成されたら頻繁に変更されない。 (他のリソースが頻繁に更新される際も、ネットワークリソースは変更されないことを保証したい)
Web module
Web moduleとして、ロードバランサーやWebサーバーを含むWeb層のリソースを含めます。
Module設計の観点:高いカプセル性と高い変動性
- Web層のリソースという、概念的にも容易に分離できるリソースをmoduleとして束ねる。
- これらリソースは頻繫に変更されるため、moduleとして分離することで他のリソースへの影響を抑える。
App module
App moduleとして、AppサーバーやS3を含むアプリケーション層のリソースを含めます。
Module設計の観点:高いカプセル性と高い変動性
- アプリケーション層のリソースという、概念的にも容易に分離できるリソースをmoduleとして束ねる。
- これらリソースは頻繫に変更されるため、moduleとして分離することで他のリソースへの影響を抑える。
Database module
Database moduleとしてデータベースをmoduleとして分離します。
Module設計の観点:高い特権性と低い変動性
- データベースインフラは、責任を持つ単一のチームのみが管理する。
- 変更頻度が低いリソースのため、moduleとして分離することで他リソースの頻繫な変更からの影響を抑える。
Routing module
Route 53など、ネットワークルーティングに必要なリソースをRouting moduleに含めます。
Module設計の観点:高い特権性と低い変動性
- ネットワークルーティングは、責任を持つ単一のチームのみが管理する。
- 変更頻度が低いリソースのため、moduleとして分離することで他リソースの頻繫な変更からの影響を抑える。
Security module
IAMやsecurity grounp、MFAなどのセキュリティ関連リソースをmoduleとして分離します。
Module設計の観点:高い特権性と低い変動性
- IAMやセキュリティの変更は、責任を持つ単一のチームのみが管理する。
- 変更頻度が低いため、moduleとして分離することで他リソースの頻繫な変更からの影響を抑える。
おわりに
以上、Terraform module設計時の観点とその適用例をまとめました。
インフラコードはアプリケーションコードに比べてそのプラクティスが語られる機会は多くないように感じますが、この記事が一つの参考になれば幸いです。
[関連記事]
参考
Module Creation - Recommended Pattern | Terraform | HashiCorp Developer
Module Composition | Terraform | HashiCorp Developer
Index - Terraform Recommended Practices | Terraform | HashiCorp Developer