はじめに
ある晴れた日のこと。あなたはPCを立ち上げ、上司から振られた真新しい機能をデプロイすべく、軽やかに terraform apply を叩こうとしました。でも、ちょっと待って... terraform.tfstate ファイルが跡形もなく消え失せているではないですか。
それはまるで、一生分の旅行チケットを手に入れた「推し」が、冷たいコンソールの前にあなたを一人残して旅立ってしまったかのよう。さらに非情なことに、その推しは「お供」であるはずの terraform.tfvars ファイルまで道連れにして、一言の別れもなく姿を消してしまったのです。
見守り役(リモートバックエンド)すら設定していなかったため、推しが消えればすべてが水の泡。インフラエンジニアであるあなたの頭の中はパニック状態でしょう。「AWSはピンピンして動いているのに、Terraformのコードは自分たちが作ったはずのインフラを完全に忘却している」という絶望的な状況です。
tfstate と tfvars って、結局何がそんなに重要なのか?
もしこの地獄を見たことがなく、これら2つのファイルの役割がいまいちピンと来ないなら、現実世界の例で考えてみましょう。会社で新しいオフィスをセットアップするとします。
-
tfvarsは 「設計図&発注リスト」 です。黒いデスクを10脚、青いオフィスチェアを5脚買う、といった情報が書かれています。(これはインフラを定義するための入力パラメータです)。 -
tfstateは 「資産管理台帳」 です。黒いデスクの1台目がどの区画のどの部屋に置かれているか、管理用の識別番号(クラウド上のID)は何番か、といった情報を正確に記録しています。
黒いデスク10脚を白いデスクに入れ替えたい時、Terraformはこの 資産管理台帳(tfstate) を引っぱり出して該当するデスクを探し出し、それらを廃棄して新しいものを配置します。
ここで台帳(tfstate)を紛失するとどうなるでしょう?Terraformおじさんはオフィスに入ってきて... ポカーンとします。
目の前に黒いデスクが10脚あるのは見えています。でも、台帳に載っていないため「これはうちの会社の備品ではない」と頑なに認識しません。もしここで設定変更を無理やり通そう(apply)とすれば、彼は追加で新品のデスクを10脚買ってきて部屋に押し込む(インフラの重複)か、エラーを吐いてへそを曲げるかの二択になります。
「推し」を探す旅:涙なしでは語れない復旧作業
しばらく呆然とした後、ネットの海を漁って残酷な現実に気付きます。現在のインフラに一切の傷をつけず、きれいに元通りにする唯一の方法。それは、新しいStateファイルを手作業で一つ一つ import して元の状態に復元することです。
泣く泣くその現実を受け入れるしかありません。なにせ、リリース期限が背後まで迫っているのですから。
当初の計画は完璧に思えました。手作業でちまちま import を合わせ、最後に terraform plan を実行して、魔法のような緑色の文字を拝むこと:
0 changed, 0 added, 0 destroyed
要するに、「私たち、ずっと一緒にいたよね?」とTerraformを騙し切る作戦です。
ステップ 1: 炎上するスケジュール
AWSコンソールを開き、リソースの数を数えます。絶望的な数ではありません。昼夜問わずコマンドを叩き続ければ、3〜4日くらいでなんとか終わりそうです...
そこでハッと考えました。新機能のリリース期限は 「明後日」 ではありませんか。「ローカルのファイルをうっかり消しちゃったので、チーム全員の開発を止めます」なんて上司に報告したら、大炎上どころでは済みません。
半日ほどコンソール画面と睨めっこして目を酷使した結果、あなたはズル(Cheat)をすることに決めました。AIに頼み込んで、クラウドをスキャンして既存リソースを一網打尽に新Stateへ import するための自動化スクリプトを書かせたのです。
ステップ 2: tfvars という名の悪夢
しかし、この魔法の自動化プロセスがすんなり進むはずがありません。根本的な問題がありました。「推し」であるStateが家出をした際、入力パラメータである tfvars まで一緒に持ち逃げしていたのです。
設定ファイルがない以上、AWSコンソール上の静的な設定値を逆引きし、ゼロから tfvars をでっち上げるしかありません。ここが本当の地獄です。
名前が一つでもずれたり、instance_type が合っていなかったり、ちょっとしたタグが抜けているだけで、terraform plan は容赦なく画面を真っ赤に染め上げます。古いDBとサーバーを根こそぎ destroy して作り直そうとする警告の嵐。Production環境を更地にしようとするその恐ろしいメッセージを見て、DevOpsエンジニアの心臓は小一時間ほど止まりかけたことでしょう。
致命的な落とし穴: import 作業は、HCLコードと実際のクラウドリソースの間にズレ(ドリフト)を生じさせやすいです。tfvars の復元を少しでも間違えれば、次のApplyで(再作成が必須なリソースの場合)重要な本番インフラを完全に消し飛ばしてしまう危険性があります。
ステップ 3: 心臓が縮む再会
絶望して何度もノートPCを叩き割りそうになりながら、比較と変数の修正を繰り返し... ついに画面が「0 destroyed」という美しい数字を返しました。
「推し」こと tfstate と「お供」の tfvars が、ついにあなたの手元に帰ってきたのです。肩の荷が下りて、椅子に深く腰掛けながら生きててよかったと実感したことでしょう。
しかし...
マウスを操作していた手が Delete というメニューにかすった瞬間、急に嫌な汗が吹き出しました。「もしまた運の悪い日に、あるいは酔っ払っている時に、うっかりこのボタンを押してしまったら...?」
解決策 / S3 Backendという「オンラインシッター」を直ちに雇う
もう半分秒たりとも猶予はありません。あなたはすぐにコードを開き、tfstate をしっかりクラウドに縛り付けておくための「オンラインのベビーシッター」を雇いました。S3バックエンドとDynamoDBによるStateロック機能です。
terraform {
backend "s3" {
bucket = "company-tfstates-prod-bucket"
key = "core/terraform.tfstate"
region = "ap-northeast-1"
encrypt = true
dynamodb_table = "terraform-states-lock"
}
}
祈るように terraform init と apply を実行します。データが無事バケットに安全に格納されたという確認メッセージが返ってきました。これでようやく、ローカルPCにいたあなたの「推し」は何重ものロックで守られた強固な「本物(REAL)」となり、誰も簡単には消せなくなったのです。
まとめ
心停止寸前のトラブルを乗り越え、血と涙から得られた「インフラエンジニアへの痛烈な教訓」をまとめます。
- ローカルのStateを絶対に信じないこと — 「うちの会社のシステム、ずっとこれで問題なく動いてるし」という言い訳は通用しません。
-
インフラが安定稼働している ≠ システムが安全である。AWSを12層のファイアウォールでガチガチに守ろうが、個人のノートPCのCドライブに転がっている
.tfstateファイル一つで全滅します。 - ローカルに
tfstateを置くということは、「会社の最重要パスワードと全契約書をまとめて、ファンの壊れたボロPCのデスクトップに置いている」 のと本質的に同じです。- ブルースクリーンになった? → 終了。
- うっかりタイポして
rmコマンド叩いた? → 終了。 - 新規メンバーに引き継ぐ? → 「あれ、Stateファイルどこ行ったっけ?」
- 最も重要な真実:Terraformはあなたのインフラを管理しているわけではありません。当該インフラを「象徴」する Stateファイル を管理しているだけなのです!
Stateがなければ、会社が誇る巨大なサーバー群もデータベースも、Terraformから見れば見ず知らずの他人です。いざという時に泣かないためにも、今すぐクラウドにStateを設定しましょう!