対象を限定した計画でプレビューを復元する

DockerIntermediate
オンラインで実践に進む

はじめに

TIDE は 2 つのアーティストのスタジオを 1 日だけ一般公開します。サイトには日程、道案内、ダウンロード用ガイドがあります。City の公開サイトと Riverside の参照用プレビューは動作していますが、Courtyard のプレビューコンテナーが失われました。隣接サイトや共有ネットワークを置き換えずに、この会場を復元してください。

基本的なターミナル操作と、Docker のイメージ、コンテナー、公開ポートの利用経験が必要です。Terraform はここで学びます。HCL 設定、provider、リソース、データソース、計画、状態を順に扱います。ツールと完成済みサイトイメージは用意されています。1 台の学習用インスタンスでローカル Docker を管理し、クラウドアカウントやアプリの実装は不要です。

Live Studios、Reference Preview、Venue Preview、Workstation を使います。Venue Preview は復元するまで利用できません。この環境は独立して初期化されます。Terraform 1.14.3 とコミュニティー製 kreuzwerker/docker provider 3.0.2 に固定しています。ローカルの provider ミラーにより、学習時の初期化は公開レジストリに依存しません。

プレビューとその所有境界を宣言する

このステップでは、正常な訪問者の操作を体験してから、失われた会場コンテナーだけを宣言します。Live Studios から始めます。ホームには LIVE PROGRAMME / City と表示されます。Meet the two studios を選び、Form & Field と Small Editions の内容を読んでから Find directions and the programme を選びます。Download the day programme でダウンロードしたテキストを開き、City と両スタジオの日程を確認します。Do I need to book? を展開すると、無料で予約不要と分かります。

Reference Preview に切り替えます。同じ操作では REFERENCE PREVIEW / Riverside と表示されます。このコンテナーは現在の Terraform 設定に属し、引き続き必要なので維持してください。Venue Preview はコンテナーがないため接続できません。サーバーが存在しない状態は HTTP 404 と異なります。404 は、動作しているサーバーが特定のページを見つけられない場合の応答です。

ルートと状態を読む

Workstation に切り替えます。Terraform のルートは、その中の .tf ファイルをまとめて評価するディレクトリです。別のディレクトリで実行すると別のルートが選ばれ、隣接ディレクトリが自動検索されることはありません。pwd で現在のパスを表示します。

pwd
/home/labex/project/preview/courtyard

ls はファイル一覧、cat はテキストファイルを表示します。用意された設定を読みます。

ls
cat main.tf

.tf ファイルは設定言語 HCL を使います。波括弧のブロックで設定をまとめ、name = value で値を割り当てます。引用符付きの文字は文字列、ポート番号は引用符なしの数値です。terraform ブロックは本体と必要な provider を固定します。provider は Terraform の操作を Docker API リクエストへ変換するプラグインです。provider "docker" {} はこのインスタンスの Docker daemon を使い、パブリッククラウドには接続しません。

2 つの data "docker_network" ブロックは既存ネットワークを読みます。データソースはオブジェクトを検索しますが、その作成や削除を所有しません。city と venue は参照用のローカルラベルです。ネットワーク名は実際の Docker オブジェクトを識別します。イメージのデータソースも準備済みイメージの ID を読みます。実際の ID を使うことで、タグと解決済み ID を繰り返し別イメージと見なす問題を避けます。

cat reference.tf

リソースはこのルートが管理するオブジェクトを宣言します。docker_container.reference はリソース型とローカルラベルを組み合わせた Terraform アドレスです。Docker 名は tide-reference です。コンテナー内部のポート 80 をインスタンスの 8083 として公開します。data.docker_image.reference.id はイメージデータソースの id 属性を読む式なので、引用符で囲みません。

main.tf と reference.tf は変更しません。両ネットワーク、すべてのイメージ情報、公開コンテナーは、このルートが管理する所有範囲の外にあります。このルートが管理するのは参照と失われたプレビューの 2 コンテナーです。

状態は Terraform アドレスと実オブジェクトの ID を対応付けます。用意された terraform.tfstate は、失われたものを含む両コンテナーを記憶しています。状態は設定でもサイトのバックアップでもありません。編集や削除はしないでください。後の計画は記憶した ID だけを信じず、Docker に実在するものを問い合わせます。

失われたリソースの宣言を書く

preview.tf を作ります。Terraform は同じルートのほかの .tf と一緒に処理し、ファイル名自体は別環境を作りません。cat > preview.tf はこのファイルだけを置き換えます。引用した HCL は here-document の開始です。最後の単独行の HCL までブロック全体を貼り付けます。引用符により内容がそのまま保たれます。

cat > preview.tf <<'HCL'
resource "docker_container" "preview" {
  name  = "tide-preview"
  image = data.docker_image.site.id
  ports {
    internal = 80
    external = 8082
  }
  networks_advanced {
    name = data.docker_network.venue.name
  }
}
HCL

これは完全な Courtyard イメージから 1 つのコンテナーを宣言します。入れ子の ports は HTTP を公開し、networks_advanced は既存の会場ネットワークへ接続します。公開サイトは 8081、参照は 8083 を使うため、8082 なら衝突しません。ネットワークへの参照は、そのネットワークを管理対象リソースに変えません。

このルートを初期化します。init は provider プラグインを準備し、インフラは作成しません。

terraform init

Terraform has been successfully initialized! が表示されます。ローカルミラーが 3.0.2 を供給します。.terraform は初期化した provider、.terraform.lock.hcl は選択した provider とチェックサムを保存します。ロックファイルは設定と一緒に保持します。terraform state list で記憶したアドレスを表示します。

terraform state list

出力には docker_container.preview、docker_container.reference、イメージとネットワークのデータソースが含まれます。プレビューのアドレスが一覧にあるだけでは、コンテナーの実在は証明できません。

fmt は HCL の空白を整え、validate は構文と provider 引数の型を確認します。どちらもサイトの稼働を証明するものではありません。

terraform fmt
terraform validate

Success! The configuration is valid. が表示されます。構文エラーならファイル名と行を読み、preview.tf を上の完全なブロックと比較して修正し、fmt と validate を再実行します。エラーを消すために状態を削除したり共有設定を書き直したりしないでください。これで参照を変えずに対象を再作成できる宣言ができました。

正確な復元計画を確認して適用する

このステップでは、記憶した状態と実インフラを区別し、Courtyard の訪問者向け機能全体を復元して、ほかが変わらないことを確認します。同じルートの Workstation から始めます。

変更前に計画を見る

terraform plan は Docker を読んで情報を更新し、現実と宣言を比較して変更を提案します。-out=recovery.tfplan は提案をバイナリ計画ファイルに保存し、apply が確認済みの計画を実行できるようにします。保存計画には機密設定が含まれる場合がありますが、この演習には認証情報はありません。プロジェクト内に置きます。

terraform plan -out=recovery.tfplan

記憶しているプレビュー ID の更新に続き、次を探します。

## docker_container.preview will be created
...
Plan: 1 to add, 0 to change, 0 to destroy.

+ は作成です。~ はその場の更新、- は破棄、-/+ は置き換えを示します。失われたプレビューには 1 回の作成だけが必要です。参照には変更が提案されてはいけません。ネットワークも作成、置き換え、破棄されてはいけません。既存の共有データソースであり、このルートの所有リソースではないからです。

破棄、置き換え、別リソースがあれば apply 前に止めます。pwd、preview.tf、reference.tf の誤編集を確認します。提供例を使って自分の誤編集だけを直し、新しい計画を作ります。ネットワーク名の誤りは network not found になることがあります。代わりの共有ネットワークを作らず、既存の data ブロックと照合します。名前の接頭辞でコンテナーを削除したり、復元の近道として terraform destroy を使ったりしないでください。

確認済み計画を実行する

terraform apply recovery.tfplan は保存済みの変更を実行します。計画ファイル名なしの apply と違って、再度 yes を求めません。保存したこと自体は実行承認ではないので、このコマンドの前に確認します。

terraform apply recovery.tfplan
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

計画が古いというエラーなら、計画後の別操作で状態が変わっています。新しい計画を作成して確認してから適用します。8082 が使用中なら、すべてのコンテナーを削除せず、競合する具体的なコンテナーを調べます。この準備済み環境では空いているはずです。外部ポートを再確認し、8081 と 8083 を維持します。

Venue Preview に切り替え、コンテナー起動後に再読み込みします。VENUE PREVIEW / Courtyard が表示されるはずです。Meet the two studios → Find directions and the programme → Download the day programme と進みます。ダウンロードを開き、Courtyard と両スタジオの実演時間を確認します。完全なページ、スタイル、イラスト、ダウンロードは提供イメージから得られ、空の Nginx 歓迎ページではありません。

Live Studios と Reference Preview に切り替えます。元の操作は両方で動作し、それぞれ City と Riverside を示す必要があります。ホームの名前が違うだけでは維持の証明になりません。基になるオブジェクトも元のままである必要があります。

収束と維持を確認する

Workstation に戻ります。2 回目の計画は、現在の宣言と Docker の実際を再観測します。

terraform plan
No changes. Your infrastructure matches the configuration.

これが収束です。必要なリソースが宣言した設定で存在しています。Terraform はコンテナーを常時監視して修復するわけではありません。後で変更が起きたら、人か自動化がもう一度この流れを実行します。この復元が戻すのは交換可能なインフラと提供サイトの内容であり、失ったユーザーデータやホスト全体ではありません。

terraform state show は 1 リソースの記録済み属性を表示します。id を実際の Docker ID と比較します。Docker の --format は項目を選び、単一引用符はテンプレートをそのまま保ちます。

terraform state show docker_container.preview
docker inspect --format '{{.Id}}' tide-preview

両者は同じ新コンテナーを示すはずです。ID は変動するので、例の ID を状態へコピーしないでください。元の隣接サイトと両既存ネットワークを変更せず読みます。

docker inspect --format '{{.Name}} {{.Id}} {{.State.StartedAt}}' tide-live tide-reference
docker network inspect --format '{{.Name}} {{.Id}}' tide-city tide-courtyard

コースでは識別情報を元の値と比較します。公開コンテナーはこのルートの外、参照はこのルート内で意図的に維持する管理対象です。どちらの境界も重要です。これで 1 つの失われたプレビューを復元し、ほかのサイトと共有インフラを維持できました。

まとめ

HCL と固定版 Docker provider を使い、失われた会場コンテナーを宣言しました。データソースによって共有ネットワークとイメージはこのルートの管理所有範囲外に保たれました。設定、状態、実 Docker オブジェクトを比較し、確認した 1 回の作成を適用し、訪問者の一連の操作を検証して、公開サイトと参照を維持しながら変更なしの計画を得ました。