Terraformで本番サーバーを構築する現場の設計判断5選

Terraformによる本番構築が立ち止まる原因の多くは、コードの書き方ではなく「設計の判断」を後回しにしたことにある。モジュールの粒度、環境分離の方式、変数の外出し境界、破壊的変更の封じ方、手動リソースとの共存——この5つの判断を構築開始前に揃えておくと、運用フェーズで発生する手戻りが大幅に減る。それぞれの選択肢と、現場で機能する判断基準を解説する。

なぜ本番Terraformは「書き方」より「設計判断」で差がつくのか

コードが丁寧でも壊れる運用

Terraformの学習コンテンツの多くは、リソース定義の文法やモジュールの組み方といった「書き方」に焦点を当てる。しかし実際の本番構築プロジェクトで問題が起きる場所は、構文エラーや型ミスではなく「設計の意思決定をどこかで先送りにした箇所」であることが多い。環境ごとに微妙に異なる変数をどう管理するか、モジュールをどの単位で切るか——こうした判断を「後で考えよう」と曖昧にしたまま進めると、半年後の変更対応で大きな手戻りが発生する。構築を任されたある担当者が、後から「あのときモジュール境界を決めておけばよかった」と振り返るケースは珍しくない。3環境(dev/stg/prod)を管理するリポジトリが、1年後には誰も全容を把握できない状態になっていた、という話は現場でよく聞く。問題の根は「書き方」ではなく「判断のタイミング」にある。

「後で直す」が一番高くつく

インフラコードの修正コストは、アプリケーションコードと比べて格段に高い。コードを書き直すだけでなく、実際のリソースをplan→apply→動作確認のサイクルで追いながら変更しなければならない。Terraform stateと実リソースの整合が崩れた場合は、さらに複雑な復旧作業が待つ。モジュール分割の方針を途中で変えると、stateのmv操作が数十行に及ぶことがある。環境分離の方式を変更する場合は、全リソースを一度destroyして作り直すか、手作業でstateを移行するかの二択になる事例も多い。設計判断の変更コストは時間が経つほど大きくなる構造を持っている。

5つの判断を先に決める意味

本記事で取り上げる5つの判断は独立しているように見えて、互いに絡み合っている。モジュールの粒度と変数の外出し境界は密接に関係するし、環境分離の方式は破壊的変更リスクの発生パターンにも影響する。5つをばらばらに決めるのではなく、プロジェクト初期に一括して方針を揃えておくと、後続の判断が格段に楽になる。以降では判断ごとに選択肢の特性と落とし穴を整理する。

判断1: モジュール分割の粒度をどこで切るか

粒度が細かすぎるときの落とし穴

モジュールをリソース単位で細かく切ると、再利用性が高まる一方で「呼び出し元が複雑になりすぎる」問題が起きやすい。VPC、サブネット、セキュリティグループをそれぞれ独立モジュールにした場合、ルートモジュールにdependsの連鎖が発生し、moduleブロックが20個を超えることもある。呼び出し元だけを見ても全体像がつかめず、新しいメンバーが参入したときの学習コストが高くなる。変数の受け渡しが多段になると、一つの値変更が連鎖して予期しない場所に波及する。「インターフェースが多すぎるモジュール構成」は、見た目には整頓されているが実態としては管理が難しいアンチパターンだ。ソフトウェア開発での過度な抽象化と同じ失敗が、インフラコードでも起きる。

粒度が粗すぎるときの落とし穴

逆にモジュールをほとんど切らず、全リソースを一つのルートモジュールに詰め込む構成もある。小規模なうちは見通しがよいが、リソース数が50を超えたあたりから「どこを変えたら何が変わるか」の把握が難しくなる。plan実行時の差分が長くなり、意図しないリソースへの変更を見逃しやすくなる。チームで作業する場合はstateのlockが全体にかかるため、並列作業の効率も落ちる。1人が長時間のapplyを走らせると、他のメンバーが一切操作できない状態が続く。規模が大きくなるほど、粗すぎる構成のデメリットが顕在化する。

実務的な分割基準

現場でよく機能する分割の基準は「ライフサイクルと変更頻度が違うものを別モジュールにする」という考え方だ。ネットワーク基盤(VPC・サブネット・IGW)は一度作ったらほぼ変わらない。一方、アプリケーション層(EC2・ALB・Security Group)は頻繁に変更が入る。この二つを同じstateで管理すると、頻繁な変更のたびにネットワーク基盤への差分チェックが走り、心理的な負担と誤操作のリスクが増す。判断の目安として、一つのmoduleが管理するリソース数は10〜30個が扱いやすい範囲とされる。それを超えてきたら分割を検討するサインと見るとよい。ただし機械的に数を守るより「変更頻度と責任の境界」を軸に考えるほうが実態に合う。

判断2: 環境分離(dev/stg/prod)をworkspaceで持つかディレクトリで持つか

workspaceアプローチの特性と限界

Terraform workspaceは一つのコードベースで複数の環境を管理できる仕組みだ。`terraform workspace new stg`でstg用のstateを作り、コード上は`terraform.workspace`変数で環境名を参照してリソース名やスペックを切り替える。コードの重複を排除できる点が魅力で、小〜中規模かつ環境差分が少ないケースで有効に機能する。しかし、環境ごとの差分が大きくなると`terraform.workspace`による条件分岐がコード中に散在し始め、可読性が落ちる。prodだけ異なる設定(特殊なSecurity Group、マルチAZ構成、専用のKMSキーなど)が増えるほど、workspaceのメリットは薄れる。また、`terraform workspace select prod`を手動で操作する際の選択ミスは実害につながるため、CI/CDに組み込まない運用では人的ミスのリスクを内包する。

ディレクトリ分離アプローチの特性

ディレクトリ分離は`environments/dev`、`environments/stg`、`environments/prod`のようにディレクトリを切り、それぞれに独立したstateを持つ方式だ。環境ごとの差分を明示的に管理でき、「prodだけに存在するリソース」が一目でわかる。stateが分離されているため、dev環境での操作がprodのstateに影響することはない。デメリットはコードの重複だ。共通部分はモジュール化で吸収できるものの、ルートモジュールの記述が環境数分だけ存在することになる。環境を追加するたびにディレクトリのコピーと調整が必要で、変更を全環境に横展開する際の管理コストも高い。Terragruntのようなラッパーツールを使うとこの冗長性を緩和できるが、ツール依存が増える点は考慮が必要だ。

判断の分岐点と方式比較

観点 workspace方式 ディレクトリ分離方式
環境差分の大きさ 小さい場合に向く 大きい場合に向く
stateの独立性 workspace選択ミスのリスクあり 完全独立・物理的に安全
コードの重複 少ない 多い(モジュール化で緩和可)
誤操作リスク 切替ミスが本番に直撃しうる ディレクトリが物理的に分離
CI/CD連携 workspace切替の自動化が必要 パス変数で環境を指定しやすい
向いている規模 小〜中規模・環境差分少 中〜大規模・環境差分多

本番環境がstg・prodで明確に異なる要件を持つ場合(冗長構成、専用KMS、コンプライアンス要件など)は、ディレクトリ分離を選ぶほうが後の管理が楽になる。反対に3環境を同一構成で動かすシンプルな構造ならworkspaceで十分だ。どちらを選んでも、採用理由を一文残しておくことが後から加わる担当者への最大の貢献になる。

■ この設計判断を深める一冊[PR]

実践Terraform AWSにおけるシステム設計とベストプラクティス(野村友規/NextPublishing)

本記事の設計判断を、AWS上のIaC実装に落とし込む実務書です。state設計やベストプラクティスを手を動かして確かめたい構築担当者に向いています。

Amazonで見る →

判断3: 変数の外出し境界 — どこまでコード、どこから設定値か

コード内に書くべきものと外に出すべきもの

Terraformのコードには「変えてはいけない設計上の定数」と「環境・実行ごとに変わる設定値」が混在する。前者はコード内にhardcodeしてよい。たとえば「このサブネットのCIDRは/24で設計した」という判断そのものは、変数化して外から書き換えられるようにするより、コードに固定して履歴に残すほうが設計の意図が伝わりやすい。逆に環境ごとに変わるもの(インスタンスタイプ、レプリカ数、ドメイン名、各種フラグ)は外出しが必要だ。ここで問題になるのは「外出しの場所」をどこにするかだ。tfvars、環境変数、SSM Parameter Store、HashiCorp Vault——選択肢は複数あり、それぞれ適切なユースケースがある。

tfvarsとSSM/Vaultの使い分け

tfvarsは設定値をGitで管理できる利点がある。非機密の設定(インスタンスタイプ、リージョン、タグ名など)はtfvarsをGitにコミットし、PRレビューで変更を確認できる運用が望ましい。環境ごとに`dev.tfvars`、`stg.tfvars`、`prod.tfvars`を用意する構成が多い。機密情報(DBパスワード、APIキー、証明書)はGitに入れてはならない。SSM Parameter StoreやHashiCorp VaultをTerraformから参照する形にし、コードには「どのSSMパスから取るか」だけを書く設計が標準的だ。この境界を最初に引いておかないと、後からtfvarsに入ったシークレットを削除する作業——Gitの履歴ごとの清書を含む——が発生する。

外出しのやりすぎが招く問題

変数外出しの行き過ぎも落とし穴だ。「すべてを変数化すれば柔軟性が上がる」という発想で50個以上の変数を定義したリポジトリを引き継いだ担当者が、どの変数が必須でどれがオプションかを把握するだけで相当な時間を要した、という話がある。変数が多すぎると、逆に何も変えられないコードになる。変数化の判断基準は「実際に環境間で変わるか」と「外から変えることに意味があるか」の2点だ。「変えられる」だけを理由に変数化するのではなく、運用で変更が想定される値だけを外出しする。設計の自由度と管理コストはトレードオフであることを前提に境界を引く必要がある。

判断4: 破壊的変更(destroy/replace)をどう設計で封じるか

destroyとreplaceが起きる条件

Terraformでは一部のリソース属性を変更すると、既存リソースを削除して新規作成(replace)するか、リソース全体を削除(destroy)する動作が起きる。代表的なのはEC2インスタンスのAMI変更、RDSのエンジン種別変更、セキュリティグループの結びつき変更などだ。これらは`terraform plan`の出力に`-/+`または`forces replacement`として現れるが、レビューを飛ばして`apply`を実行すると本番データやサービスに直接影響する。特に危険なのは「意図せずreplaceが発生するケース」だ。モジュールのインターフェースを変更した際に、内部のリソース属性への参照が変わりreplaceトリガーが引かれることがある。コードの変更量は小さいのに、planを見ると本番RDSのreplaceが含まれていた——という状況は、reviewの目が行き届かないチームで発生しやすい。

lifecycleブロックによる封じ方

Terraformには`lifecycle`ブロックがあり、`prevent_destroy = true`を設定するとそのリソースのdestroy操作が実行時エラーになる。本番DBやキーストレージなど、誤削除が致命的なリソースには必ず設定する設計にしておくと、誤った操作を計画段階でブロックできる。また`ignore_changes`は特定の属性の変更をTerraformが無視するよう指示できる。外部システムや手動操作で変更される属性(タグの一部、スケールグループのデシレッドキャパシティなど)に対して使う。ただし使いすぎると「Terraformで管理しているつもりだが実態は追跡されていない属性」が増え、stateとリソースの乖離が静かに拡大する副作用がある。設定する際は必ず理由を残す規律が求められる。

CI/CDでのplan差分レビューとガード設計

設計だけでなくプロセスでも破壊的変更を封じることができる。CI/CDパイプラインに`terraform plan`の出力を解析するステップを組み込み、`forces replacement`や`will be destroyed`を含むplanをマージブロックまたは承認必須にする設計だ。5人以上のチームでTerraformを運用する場合、「誰かがapplyする前に必ずplanレビューのPRがある」という文化を設計段階から仕込んでおくと、運用フェーズの事故が大幅に減る。planのレビューを必須化することは、破壊的変更を防ぐ最も確実な手段の一つだ。OPA(Open Policy Agent)を使うと、planの差分に対してポリシーチェックを自動化することもできる。

判断5: 手動リソースとの共存(importか作り直しか)

importかゼロベース作り直しかの選択

Terraform管理を始める前から存在する手動リソース(コンソールで作ったVPC、既存のEC2、過去のRDSなど)をどう扱うかは、移行プロジェクトでほぼ必ず直面する判断だ。選択肢は大きく二つ——`terraform import`で既存リソースをstateに取り込む方法と、リソースを新規に作り直す方法だ。作り直しが可能な場合はゼロベースを推奨する現場が多い。importはstateにリソースを登録するだけで、コード(.tf)は自分で書かなければならない。コードとstateの整合を取る作業に予想以上の工数がかかり、import後のplanがcleanにならず微妙な差分が残り続けるケースがある。設定項目が多い複雑なリソースほど、完全一致のコードを書くのが難しい。

importのリスクと限界

Terraform 1.5以降では`import`ブロックとgenerated configによるコード自動生成が可能になったが、すべてのリソースタイプで完璧に動くわけではない。生成されたコードには不完全な属性指定が残ることがあり、planを実行するたびに差分が出る状態が続くことがある。この「差分ノイズ」は、本当の変更差分を見逃すリスクを生む。importで取り込んだリソースは「Terraformが作ったリソース」ではないため、リソース内部の依存関係(タグ、ポリシー、バインディング)が想定外の形で残っていることもある。importを選ぶ場合は、import後に必ず`terraform plan`がcleanになること(差分ゼロ)を確認してから次のステップに進む規律が欠かせない。

共存の設計パターン

すぐに作り直せないリソース(長期稼働のDB、移行コストが高いネットワーク基盤など)については、Terraformの管理対象外として明示的に除外する方法もある。data sourceとして読み込み専用で参照する設計だ。`aws_db_instance`をresourceとして管理せず、`data “aws_db_instance”`で参照するだけにすれば、Terraformが誤って変更・削除するリスクがなくなる。手動リソースとTerraform管理リソースの境界を明示的にドキュメント化しておくことも重要だ。どのリソースがTerraform管理でどれが手動管理かを一覧にしておくと、チームメンバーが誤ってimportしようとした際の確認コストが減る。「Terraformで管理できるもの」と「あえて管理対象外にしているもの」を区別する設計の意図を残すことが、長期運用を支える土台になる。

5つの判断を最初に決めておくと後で効く理由

手戻りコストの非対称性

ソフトウェア開発と同様に、インフラコードの設計変更コストは後工程ほど高くなる。インフラの場合はコード変更に加えて「実リソースへの影響」が常についてくるため、その非対称性はさらに大きい。モジュール構造を変えるならstateのmv操作が伴い、環境分離方式を変えるなら全リソースの再作成か手動stateの移行が必要になる。プロジェクト初期(リソース数が10以下の段階)に5つの判断を揃える工数は、半日から1日程度だ。それが後工程で顕在化したときの手戻りコストは、数日から数週間になることがある。初期の判断コストが低く、先送りのコストが高い——この非対称性を意識することが、Terraform設計の出発点になる。

チームの判断軸を揃える効果

5つの判断を文書化して共有しておくと、新しいメンバーが加わった際の意思統一が早い。「なぜこのリポジトリはworkspaceではなくディレクトリ分離なのか」「なぜこのリソースはimportせず除外しているのか」——こうした「なぜ」の答えがないチームでは、担当者が変わるたびに同じ議論が繰り返される。5つの判断とその理由を残しておくことは、チームの暗黙知をコードに隣接する形で明示化することでもある。コードが読めても設計の意図が読めなければ、変更のたびに同じ地雷を踏む可能性が残る。

構築開始前の設計判断チェックリスト

プロジェクト開始時に確認すべき判断事項を以下に整理する。最初のPRに添付するか、READMEに記載しておくと、後続の判断ブレを防げる。

  • モジュール分割の単位: ライフサイクルと変更頻度を軸に境界を定義したか
  • 環境分離の方式: workspace/ディレクトリのどちらを採用し、その理由を記録したか
  • 変数外出しの境界: 機密情報とそれ以外の格納先(tfvars/SSM/Vault)を明確に分けたか
  • 破壊的変更の防止: prevent_destroy設定対象リソースを定義し、CI/CDのplan差分チェックを組み込んだか
  • 手動リソースの扱い: import対象・除外対象・作り直し対象を分類して記録したか
  • stateの保管場所とlockの仕組みを確定したか(S3+DynamoDBなど)
  • apply権限を持つロールとCI/CDのIAM設計を確定したか

この7項目を構築開始前に埋めておくと、後続のコードレビューや運用引き継ぎで迷う場面が大幅に減る。各項目の「判断の理由」を一行でも記しておくことが実際の価値を生む。手を動かして実装に進む前に、設計の判断を揃えておく習慣が、本番Terraformの品質を決定づける。

▶ 手を動かして本番まで到達する

設計の型は掴めても、本番でTerraformを通しきる経験は別物です

ここまでの設計判断は、読めば腹に落ちます。ですが「自分の手で本番まで通しきる自信」は、それとは別の話になります。

2日間の集中ハンズオンで、AWS上にIaCで構築しきる経験を持ち帰れます。設計判断を、動くコードと本番環境の手応えに変える場です。

Terraformを本番まで通す2日間ハンズオンへ →

Terraformマスターセミナー|2日間ハンズオンでAWS上にIaCで本番構築

コメントする