Webサービスを運用し続けるためのTerraform設計 ─ AWSのサービスを目的の単位で組み替える

 公開 2026-09-13

AWSのサービスを組み合わせるたびに設計をやり直すと、プロジェクトごとに作りがばらつく。ECSを中心とするWebサービスを運用し続けるという目的の単位でTerraformを組み替え、環境ごとの記述を「宣言と配線」に絞る設計の考え方と、それを支える規則・品質の担保・運用の循環を解説する。

AWSでWebサービスを作るとき、ECS、ALB、IAM、CloudWatchといったサービスをどう組み合わせるかを、プロジェクトのたびに一から考えていないだろうか。 その結果、同じ会社の中でも、デプロイの仕組み、権限の付け方、監視の置き場所がプロジェクトごとに違ってくる。 本稿では、当社がECSを中心とするWebサービスをTerraformで構築・運用するときの設計の考え方を、読者が自分の設計に持ち帰れる規則として解説する。

1. 課題: サービスの単位で並べると、設計が毎回やり直しになる

AWSのAPIは、サービスごとに独立して提供されている。Terraformでも、サービスごとにリソースを書くことはできる。 しかしWebサービスを運用する側が知りたいのは、個々のサービスの設定よりも、次のような問いへの答えである。

運用で問われること
サービスの単位で並べたときに起きること
新しいバージョンをどう安全にリリースするか
デプロイの仕組みがプロジェクトごとに違い、手順を毎回覚え直す
誰がどのリソースを操作できるか
権限の定義がリソースごとに散らばり、全体像を把握できない
障害にどう気づき、どう調べるか
監視や通知の置き場所がばらつき、調査の起点が定まらない
構成を変えたとき、どこに影響するか
リソース間のつながりが文字列で書かれ、変更の影響を追いにくい

サービスの知識があっても、これらの問いへの答え方を決めていなければ、設計はプロジェクトのたびにやり直しになる。

2. 考え方: 運用し続ける目的の単位で組み替える

当社では、AWSのサービスをサービスの単位のまま並べるのではなく、ECS/Fargateを中心としたWebサービスを公開し、運用し続けるという目的の単位でTerraformを組み替えている。

左にECS、ALB、IAM、CloudWatchの4つのサービスがあり、中央の「目的の単位で組み替える」を経て、右の公開、リリース、監視・通知、権限と通信の4つの目的へつながる図

たとえば「リリースする」という目的には、ECSのサービス、ALBのターゲットグループ、デプロイの制御、承認、ロールバックが関わる。 これらを1つの目的のまとまりとして設計しておけば、新しいプロジェクトでも同じ考え方で、同じ判断を再利用できる。

目的の単位で組み替えることは、サービスの細部を隠すことではない。 何度も決め直している判断を、一度だけ設計して使い回すための整理である。

3. 構造: 部品、組み合わせ、環境ごとの記述

組み替えた構成は、3つの層で考える。

上から、環境ごとの記述(値の宣言と配線)、構成のまとまり(目的ごとに組み合わせる)、単機能の部品(リソースを作る)、AWSリソースの順につながり、部品の出力が環境ごとの記述へ戻る図
役割
書くもの
単機能の部品
AWSのリソースを作る
どのリソースを、どの設定で作るか。そのリソースに必要な権限と出力
構成のまとまり
部品を目的ごとに組み合わせる
「リリースする」「ログを分析する」などの目的に必要な部品のつながり
環境ごとの記述
環境に固有の値を決め、部品やまとまりをつなぐ
値の宣言、既存リソースの参照、部品の出力を別の部品の入力へ渡す配線

この構造でいちばん重要なのは、環境ごとの記述を「宣言と配線の場所」に限ることである。 環境ごとの記述の中でAWSのリソースを直接作ることは、原則として行わない。例外を設ける場合は、理由を明記し、恒久化しない。

こうしておくと、環境ごとの記述を読めば「この環境が何で構成され、何と何がつながっているか」が分かり、リソースの作り方は部品の側だけで管理できる。

4. 責務の置き場所: 持ち帰れる5つの規則

構造を決めても、どこに何を書くかが人によって違えば、作りはまたばらつく。当社では次の規則で置き場所を決めている。

規則1: 権限の外形は環境ごとに、厳密な権限は部品の側に

IAMのロールそのものは、環境ごとの記述でまとめて作り、一覧できるようにする。 一方、特定のリソースへのアクセスのような厳密な権限は、そのリソースを作る部品の側で追加する。 リソースを消すと、そのリソースのための権限も一緒に消える。

規則2: 保存先、ログ、通信許可は共通の場所にまとめる

S3のバケット、ログの出力先、Security Groupは、共通の場所でまとめて定義する。 散らばると、何が存在するかを把握できず、不要なものが残り続けるためである。

規則3: 部品どうしは出力でつなぐ

ある部品が作ったリソースを別の部品が使うときは、部品の出力を受け取って渡す。 部品の内部の実装に、別の部品から直接触れない。

規則4: ARNは組み立てず、参照する

リソースのARNを文字列で組み立てると、書き間違いに気づきにくく、元のリソースとのつながりもコードから読み取れない。

参照にすると、Terraformはその値がどのリソースから来たかを把握でき、依存関係も参照から推測される。 HashiCorpも、明示的な depends_on より、式の参照によって依存関係を表すことを推奨している。

規則5: 入力の検査は、複数の値の整合性だけに絞る

部品が受け取る値の検査は、「この値を指定するなら、あの値も必要」といった複数の値の間の整合性に限る。 単一の値の書式、長さ、範囲の検査は、プロバイダとAWSのAPIに任せる。 同じ検査を部品の側にも書くと、AWS側の仕様が変わったときに部品の検査だけが古くなり、正しい値を拒むおそれがあるためである。

5. 品質の担保: 最小の入力で計画が通ることを確かめる

部品は多くのプロジェクトから使われる。1つの不具合が、その部品を使うすべての環境に影響する。 当社では、省略できる値をすべて省いた最小の入力で、Terraformの計画(plan)が成功することを確かめるテストを、すべての部品に必須のルールとして定めている。

Terraformのテスト機能では、テストの実行を計画に限定すると、実際のリソースを作らずに設定の論理や条件を検証できる。 また、プロバイダが返す値をモックして、AWSに接続せずに検証することもできる。

このテストを重視しているのは、落ちたときの影響がいちばん大きいからである。 テストを導入した際には、実際に次のような不具合が見つかった。いずれも「その値を指定しないすべての利用者が使えなくなる」種類の不具合だった。

不具合の類型
起きること
省略された値が計算や比較に流れ込む
値を指定しない利用者の計画が失敗する
条件によって作られないリソースを、出力が無条件に参照する
そのリソースを作らない構成で失敗する
出力を二重に定義している
初期化の段階から失敗し、部品をまったく使えない
省略可能と宣言しているが、実質は必須になっている
省略した利用者だけが失敗する

レビューで目視しても見落としやすい不具合を、機械的に拾えることがこのテストの価値である。

同じ考え方で、4章の規則もモジュール群と一緒に配布し、利用するプロジェクト側で同じ規則を読めるようにしている。 特定のプロジェクト名や環境名が部品に混入していないかといった検査は、スクリプトで機械的に行う。 規則を文書として配るだけでなく、守られているかを機械で確かめられる範囲を広げていくことが、品質を保つための方針である。

6. 運用の循環: レビュー、反映、観測、AIによる分析

構成は作って終わりではなく、運用しながら改善していく。当社では次の循環で改善を進めている。

レビュー承認、AWSへ反映、観測、AIが分析の4つが順につながり、AIの分析から人が判断してレビュー承認へ戻る循環の図
  1. アプリケーションのコードとインフラの設定コードを更新し、レビューで承認する
  2. 承認されたコードをAWSへ反映する
  3. 障害、性能の劣化、変更の要求が起きたとき、AIがAWSの実環境の情報とTerraformのコードを読み取り、原因と改善案を整理する
  4. AIの出力を、Terraformの修正案、実装の提案、原因の説明、構成の提案として人が判断し、採用するものは再びレビューに回す

AIの出力は、人が採否を判断する提案として扱う。コードの変更は、レビューの承認を経てからAWSへ反映する。

この循環は、2〜4章の設計と相性がよいと当社は考えている。 構成が目的の単位で整理され、置き場所の規則が揃っていれば、AIが実環境とコードを照合するときの手がかりが一定になり、提案を人がレビューするときにも同じ観点で確認できるためである。

AIが読む範囲を、構成の側で絞る

AWS Summit Japan 2026 のセッション「AI が開発/運用しやすいクラウド サーバーレスの視点から考える設計原則」(CNS449)では、 AIのコーディングエージェントは読み込む情報が増えるほど精度が落ちることを前提に置き、AIに読ませる範囲を文書だけでなくアーキテクチャで絞るという設計原則が示された。 境界を明確にしてインターフェースだけで判断できる状態にすること、構造上の規則を文書ではなく機械的な検査で守らせることが、その具体策として挙げられている。

2〜5章の設計は、この考え方と同じ方向を向いている。

講演で示された考え方
本稿の設計
境界を明確にし、変更の影響を閉じ込める
目的の単位での組み替え(2章)、部品・組み合わせ・環境ごとの記述の3層(3章)
インターフェースだけを読んで判断できる状態にする
部品どうしを出力でつなぎ、ARNは参照する(4章 規則3・4)
構造上の規則を機械的に検査する
最小の入力での計画の検証と、規則の機械的な検査(5章)

一方で、講演が挙げる運用エージェント向けの可観測性(構造化したログやトレースで、サービス境界をまたいで調査できること)は、本稿の範囲ではまだ規則として定めていない。 AIによる分析の精度を上げるために、今後取り組む領域である。

7. 責務領域から個別のテーマへ

ここまでの考え方は、個別のテーマに分けて具体化している。テーマは、変更の性質で分けた4つの責務領域から辿れる。

責務領域
扱う変更
個別のテーマの例
アプリケーション実行
アプリケーションのコード、コンテナ、環境変数、シークレットの参照、タスクの実行
コンテナの設定値とシークレットの管理
リリース管理
ビルド、タスク定義の生成、デプロイ、承認、ロールバック
ECSのBlue/Greenデプロイの方式の選び方
サービス運用
日常の更新、監視、通知、障害対応、監査、セキュリティ運用
イベント駆動で作る障害検知、日次のコスト通知、ログ分析の基盤、運用管理画面の置き場所構成の出力から作る運用管理画面、インフラ担当と運用担当の責務分離
IaC・基盤管理
Terraform、ネットワーク、IAM、Security Group、共通の基盤
IAMとSecurity Groupによるアクセス制御、それぞれの一括管理

個別のテーマは、複数の責務領域にまたがってよい。責務領域は、記事を読むときの補助線である。

8. まとめ

設計判断
内容
目的の単位で組み替える
AWSのサービスを並べるのではなく、Webサービスを公開・運用し続ける目的でまとめ、判断を使い回す
環境ごとの記述は宣言と配線に限る
リソースの作り方は部品の側で管理し、環境ごとの記述は構成とつながりを示す場所にする
置き場所を規則で決める
権限の外形と厳密な権限、共通の保存先、出力による接続、ARNの参照、入力の検査の範囲
最小の入力で計画を検証する
すべての部品に必須とし、利用者全体を止める種類の不具合を機械的に拾う
レビューとAIの分析で循環させる
AIの提案を人が判断し、コードの変更はレビューの承認を経て反映する

AWSのサービスを知っていることと、Webサービスを運用し続けられる構成を作れることの間には距離がある。 その距離を埋めるのは、個々のサービスの知識よりも、何を一度だけ設計し、どこに何を書くかを決めておくことである。