はじめに

これまでの実験では、あなたはシェフとして、ロボット(Terraform)が調理(構築)するためのメニュー(設定)を書きました。それでは、ロボットはすでに調理したものをどのように覚えているのでしょうか。

倉庫はあるのに在庫リストをなくしてしまった状況を想像してください。何がどこにあるのか、何か盗まれていないかも分からなくなります。

Terraform では、この在庫リストを state と呼びます。state は Terraform の記憶です。Terraform が作成したリソースを記録し、設定内のオブジェクトと実際のインフラストラクチャ上のオブジェクトを対応付けます。

宣言的な管理を実用的にするのが state です。state がなければ、Terraform は設定ファイルを読み取れても、その宣言が実際のどのオブジェクトに対応するのかを確実に記憶できません。

state は Terraform の最も重要な概念の 1 つです。state がなければ、Terraform は何がすでに存在するのか、何が変更されたのか、何を更新または再作成する必要があるのかを判断できません。

この実験では、Terraform が state を使ってインフラストラクチャを正常な状態に保つ方法を確認します。あなたは「Chaos」の役割として、手動で環境を壊します。その後、Terraform が損傷を検出し、システムを自動的に「修復」する様子を見ていきます。

State を確認する

この環境はあらかじめ設定されています。main.tf ファイルが存在し、すでに terraform apply が実行されています。つまり、インフラストラクチャ(Docker コンテナ)はすでに稼働しています。

まず、コンテナが実行中であることを確認します。

sudo docker ps

tutorial という名前のコンテナが表示されます。

次に、現在のディレクトリにあるファイルを確認します。terraform.tfstate が見つかります。

ls -l

このファイルは Terraform の「秘密の日記」です。Terraform が行ったすべての操作をここに記録します。中身を確認してみましょう。

cat terraform.tfstate

出力は JSON という形式です。最初は複雑に見えるかもしれませんが、コンピューターが情報を記録するための構造化された形式にすぎません。

出力のどこかに、docker_container と実行中のコンテナの ID が表示されます。これは、Terraform がこの特定のコンテナを認識していることを示します。

重要なルール: このファイルを手動で編集してはいけません。変更すると Terraform が記憶を失い、インフラストラクチャを誤って削除したり、壊したりする可能性があります。Terraform 自身の日記は、必ず Terraform に管理させてください。

この注意が重要なのは、state が単なるログではなく、信頼できるメタデータだからです。state が壊れると、Terraform が後で破壊的な操作や分かりにくい判断を行う可能性があります。

Drift を発生させる

Terraform は、これらのリソースを自分だけで管理することを想定しています。しかし、現実の環境ではさまざまなことが起こります。サーバーがクラッシュしたり、同僚が誤って何かを手動で削除したりすることもあります。

この状態を Drift と呼びます。これは、「現実」の状態が「計画」と一致しなくなったことを意味します。

Drift は共有環境でよく発生します。人間、スクリプト、クラッシュ、外部システムなどが、Terraform の通常の管理対象外でインフラストラクチャを変更する可能性があるためです。

ここで、意図的に混乱を起こしてみましょう。Terraform に知らせず、Docker コマンドを直接使ってコンテナを削除します。

sudo docker rm -f tutorial

コンテナが本当に削除されたことを確認します。

sudo docker ps

この時点で、次の問題が発生しています。

  • 現実:コンテナは停止し、削除されています。
  • State ファイル:Terraform は、コンテナがまだ稼働していると考えています(削除されたことを Terraform に伝えていないためです)。

Drift を検出する

それでは、Terraform がこの削除を検出できるか確認しましょう。

terraform plan を実行すると、Terraform は最初に「Refresh」を行います。Docker に問い合わせ、「ID が XYZ のコンテナはまだ存在しますか」と確認します。

次のコマンドを実行します。

terraform plan

出力をよく確認してください。次のメッセージが表示されます。

docker_container.nginx: Refreshing state...

続いて、緑色の +(作成)を含む計画が表示されます。

Terraform will perform the following actions:

  ## docker_container.nginx will be created
  + resource "docker_container" "nginx" { ... }

Terraform は状況を把握しました。計画にはコンテナが存在するはずだと書かれていますが、現実には存在しません。そのため、望ましい状態に戻すには、新しいコンテナを 作成 する必要があると判断したのです。

この調整動作は、Terraform の最も重要な運用上の特性の 1 つです。Terraform は、望ましい状態、記録された state、実際に稼働している状態を比較し、必要な修正内容を判断します。

インフラストラクチャを修復する

これは Infrastructure as Code の「自己修復」機能です。コードで Desired State(実行中のコンテナ)を定義しているため、Terraform は発生した Drift を自動的に修正できます。

問題を修正するために apply を実行します。

terraform apply

プロンプトが表示されたら yes と入力します。

完了したら、Docker の状態をもう一度確認します。

sudo docker ps

コンテナが戻っています。新しい ID になっている場合や、新しく作成されたインスタンスになっている場合がありますが、機能的には、設計図で定義した状態どおりにインフラストラクチャが復元されています。

まとめ

この実験では、State の力を確認しました。

学んだことは次のとおりです。

  • State ファイル:存在するリソースに関する Terraform の記憶(terraform.tfstate)。
  • Drift の検出:手動削除のように、Terraform に知らせず変更されたことを Terraform が検出する仕組み。
  • 自己修復:terraform apply がコードに一致するよう、失われたリソースを自動的に復元する仕組み。

この信頼性があるため、Terraform は重要なインフラストラクチャの管理に利用されています。障害が発生しても、Terraform を使えば、正常だと分かっている状態へすばやく戻すことができます。