BioErrorLog Tech Blog

試行錯誤の記録

Terraform module設計時に考慮すべき3つの観点

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設計を考えてみます。

3層構造のアプリケーションを構築する | 画像はドキュメントより

Network module

Network moduleとして、VPCやSubnetなどのネットワーク関連リソースを含めます。

Network moduleの設計 | 画像はドキュメントより

Module設計の観点:高い特権性と低い変動性

  • ネットワークリソースは、責任を持つ単一のチームのみが作成/変更できるべきである。
  • ネットワークリソースは、一度作成されたら頻繁に変更されない。 (他のリソースが頻繁に更新される際も、ネットワークリソースは変更されないことを保証したい)

Web module

Web moduleとして、ロードバランサーやWebサーバーを含むWeb層のリソースを含めます。

Web moduleの設計 | 画像はドキュメントより

Module設計の観点:高いカプセル性と高い変動性

  • Web層のリソースという、概念的にも容易に分離できるリソースをmoduleとして束ねる。
  • これらリソースは頻繫に変更されるため、moduleとして分離することで他のリソースへの影響を抑える。

App module

App moduleとして、AppサーバーやS3を含むアプリケーション層のリソースを含めます。

App moduleの設計 | 画像はドキュメントより

Module設計の観点:高いカプセル性と高い変動性

  • アプリケーション層のリソースという、概念的にも容易に分離できるリソースをmoduleとして束ねる。
  • これらリソースは頻繫に変更されるため、moduleとして分離することで他のリソースへの影響を抑える。

Database module

Database moduleとしてデータベースをmoduleとして分離します。

Database moduleの設計 | 画像はドキュメントより

Module設計の観点:高い特権性と低い変動性

  • データベースインフラは、責任を持つ単一のチームのみが管理する。
  • 変更頻度が低いリソースのため、moduleとして分離することで他リソースの頻繫な変更からの影響を抑える。

Routing module

Route 53など、ネットワークルーティングに必要なリソースをRouting moduleに含めます。

Routing moduleの設計 | 画像はドキュメントより

Module設計の観点:高い特権性と低い変動性

  • ネットワークルーティングは、責任を持つ単一のチームのみが管理する。
  • 変更頻度が低いリソースのため、moduleとして分離することで他リソースの頻繫な変更からの影響を抑える。

Security module

IAMやsecurity grounp、MFAなどのセキュリティ関連リソースをmoduleとして分離します。

Security moduleの設計 | 画像はドキュメントより

Module設計の観点:高い特権性と低い変動性

  • IAMやセキュリティの変更は、責任を持つ単一のチームのみが管理する。
  • 変更頻度が低いため、moduleとして分離することで他リソースの頻繫な変更からの影響を抑える。

おわりに

以上、Terraform module設計時の観点とその適用例をまとめました。

インフラコードはアプリケーションコードに比べてそのプラクティスが語られる機会は多くないように感じますが、この記事が一つの参考になれば幸いです。

[関連記事]

www.bioerrorlog.work

www.bioerrorlog.work

www.bioerrorlog.work

参考

Module Creation - Recommended Pattern | Terraform | HashiCorp Developer

Module Composition | Terraform | HashiCorp Developer

Index - Terraform Recommended Practices | Terraform | HashiCorp Developer

Welcome - Terraform Best Practices

Best practices for using Terraform  |  Google Cloud