株式会社MIXIで
Terraformとは
TerraformとはHashiCorpが提供するIaC
TerraformはAPIを通じてプラットフォームやサービス上にリソースを作成します。Terraformは対象とのAPIのやり取りを
プロバイダの一覧はTerraform Registryから確認することができ、開発 / 管理元に応じたバッジが付与されています。HashiCorp
Terraformのプラクティス
Terraformは主にAWSやGCPなどクラウドサービスのリソースをプロビジョニングするために多くの企業やサービスに利用されており、その活用方法やプラクティスについてもブログや登壇などで多くの知見が共有されています。
複数のチームでTerraformを利用する場合には、Terraform公式サイトのTerraform Recommended PracticesやGoogleから公開されている
たとえば、初期に悩みがちなディレクトリ構成などはGoogleのベストプラクティスを参考にすればまずは困らないでしょう。
とはいえこれらは推奨事項なので、それぞれの組織やプロダクトに合わせて、個別の構成を取ったり改善していくことももちろん可能です。
Terraform構成はモノリポジトリかマルチリポジトリか
こういった議論の中に
HashiCorpのブログ
モノリポジトリのメリット・デメリット
モノリポジトリとは、その名のとおりインフラ設定のすべての Terraform コードが同一のリポジトリ内に含まれている構成であり、個人プロジェクトや小規模なチームでの運用において有効です。
モノリポジトリを採用した場合のメリット / デメリットは以下のとおりです。
メリット
- すべてのインフラ設定を取得するための、単一の信頼できるソースになる
- データベースのパイプラインなどにとって重要な、テスト、デバッグ用のインフラ設定を一元化できる
デメリット
- モジュールとプロバイダのバージョン管理と依存関係のメンテナンスコストが増加する
- インフラ設定の変更を適用する場合、リポジトリ内の評価対象が多いため、CI
(Continuous Integration) のパイプラインの実行時間が長くなる - Terraformのコードへのアクセス制御をしたい場合、ユーザやグループに特定のサブディレクトリへのアクセスのみを許可する必要がある
モノリポジトリは変更の影響範囲の大きさが問題
モノリポジトリのデメリットで最も大きいのは、一部の変更の影響範囲の大きさです。
Terraformは変更を適用するとき、すべての定義についての評価を行い、それぞれの依存関係の解決を行います。そのため一部のインフラ設定の変更によって、想定していなかったリソースへの影響が及ぶ可能性があります。
その内容については、変更計画を確認するterraform plan
コマンドの結果をよく確認していれば気づくことができますが、モノリポジトリで運用していると、インフラ設定の増加とともに運用負荷が増えることになります。
このほか、モノリポジトリを運用する中で問題になりやすいのはTerraformのState Locking機能を利用している場合です。この問題について説明します。
State Lockingは、Terraformが管理している現在のリソースの状態
この機能を使うことで、複数人で同じTerraformリポジトリを運用している場合などに、インフラ設定の変更作業の競合によってStateが壊れるのを防ぐことができます。Terraformコマンドを実行してロックが取得できなければ、そのコマンドは続行されません。
Terraformをチームで運用する場合にはほぼ必須とも言える機能なのですが、同時に、同じTerraformリポジトリについての並列での変更作業が難しくなるということでもあります。
どういうことかというと、Terraformの変更には、変更を適用するterraform apply
コマンドと最新の設定を取得してStateを同期するterraform plan
コマンドがあります。
terraform apply
が失敗することは複数人運用にはあまり影響がない一方で、terraform plan
コマンドでは、リソースの最新の設定を取得してStateを同期する
それ以外にも、Terraformを有効に活用して多くのリソースを管理するようになればなるほど、CIの実行時間が増加していき、ロックを取得できない時間も増加していくことになります。
マルチリポジトリのメリット・デメリット
こうしたデメリットの影響は、モノリポジトリを複数のリポジトリに分割して、問題を解消することができます。
マルチリポジトリとは、特定の単位でリポジトリを分割する構成であり、複雑なインフラを複数または大規模なチームで運用している場合に有効です。
マルチリポジトリを採用した場合のメリット / デメリットは以下のとおりです。
メリット
- それぞれのサービスごとにインフラ設定を管理することができる
- リポジトリが独立しているため、個別にモジュールのセキュリティと機能をテストすることができる
- リポジトリごとに、モジュールのバージョン管理を適用できる
- リポジトリごとに、モジュールとディレクトリへのアクセス制御ができる
- リポジトリへの変更の影響範囲を最小限に抑えることができる
デメリット
- リポジトリ内で多くのリモートモジュールを参照する場合、それらのダウンロードに時間がかかる
もちろんモノリポジトリとマルチリポジトリのどちらが正しい / 間違っている、ということはないので、それぞれの組織やプロダクトに合わせて最適な構成を模索することが重要になります。
『家族アルバム みてね』におけるTerraform リポジトリの分割例
前述したHashiCorpのマルチリポジトリの例では、リポジトリはビジネスドメインやプロダクトのチームごとに分割されていました。
ここでは
『みてね』
みてねのシステムは、Amazon EKSクラスタ上でRuby on Railsのアプリケーションが起動し、CloudFrontおよびALB
データベースにはAmazon RDS Aurora
『みてね』のTerraformリポジトリ分割
このようにシンプルな構成ですが、実際には下記のようにそれぞれの機能ごとに多くのリソースを作成するため、
- EKSクラスタに関連するさまざまなリソース
- サブ・
サービスごとのネットワーク設定やデータストア - ドメインごとのルーティング設定
- 開発者のアカウント管理
- その他、マネージドサービス
図1は簡素化した
このインフラ設定を下記の Terraform リポジトリ構成で管理しています。
ちなみに商用 / 検証環境の分離には、Terraform Workspaces を活用しています。
-- SERVICE-DIRECTORY/
# Kubernetes : EKS
-- kubernetes/
-- modules/
-- <service-name>/
-- main.tf
-- variables.tf
-- outputs.tf
-- ...other...
-- main.tf
-- variables.tf
# 商用環境の設定値
-- prod.tfvars
# 検証環境の設定値
-- dev.tfvars
# データストア : RDS Aurora, ElastiCache
-- database/
-- ...省略...
# 外部との通信 : Route53, CloudFront, ALB
-- ingress/
-- ...省略...
# その他のリソース : S3, SQS, SES など
-- resources/
-- ...省略...
みてねのTerraformマルチリポジトリのメリット・デメリット
この構成を採用した場合には、前述したマルチリポジトリのメリットをさらに効果的に享受することができます。
とくにKubernetesやデータストアのコンポーネントごとに適用ができるため、変更の影響範囲は最小限に抑え、複数人での変更作業もほとんど競合することなく並列して進めることができます。
一方、デメリットは以下のとおりです。
- Terraformリソースの属性をリポジトリをまたいで参照することができない
- リソースの依存関係を注入するために、適切に変数設定をする必要がある
- インフラの構築には、リソースの依存関係に留意して段階的に行う必要がある
Terraformではリソースの属性を参照し、また別のリソースを作成するために利用することができます。
リポジトリをまたいでの属性の参照はできないため外部から適切に設定を行う必要があります。
しかし、サンドボックス環境のようにスクラップ & ビルドを繰り返さない限り、基本的には一度作成したリソースを削除することは少ないので、運用をするなかで問題にはなりにくいです。AWSの場合はSystems Manager Parameter Storeも利用できるので、属性の用途
最後に
Terraformのプラクティスについては多くの知見が共有されていますが、組織やプロダクトにおいて
それゆえに試行錯誤や特徴が見えるところでもあると思うので、皆さんが考える