Terraformで本番が旧版に|ignore_changesの罠

事前の確認では「変更は1か所だけ」と出ていたのに、作業後に別の場所まで変わっていた。そんな場面を想像すると、変更作業がこわくなりませんか。

この記事では、2026年10月1日にZennで公開されたTerraformの障害事例をもとに、何が起きたのかと、運用の現場で使える確認のしかたがわかります。結論から言うと、ignore_changesは「いまの値を守る設定」ではなく「差分として数えない設定」に近い、というのがこの事例の教訓です。

目次

Terraformで何が起きた?環境変数を消したら本番が旧版に

起きたのは、使っていない環境変数を消しただけで、本番環境が1か月半前のコードに戻ったという障害です。なお、記事によるとサービスはまだリリース前でした。

Terraform(テラフォーム)とは、サーバーやネットワークの構成をコードで書いて管理する道具です。terraform applyというコマンドで、コードの内容を実際の環境に反映します。

Zennの記事によると、投稿者(Google Cloud上で開発中のサービスをTerraformで管理している方)は、9月30日に使わなくなった環境変数をいくつか削除してapplyを実行しました。すると3つあるサービスのうち2つが起動に失敗し、残る1つのWebアプリは全ページが500エラーになりました。

調べると、動いていたのは8月12日にデプロイされた古いイメージでした。イメージとは、アプリを動かすためのひとまとめの部品です。本来は当日の新しいイメージが動いているはずでした。

つまり、環境変数を1つ消す作業が、アプリ本体を古い版へ戻す作業にもなっていたのです。

Terraformのignore_changesとは?「守る」ではなく「数えない」

原因は、ignore_changesという設定の意味を取りちがえやすいことにあったようです。投稿者自身も「自信を持って説明できない」と断ったうえで、調べた範囲を書いています。

ignore_changesは、指定した項目を「更新を計画するときには無視する」設定です(Terraform公式ドキュメント)。記事の環境では、イメージの更新はGitHub Actionsによる別のデプロイのしくみが担当していました。そこで、イメージの項目をignore_changesに入れていたのです。

ここで大事なのがstate(ステート)です。stateとは、Terraformが「前回こう作った」と記録している台帳のことです。イメージを別のしくみで更新していると、台帳のイメージ欄は古いまま残ることがあります。

公式ドキュメントには、無視したときに実際に何が送られるかまでは書かれていません。投稿者は今回の挙動から、ignore_changesは「いま動いている値をそのまま残す」ではなく「食い違いを差分として扱わない」という意味のようだ、と整理しています。そのため、ほかの変更で設定を送り直すときに、台帳に残っていた古い値がいっしょに使われた、というのが投稿者の見立てです。同じ挙動の報告は、TerraformのGoogle Cloud用プロバイダーのissueにもあります。

たとえるなら、古い住所録をもとに年賀状を刷り直すようなものです。名前を1人分直しただけのつもりが、全員の住所が古いまま印刷されてしまいます。

Terraformのplanに出ない変更が、なぜ本番に届いたのか

やっかいなのは、この巻き戻りが事前の確認に出てこなかった点です。

terraform planは、applyの前に「何が変わるか」を見せるコマンドです。記事では、planに出たのは環境変数の削除だけでした。イメージは「数えない」対象なので、表示されなかったのです。

一方で、記事の環境(Google CloudのCloud Run)では、環境変数もCPUやメモリの設定も、同じtemplateというまとまりに入っています。投稿者は、環境変数を1つ変えるだけでもまとまり全体が書き換わり、イメージも一緒に送られたと理解しています。

さらに、サービスによって症状がちがいました。2つのサービスは、通信の受け口(ポート)を開く前に環境変数を確かめるつくりでした。そのため起動に失敗し、Terraformもエラーで止まりました。

しかしNext.jsのアプリは先にポートを開くため起動の確認を通ってしまい、アクセスが来てからエラーになりました。Terraformの表示は「変更完了」でした。「applyが成功した」ことは「正しく動いている」ことの証明にならない、とわかる例です。

筆者の考察:Terraformの変更作業で運用担当が確認したい3点

この事例は、Terraformを書かない運用担当にこそ関係があります。作業後の確認で拾える障害だからです。

記事の内容をもとに、planで見えるものと見えないものを筆者なりに整理しました。

確認したいこと planで見えるか かわりの確認方法
コードに書いた変更 見える planの出力を読む
ignore_changesにした項目の実際の値 見えない 作業の前後で実機の値を見くらべる
アクセスが来てから出るエラー 見えない 作業後に画面やAPIを実際にたたく
Terraformのplanに出た変更と実際に変わったものの図。コードでは環境変数を削除しただけで、planにも削除だけが表示されたが、applyではtemplateごと送り直され、実際の環境ではイメージも古い版になった
図: planに出た変更と、実際に変わったもの(筆者作成・事例はZennの記事より)

ここから、作業後の確認に入れたい項目は次の3つです。

  • 動いているイメージのタグ(版の名前)が、作業前と同じかを見る
  • 起動したかだけでなく、実際にアクセスして応答を確かめる
  • 手順書に「作業前の値をメモする」ステップを入れておく

これは「動いた」だけで安心しないという、監視の基本と同じ考え方です。くわしくはバッチ監視の4観点の記事でも扱っています。

もし作業後に異常へ気づいたら、まず止血と報告です。初動の流れはインシデント初動で新人がやる5つのことの記事を参考にしてください。確認項目を手順に組みこむ方法は、実行できる手順書LC4RIの記事が役に立ちます。

Terraformのignore_changes問題に決定打はない:3つの対策案

投稿者は、再発を防ぐ案を3つ検討していますが、どれにも弱点があると書いています。

  • applyのあとに必ずデプロイをやり直す:デプロイが終わるまでのあいだ、古いイメージが本番で動いてしまう
  • Cloud RunをTerraformの管理から外す:CPUやメモリなどの設定変更がTerraformのレビューに乗らなくなる(この案は見送り)
  • イメージのタグを変数にしてapply時に渡す:投稿者が検討中の案(未実装)。applyの失敗がデプロイの失敗に直結する

1つ目の運用ルールには、もう1つ落とし穴があります。今回は古いイメージが起動に失敗したので気づけました。しかし、メモリの量を変えるだけのような変更では古いイメージがふつうに起動するため、巻き戻りに誰も気づかないおそれがある、と投稿者は指摘しています。

投稿者は、決済をあつかうので、いつのコードで課金が動いたかわからない状態は受け入れにくいと述べています。そのうえで、どの方法が正しいというより、何を優先するかの違いだとまとめています。

なお記事では、AWSのECSでも似た報告があると触れていますが、投稿者自身は未検証としています。自分の現場で同じことが起きるかは、検証環境で確かめるのが安全です。

まとめ:Terraformのignore_changesは「数えない」だけと覚える

  • ignore_changesは値を守る設定ではなく、差分として数えない設定に近い。事例では台帳(state)の古い値が使われたとみられる
  • planに出ない変更がある。applyの成功は、正しく動いていることの証明にならない
  • 作業の前後でイメージのタグを見くらべ、実際にアクセスして確かめる手順を入れる

次の変更作業では、手順書の最初に「いま動いている版をメモする」の1行を足してみましょう。

参考リンク

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

インフラの運用・構築に10年以上携わり、AWS 認定8資格を持つ運営者です。いまは Claude Code などの AI ツールを日々の作業の自動化に使いながら、これから使う人のための教科書サイトを運営しています。

コメント

コメントする

目次