every Tech Blog

株式会社エブリーのTech Blogです。

Terraformをマルチテナント対応させる上で意識したこと

この記事は every Tech Blog Advent Calendar 2025 の 20 日目の記事です。

はじめに

こんにちは、リテールハブ開発部の杉森です。

小売向けサービスのインフラ基盤を管理している中で、マルチテナント対応を行うことになりました。
本記事では、既存のTerraformコードをマルチテナント対応させた際の取り組みと、意識したポイントについて紹介します。

実施概要

変更前の構成

既存のTerraformの構成は以下のような形になっていました。

この構成では、新しいテナントを追加する際にvariable.tfから全てのファイルをテナントごとに複製して作成する必要がありました。

各テナントごとに共通化している部分と独立しているリソースがあり、独立したリソースの追加や共通化しているリソースの変更が困難な状態でした。

変更後の構成

以下のような構成に変更しました。

この変更により、variables.tfにテナント情報を追記してterraform applyするだけでテナントの追加ができるようになりました。

以下は簡略化したコード例です。

# variables.tf
variable "tenants" {
  default = {
    tenantA = { ... }
    tenantB = { ... }
  }
}

# main.tf
module "s3" {
  ...
  tenants = var.tenants
}

# s3.tf
resource "aws_s3_bucket" "tenant_media" {
  for_each = var.tenants
  ...
}

意識したこと

大幅なTerraformのコード修正をする上で、意識したことを紹介します。
※マルチテナント対応する上で、各リソースをどのように分離と共通化をしたかという設計部分の内容は記載しておりません。

1. AIエージェントで徹底的に疑問を解消する

入社して間もなかったため、既存のインフラ構成に詳しくありませんでした。また、AWS自体は触ったことがありましたが、Terraformは未経験でした。

そこで「既存のインフラ構成について」と「Terraformについて」の2つについて、気になることがなくなるまでClaude Codeに壁打ちをしました。例えば「この設定は何のためにあるのか」「この書き方はTerraformとして適切か」といった疑問を一つずつ解消していきました。

十分な知識がない状態でいきなりコードを書き始めると、表面的な動作確認だけで終わってしまいがちです。土台や前提を理解することで、自分が書いたコードに責任を持てるようになると考えています。

2. 不必要にリファクタリングをしない

コード全体に影響する対応をしていると、「ここも直したい」という改善点が次々と見えてきます。しかし、逐一対応してしまうと本来のゴールから外れ、タスクの完了が後ろ倒しになってしまいます。

そこで今回は、マルチテナント対応の障壁にならないリファクタは実施せず、Asana上にチケットとして起票して後回しにしました。

「ついでに直す」は一見効率的に見えますが、スコープが曖昧になりやすいです。裁量のあるエンジニアであればあるほど曖昧になりやすいため、目の前のタスクに集中し、改善点は別途管理する意識が大切だと考えています。

3. AWS側のリソース変更を最小限にする

今回の対応ではすでに本番稼働しているテナントAと新規で追加するテナントBが存在します。 そのため、可能な限りテナントAのリソース変更やダウンタイムは最小限になるようにしました。

その施策の一つに、movedブロックの活用があります。

terraformはデフォルトの挙動として、リソース自身の構成が同一の内容であったとしても、アドレスが変更された場合、破棄と作成が実施されます。
リリースをした際に適切にmovedブロックを実施し、破棄が発生しないようにしました。

また、将来的に移行した内容をgithub上で追跡できるように、state mvコマンドではなく、movedブロックを利用しました。

以下はmovedブロックの例です。

# リソースアドレスの変更を追跡
moved {
  from = aws_s3_bucket.tenant_media
  to   = aws_s3_bucket.tenant_media["tenantA"]
}

参考リンク https://developer.hashicorp.com/terraform/language/modules/develop/refactoring

4. AIコードレビューを活用する

今回の対応では、CodeRabbitとGitHub Copilotを活用してコードレビューを実施しました。

大規模なコード変更では、人間のレビュアーだけでは見落としが発生しやすくなります。AIコードレビューを併用することで、以下のようなメリットがありました。

  • 変更漏れの検出: 大量のファイル変更の中から、意図しない変更や修正漏れを指摘してもらえた
  • ベストプラクティスの提案: Terraformの書き方について、より良い記述方法を提案してもらえた

AIによるコードレビューを効果的に活用するためには、些細な指摘や精度の低い指摘であっても無視せず、一つ一つの内容を精査し、意図を汲み取ろうとすうる姿勢が大切だと感じました。

5. 最終確認をしっかりする

大規模な変更では、PRレビューだけでは全体の整合性を見落としやすくなります。特にインフラの変更は、Terraformのコードだけでなく、バックエンドやフロントエンドのコード、リリース手順書など、関連する様々な領域に影響を及ぼすことがあります。

そこでリリース前に、チームメンバー全員で変更内容を横断的に確認する会を設けました。実際に考慮漏れを発見でき、各メンバーの理解も深まったため、時間をかけた価値がありました。

最後に

今回の対応により、新規テナントの追加がvariables.tfへの追記とterraform applyだけで完結するようになりました。 まだまだ改善の余地がありますが、予定通りリリースでき、運用負荷の軽減を実現できました。 今後もより良い構成を目指して改善を続けていきます。