AWSでWebサービスを作るとき、ECS、ALB、IAM、CloudWatchといったサービスをどう組み合わせるかを、プロジェクトのたびに一から考えていないだろうか。 その結果、同じ会社の中でも、デプロイの仕組み、権限の付け方、監視の置き場所がプロジェクトごとに違ってくる。 本稿では、当社がECSを中心とするWebサービスをTerraformで構築・運用するときの設計の考え方を、読者が自分の設計に持ち帰れる規則として解説する。
1. 課題: サービスの単位で並べると、設計が毎回やり直しになる
AWSのAPIは、サービスごとに独立して提供されている。Terraformでも、サービスごとにリソースを書くことはできる。 しかしWebサービスを運用する側が知りたいのは、個々のサービスの設定よりも、次のような問いへの答えである。
サービスの知識があっても、これらの問いへの答え方を決めていなければ、設計はプロジェクトのたびにやり直しになる。
2. 考え方: 運用し続ける目的の単位で組み替える
当社では、AWSのサービスをサービスの単位のまま並べるのではなく、ECS/Fargateを中心としたWebサービスを公開し、運用し続けるという目的の単位でTerraformを組み替えている。
たとえば「リリースする」という目的には、ECSのサービス、ALBのターゲットグループ、デプロイの制御、承認、ロールバックが関わる。 これらを1つの目的のまとまりとして設計しておけば、新しいプロジェクトでも同じ考え方で、同じ判断を再利用できる。
目的の単位で組み替えることは、サービスの細部を隠すことではない。 何度も決め直している判断を、一度だけ設計して使い回すための整理である。
3. 構造: 部品、組み合わせ、環境ごとの記述
組み替えた構成は、3つの層で考える。
この構造でいちばん重要なのは、環境ごとの記述を「宣言と配線の場所」に限ることである。 環境ごとの記述の中でAWSのリソースを直接作ることは、原則として行わない。例外を設ける場合は、理由を明記し、恒久化しない。
こうしておくと、環境ごとの記述を読めば「この環境が何で構成され、何と何がつながっているか」が分かり、リソースの作り方は部品の側だけで管理できる。
4. 責務の置き場所: 持ち帰れる5つの規則
構造を決めても、どこに何を書くかが人によって違えば、作りはまたばらつく。当社では次の規則で置き場所を決めている。
規則1: 権限の外形は環境ごとに、厳密な権限は部品の側に
IAMのロールそのものは、環境ごとの記述でまとめて作り、一覧できるようにする。 一方、特定のリソースへのアクセスのような厳密な権限は、そのリソースを作る部品の側で追加する。 リソースを消すと、そのリソースのための権限も一緒に消える。
規則2: 保存先、ログ、通信許可は共通の場所にまとめる
S3のバケット、ログの出力先、Security Groupは、共通の場所でまとめて定義する。 散らばると、何が存在するかを把握できず、不要なものが残り続けるためである。
規則3: 部品どうしは出力でつなぐ
ある部品が作ったリソースを別の部品が使うときは、部品の出力を受け取って渡す。 部品の内部の実装に、別の部品から直接触れない。
規則4: ARNは組み立てず、参照する
リソースのARNを文字列で組み立てると、書き間違いに気づきにくく、元のリソースとのつながりもコードから読み取れない。
# 概念例: 避ける書き方(文字列で組み立てる)
|
resources = ["arn:aws:s3:::${var.bucket_name}/*"]
|
|
# 概念例: 採る書き方(リソースの属性を参照する)
|
resources = ["${aws_s3_bucket.logs.arn}/*"] |
参照にすると、Terraformはその値がどのリソースから来たかを把握でき、依存関係も参照から推測される。
HashiCorpも、明示的な depends_on より、式の参照によって依存関係を表すことを推奨している。
規則5: 入力の検査は、複数の値の整合性だけに絞る
部品が受け取る値の検査は、「この値を指定するなら、あの値も必要」といった複数の値の間の整合性に限る。 単一の値の書式、長さ、範囲の検査は、プロバイダとAWSのAPIに任せる。 同じ検査を部品の側にも書くと、AWS側の仕様が変わったときに部品の検査だけが古くなり、正しい値を拒むおそれがあるためである。
5. 品質の担保: 最小の入力で計画が通ることを確かめる
部品は多くのプロジェクトから使われる。1つの不具合が、その部品を使うすべての環境に影響する。 当社では、省略できる値をすべて省いた最小の入力で、Terraformの計画(plan)が成功することを確かめるテストを、すべての部品に必須のルールとして定めている。
Terraformのテスト機能では、テストの実行を計画に限定すると、実際のリソースを作らずに設定の論理や条件を検証できる。 また、プロバイダが返す値をモックして、AWSに接続せずに検証することもできる。
このテストを重視しているのは、落ちたときの影響がいちばん大きいからである。 テストを導入した際には、実際に次のような不具合が見つかった。いずれも「その値を指定しないすべての利用者が使えなくなる」種類の不具合だった。
レビューで目視しても見落としやすい不具合を、機械的に拾えることがこのテストの価値である。
同じ考え方で、4章の規則もモジュール群と一緒に配布し、利用するプロジェクト側で同じ規則を読めるようにしている。 特定のプロジェクト名や環境名が部品に混入していないかといった検査は、スクリプトで機械的に行う。 規則を文書として配るだけでなく、守られているかを機械で確かめられる範囲を広げていくことが、品質を保つための方針である。
6. 運用の循環: レビュー、反映、観測、AIによる分析
構成は作って終わりではなく、運用しながら改善していく。当社では次の循環で改善を進めている。
- アプリケーションのコードとインフラの設定コードを更新し、レビューで承認する
- 承認されたコードをAWSへ反映する
- 障害、性能の劣化、変更の要求が起きたとき、AIがAWSの実環境の情報とTerraformのコードを読み取り、原因と改善案を整理する
- AIの出力を、Terraformの修正案、実装の提案、原因の説明、構成の提案として人が判断し、採用するものは再びレビューに回す
AIの出力は、人が採否を判断する提案として扱う。コードの変更は、レビューの承認を経てからAWSへ反映する。
この循環は、2〜4章の設計と相性がよいと当社は考えている。 構成が目的の単位で整理され、置き場所の規則が揃っていれば、AIが実環境とコードを照合するときの手がかりが一定になり、提案を人がレビューするときにも同じ観点で確認できるためである。
AIが読む範囲を、構成の側で絞る
AWS Summit Japan 2026 のセッション「AI が開発/運用しやすいクラウド サーバーレスの視点から考える設計原則」(CNS449)では、 AIのコーディングエージェントは読み込む情報が増えるほど精度が落ちることを前提に置き、AIに読ませる範囲を文書だけでなくアーキテクチャで絞るという設計原則が示された。 境界を明確にしてインターフェースだけで判断できる状態にすること、構造上の規則を文書ではなく機械的な検査で守らせることが、その具体策として挙げられている。
2〜5章の設計は、この考え方と同じ方向を向いている。
一方で、講演が挙げる運用エージェント向けの可観測性(構造化したログやトレースで、サービス境界をまたいで調査できること)は、本稿の範囲ではまだ規則として定めていない。 AIによる分析の精度を上げるために、今後取り組む領域である。
7. 責務領域から個別のテーマへ
ここまでの考え方は、個別のテーマに分けて具体化している。テーマは、変更の性質で分けた4つの責務領域から辿れる。
個別のテーマは、複数の責務領域にまたがってよい。責務領域は、記事を読むときの補助線である。
8. まとめ
AWSのサービスを知っていることと、Webサービスを運用し続けられる構成を作れることの間には距離がある。 その距離を埋めるのは、個々のサービスの知識よりも、何を一度だけ設計し、どこに何を書くかを決めておくことである。
