チェックポイント
Working with Backends
/ 100
Terraform の状態の管理
このラボは Google のパートナーである Hashicorp と共同開発されました。アカウント プロフィールでサービスの最新情報、お知らせ、特典の受け取りをご希望になった場合、お客様の個人情報が本ラボのスポンサーである Hashicorp と共有される場合があります。
GSP752
概要
Terraform では、マネージド インフラストラクチャと構成に関する「状態」を保存する必要があります。Terraform はこの状態を使用して、実際のリソースを構成にマッピングしたり、メタデータをトラッキングしたり、大規模インフラストラクチャのパフォーマンスを改善したりします。
この状態は、デフォルトでは terraform.tfstate
というローカル ファイルに保存されます。チーム環境にとって便利なリモートで保存することもできます。
Terraform は、このローカルの状態を使用してプランを作成し、インフラストラクチャに変更を加えます。オペレーションを実行する前に、Terraform は更新を行い、実際のインフラストラクチャによって状態をアップデートします。
Terraform の状態の主な用途は、リモート システム内のオブジェクトと構成で宣言されているリソース インスタンスとの間のバインディングを保存することです。Terraform は構成の変更に応じてリモート オブジェクトを作成する際に、そのリモート オブジェクトを特定のリソース インスタンスに対して同定する情報を記録します。その後、構成の変更に応じて適宜オブジェクトの更新や削除を行います。
目標
このラボでは、次のタスクを行う方法を学びます。
- ローカル バックエンドを作成する。
- Cloud Storage バックエンドを作成する。
- Terraform の状態を更新する。
- Terraform 構成をインポートする。
- Terraform でインポートした構成を管理する。
設定と要件
[ラボを開始] ボタンをクリックする前に
こちらの手順をお読みください。ラボの時間は記録されており、一時停止することはできません。[ラボを開始] をクリックするとスタートするタイマーは、Google Cloud のリソースを利用できる時間を示しています。
このハンズオンラボでは、シミュレーションやデモ環境ではなく、実際のクラウド環境を使ってご自身でラボのアクティビティを行うことができます。そのため、ラボの受講中に Google Cloud にログインおよびアクセスするための、新しい一時的な認証情報が提供されます。
このラボを完了するためには、下記が必要です。
- 標準的なインターネット ブラウザ(Chrome を推奨)
- ラボを完了するために十分な時間を確保してください。ラボをいったん開始すると一時停止することはできません。
ラボを開始して Google Cloud コンソールにログインする方法
-
[ラボを開始] ボタンをクリックします。ラボの料金をお支払いいただく必要がある場合は、表示されるポップアップでお支払い方法を選択してください。 左側の [ラボの詳細] パネルには、以下が表示されます。
- [Google Cloud コンソールを開く] ボタン
- 残り時間
- このラボで使用する必要がある一時的な認証情報
- このラボを行うために必要なその他の情報(ある場合)
-
[Google Cloud コンソールを開く] をクリックします(Chrome ブラウザを使用している場合は、右クリックして [シークレット ウィンドウでリンクを開く] を選択します)。
ラボでリソースが起動し、別のタブで [ログイン] ページが表示されます。
ヒント: タブをそれぞれ別のウィンドウで開き、並べて表示しておきましょう。
注: [アカウントの選択] ダイアログが表示されたら、[別のアカウントを使用] をクリックします。 -
必要に応じて、下のユーザー名をコピーして、[ログイン] ダイアログに貼り付けます。
{{{user_0.username | "Username"}}} [ラボの詳細] パネルでも [ユーザー名] を確認できます。
-
[次へ] をクリックします。
-
以下のパスワードをコピーして、[ようこそ] ダイアログに貼り付けます。
{{{user_0.password | "Password"}}} [ラボの詳細] パネルでも [パスワード] を確認できます。
-
[次へ] をクリックします。
重要: ラボで提供された認証情報を使用する必要があります。Google Cloud アカウントの認証情報は使用しないでください。 注: このラボでご自身の Google Cloud アカウントを使用すると、追加料金が発生する場合があります。 -
その後次のように進みます。
- 利用規約に同意してください。
- 一時的なアカウントなので、復元オプションや 2 要素認証プロセスは設定しないでください。
- 無料トライアルには登録しないでください。
その後、このタブで Google Cloud コンソールが開きます。
Cloud Shell をアクティブにする
Cloud Shell は、開発ツールと一緒に読み込まれる仮想マシンです。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働します。Cloud Shell を使用すると、コマンドラインで Google Cloud リソースにアクセスできます。
- Google Cloud コンソールの上部にある「Cloud Shell をアクティブにする」アイコン をクリックします。
接続した時点で認証が完了しており、プロジェクトに各自の PROJECT_ID が設定されます。出力には、このセッションの PROJECT_ID を宣言する次の行が含まれています。
gcloud
は Google Cloud のコマンドライン ツールです。このツールは、Cloud Shell にプリインストールされており、タブ補完がサポートされています。
- (省略可)次のコマンドを使用すると、有効なアカウント名を一覧表示できます。
-
[承認] をクリックします。
-
出力は次のようになります。
出力:
- (省略可)次のコマンドを使用すると、プロジェクト ID を一覧表示できます。
出力:
出力例:
gcloud
ドキュメントの全文については、gcloud CLI の概要ガイドをご覧ください。
Terraform の状態の用途
状態は Terraform が機能するための必須要件です。ユーザーからは「Terraform は状態なしでも機能するのか」といった質問や、「状態を使用せずに実行のたびにクラウド リソースを検査する形でも機能するのか」といった質問を受けることがあります。状態を使用しなくても Terraform が機能するシナリオはありますが、状態を使用しないと、ある場所(状態)から別の場所(代替の概念)に複雑な内容を大量に移行しなければならなくなります。このセクションでは、Terraform の状態が必要な理由を説明します。
実世界へのマッピング
Terraform では、Terraform の構成を実世界にマッピングするためになんらかのデータベースが必要です。構成に resource "google_compute_instance" "foo"
が含まれている場合は、そのリソースによって i-abcd1234
インスタンスが表現されていることを認識するためにマッピングが使用されます。
Terraform は、各リモート オブジェクトが 1 つのリソース インスタンスのみにバインドされると想定します。Terraform はオブジェクトを作成し、それらのオブジェクトを同定する情報を状態に記録するようになっているので、この想定は通常保証されます。Terraform 外で作成されたオブジェクトをインポートする場合は、それぞれのオブジェクトが 1 つのリソース インスタンスに対してのみインポートされていることを確認する必要があります。
1 つのリモート オブジェクトが 2 つ以上のリソース インスタンスにバインドされていると、そういったオブジェクトに対して Terraform が想定外の振る舞いをする場合があります。これは、構成からリモート オブジェクトの状態へのマッピングが不明瞭になるためです。
メタデータ
Terraform は、リソースとリモート オブジェクト間のマッピングをトラッキングするだけでなく、リソースの依存関係などのメタデータもトラッキングする必要があります。
Terraform では通常、構成を基に依存順序を判断します。ただし、Terraform 構成からリソースを削除する際は、そのリソースの削除方法を Terraform が認識している必要があります。構成ファイル内に存在しないリソースのマッピングがあると、Terraform が識別し、破棄を計画します。ただし、リソースはすでに存在しないため、構成だけから順序を判断することはできません。
オペレーションを適切に実行するため、Terraform は最新の依存関係セットのコピーを状態内に保持しておきます。これにより、Terraform は構成から 1 つ以上の項目を削除する際に、状態から破棄の正しい順序を判断できます。
上記のプロセスは、Terraform がリソースタイプ間の必須の順序を認識している場合には回避できます。たとえば Terraform は、サブネットを削除する前に、それらのサブネットに属するサーバーを削除しなければならないことを認識できます。しかし、この手法では複雑さが増してすぐに管理できなくなります。Terraform は各クラウドの各リソースの順序セマンティクスだけでなく、複数のプロバイダ全体の順序も把握する必要があります。
同様の理由で Terraform では他のメタデータも保存します。たとえば、エイリアス化されたプロバイダが複数存在する場合に、リソースによって最後に使用されたプロバイダ構成へのポインタなどです。
パフォーマンス
Terraform は基本的なマッピングのほかに、全リソースの属性値のキャッシュを状態に保存します。これは Terraform の状態のオプション機能であり、パフォーマンスの改善のみを目的としています。
Terraform は terraform plan
を実行する際、目的の構成を実現するうえで必要な変更を上手く判断するために、リソースの現在の状態を把握する必要があります。
小規模なインフラストラクチャの場合は、プロバイダに対するクエリを実行し、すべてのリソースの最新の属性を同期できます。それが Terraform のデフォルトの動作です。すべての plan
と apply
で、Terraform は状態内のすべてのリソースを同期します。
大規模なインフラストラクチャの場合は、すべてのリソースに対するクエリを実行すると時間がかかりすぎてしまいます。多くのクラウド プロバイダは、複数のリソースに対するクエリを一括実行するための API を提供しておらず、リソースあたりのラウンドトリップ時間は数百ミリ秒になります。また、クラウド プロバイダはたいてい API のレート制限を設けています。そのため、Terraform が一定期間内にリクエストできるリソースの数は限られます。この問題を回避するために、Terraform を大規模に使用するユーザーは多くの場合、-refresh=false
フラグと -target
フラグの両方を使用します。こうしたシナリオでは、キャッシュに保存された状態が信頼できる記録として扱われます。
同期
デフォルトの構成では、状態は Terraform が実行された現在の作業ディレクトリにファイルとして保存されます。最初はこの方法で問題ないでしょう。しかし、Terraform をチームで使用する場合は、オペレーションが同一のリモート オブジェクトに適用されるように、チームメンバー全員が同じ状態を使用できることが重要です。
この問題への対応策としてリモート状態をおすすめします。多機能の状態バックエンドを利用すると、複数のユーザーが誤って Terraform を同時実行するのを防ぐ手段として、Terraform でリモートロックを使用できます。これにより、Terraform の実行が毎回、更新済みの最新の状態で開始されるようになります。
状態のロック
バックエンドがロックに対応している場合、Terraform は状態を書き込む可能性があるすべてのオペレーションに対して状態をロックします。これにより、他のユーザーがロックを取得し、状態に不適切な変更を加えることを防止できます。
状態のロックは、状態を書き込む可能性があるすべてのオペレーションを対象に自動的に行われます。ロックが行われる際に特にメッセージは表示されません。状態のロックに失敗すると、Terraform は続行できなくなります。-lock
フラグを使用すると、ほとんどのコマンドで状態のロックを無効化できますが、推奨されません。
ロックの取得に想定されているよりも時間がかかると、Terraform からステータス メッセージが出力されます。Terraform からメッセージが出力されていない場合は、状態のロックが引き続き有効です。
一部のバックエンドはロックに対応していません。バックエンドがロックに対応しているかどうかの詳細については、バックエンドのタイプのリストをご覧ください。
ワークスペース
それぞれの Terraform 構成には、オペレーションの実行方法や永続データ(Terraform の状態など)の保存場所を定義するバックエンドが関連付けられています。
バックエンドに保存される永続データは、ワークスペースに属します。最初はバックエンドに default というワークスペースしかないため、構成に関連付けられる Terraform の状態は 1 つのみです。
一部のバックエンドは複数の名前付きワークスペースに対応しており、複数の状態を単一の構成に関連付けることができます。この構成のバックエンドは 1 つのみですが、新しいバックエンドを構成したり、認証情報を変更したりしなくても、この構成を使った別個のインスタンスを複数デプロイできます。
タスク 1. バックエンドの操作
状態を読み込む方法と apply
などのオペレーションを実行する方法は、Terraform のバックエンドによって決まります。この抽象化によって、ローカル ファイルを使用しない状態の保存やリモート実行などが可能になります。
デフォルトでは、Terraform は「ローカル」のバックエンドを使用します。これは、ここまで使われていた Terraform の標準の動作です。これまでのラボでは、このローカルのバックエンドを呼び出していました。
バックエンドには次のようなメリットがあります。
- チームでの作業: バックエンドを使用すると、状態をリモートに保存できることに加え、その状態をロックによって保護し、不適切な変更を防止できます。Terraform Cloud など一部のバックエンドでは、すべての状態の変更履歴を自動的に保存することもできます。
- 機密情報をディスク外に保管: 状態はバックエンドからオンデマンドで取得され、メモリにのみ保存されます。
-
リモート オペレーション: 大規模なインフラストラクチャや一部の変更では、
terraform apply
に長時間かかる場合があります。一部のバックエンドはリモート オペレーションに対応しており、リモートでオペレーションを実行できます。その場合は PC の電源を切ってもオペレーションが完了します。前述のとおり、リモート オペレーションを状態のリモート保存およびロックと組み合わせることで、チーム環境も維持できます。
バックエンドは任意: バックエンドの学習や使用をしなくても、Terraform は問題なく使うことができます。しかし、バックエンドを使用することで、ある程度の規模のチームで悩みとなる問題を解消できます。個人で作業を進める場合は、おそらくバックエンドを使用しなくても問題ないでしょう。
ローカル バックエンドの動作は変更することもできるので、ローカル バックエンドのみを使用する場合でも、バックエンドについて学んでおくと便利です。
ローカル バックエンドの追加
このセクションでは、ローカル バックエンドを構成します。
Terraform では、バックエンドを初めて構成するときに(バックエンドが定義されていない状態から明示的に構成を行うとき)、状態を新しいバックエンドに移行するオプションが提示されます。これにより、既存の状態を失わずにバックエンドを導入できます。
細心の注意を払い、必ず手動で状態をバックアップしておくことをおすすめします。手動バックアップは、terraform.tfstate
ファイルを別の場所にコピーするだけで完了します。初期化プロセスでもバックアップが作成されますが、念のため手動でも保存しておきましょう。
初めてバックエンドを構成するときも後から構成を変更するときも方法は同じです。新しい構成を作成し、terraform init
を実行します。後は Terraform が示すガイドに沿って手順を進めます。
- 新しく開いた Cloud Shell のウィンドウで、
main.tf
構成ファイルを作成します。
- 次のコマンドを実行して、プロジェクト ID を取得します。
- Cloud Shell ツールバーで [エディタを開く] をクリックします。Cloud Shell とコードエディタを切り替えるには、必要に応じて [エディタを開く] または [ターミナルを開く] をクリックするか、[新しいウィンドウで開く] をクリックして別のタブでエディタを開いたままにします。
- Cloud Storage バケットのリソースコードを
main.tf
構成ファイルにコピーし、project
とname
の変数を実際のプロジェクト ID に置き換えます。
Cloud Storage リソースについて詳しくは、Terraform のドキュメントをご覧ください。
- ローカル バックエンドを
main.tf
ファイルに追加します。
これにより、terraform/state
ディレクトリの terraform.tfstate
ファイルが参照されます。別のファイルパスを指定するには、path
変数を変更します。
ローカル バックエンドでは、ローカルのファイルシステムに状態を保存して、その状態をシステム API によってロックし、ローカルでオペレーションを実行します。
Terraform では、構成したバックエンドを使用前に初期化する必要があります。そのためには、terraform init
を実行します。terraform init
コマンドは、いずれかのチームメンバーが Terraform 構成に対して、最初のステップとして実行する必要があります。複数回実行して、バックエンドの初期化など、Terraform 環境に必要な設定操作をすべて行うと安全です。
init
コマンドは次の場合に呼び出す必要があります。
- バックエンドを構成する環境を新しく用意する
- バックエンド構成を変更する(バックエンドの種類の変更も含む)
- バックエンド構成を完全に削除する
これらを厳密に覚える必要はありません。初期化が必要な状況になったら、Terraform からエラー メッセージが表示されます。Terraform が初期化を自動で行うことはありません。ユーザーからの追加情報が必要な場合や、状態の移行を実行する場合などがあるからです。
- Cloud Shell ツールバーで、[ターミナルを開く]、[Terraform を初期化する] の順にクリックします。
- 変更を適用します。確認プロンプトで「yes」と入力します。
Cloud Shell エディタで terraform/state
ディレクトリに terraform.tfstate
という状態ファイルが表示されるはずです。
- 状態ファイルを確認します。
google_storage_bucket.test-bucket-for-state
リソースが表示されます。
Cloud Storage バックエンドの追加
Cloud Storage バックエンドでは、構成可能なプレフィックスで状態をオブジェクトとして Cloud Storage 上の特定のバケットに保存します。Cloud Storage バックエンドは状態のロックにも対応していて、状態を書き込む可能性があるすべてのオペレーションに対して状態をロックします。これにより、他のユーザーがロックを取得し、状態に不適切な変更を加えることを防止できます。
状態のロックは、状態を書き込む可能性があるすべてのオペレーションを対象に自動的に行われます。ロックが行われる際に特にメッセージは表示されません。状態のロックに失敗すると、Terraform は続行できなくなります。-lock
フラグを使用して、ほとんどのコマンドで状態のロックを無効化できますが、推奨されません。
-
エディタで
main.tf
ファイルに戻ります。ここで、現在のローカル バックエンドをgcs
バックエンドに置き換えます。 -
既存のローカル バックエンドの構成を変更するには、次の構成をファイルにコピーし、
local
バックエンドを置き換えます。
bucket
の変数定義を更新してください。構成を変更しなかった場合は、google_storage_bucket
リソースの name
が使用されます。このバケットが状態ファイルをホストするために使用されます。
- バックエンドを再度初期化します。今回は状態を自動的に移行することが目的です。
確認プロンプトで「yes」と入力します。
-
Cloud コンソールのナビゲーション メニューで、[Cloud Storage] > [バケット] をクリックします。
-
バケットをクリックし、
terraform/state/default.tfstate
ファイルにアクセスします。状態ファイルは Cloud Storage バケット内にあります。
状態の更新
terraform refresh
コマンドは、Terraform が状態ファイルを通じて認識している状態と実際のインフラストラクチャとを整合させるために使用します。これにより、最後に認識された状態からのずれを検出し、状態ファイルを更新できます。
インフラストラクチャではなく、状態ファイルを修正するコマンドです。状態が変更されると、次の plan や apply の最中に変更が行われる場合があります。
-
Cloud コンソールで Storage バケットに戻ります。名前の横にあるチェックボックスをオンにします。
-
[ラベル] タブをクリックします。
-
[ラベルを追加] をクリックします。[鍵 1] を [
key
]、[値 1] を [value
] に設定します。 -
[保存] をクリックします。
-
Cloud Shell に戻り、次のコマンドを使用して状態ファイルを更新します。
- 更新を確認します。
構成のラベル属性に Key-Value ペア "key" = "value"
が表示されます。
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
ワークスペースのクリーンアップ
次のタスクに移る前に、プロビジョニング済みのインフラストラクチャを破棄します。
- まず、バックエンドを
local
に戻し、Storage バケットを削除できるようにします。gcs
構成をコピーし、次に置き換えます。
-
local
バックエンドを再初期化します。
確認プロンプトで「yes」と入力します。
-
main.tf
ファイルで、force_destroy = true
引数をgoogle_storage_bucket
リソースに追加します。このブール値のオプションを使用することで、バケットを削除するときに含まれているすべてのオブジェクトが削除されます。オブジェクトが含まれているバケットを削除しようとすると、Terraform による実行が失敗します。リソースの構成は次のようになります。
- 変更を適用します。
確認プロンプトで「yes
」と入力します。
- これでインフラストラクチャを正常に破棄できるようになりました。
確認プロンプトで「yes」と入力します。
タスク 2. Terraform 構成のインポート
このセクションでは、既存の Docker コンテナとイメージを空の Terraform ワークスペースにインポートします。これにより、実際のインフラストラクチャを Terraform にインポートする際の戦略や考慮事項を学ぶことができます。
Terraform のデフォルトのワークフローでは、インフラストラクチャの作成と管理はすべて Terraform によって行われます。
-
作成するインフラストラクチャを定義する Terraform 構成を記述します。
-
Terraform プランを確認し、構成から想定どおりの状態とインフラストラクチャが実現することを確かめます。
-
構成を適用し、Terraform の状態とインフラストラクチャを作成します。
Terraform でインフラストラクチャを作成した後は、構成を更新して、変更に対し plan と apply を実行できます。その後、インフラストラクチャが不要になったら、Terraform を使用してインフラストラクチャを破棄します。このワークフローは、Terraform が完全に新しいインフラストラクチャを作成することを前提としています。
しかし場合によっては、Terraform 以外で作成されたインフラストラクチャを管理する必要があります。この問題は、terraform import コマンドを使用して、サポート対象のリソースを自分の Terraform ワークスペースの状態に読み込むことで対処できます。
ただし、import コマンドでは、インフラストラクチャを管理するための構成が自動的に生成されません。そのため、既存のインフラストラクチャを Terraform にインポートするプロセスは、複数のステップで構成されます。
既存のインフラストラクチャを Terraform の管理下に置く作業には、次の 5 つの主要なステップがあります。
- インポートする既存のインフラストラクチャを特定する。
- インフラストラクチャを Terraform の状態にインポートする。
- そのインフラストラクチャに一致する Terraform 構成を記述する。
- Terraform プランを確認し、構成が想定どおりの状態とインフラストラクチャに一致していることを確かめる。
- 構成を適用し、Terraform の状態を更新する。
このセクションでは、まず Docker CLI を使用して Docker コンテナを作成します。次に、そのコンテナを新しい Terraform ワークスペースにインポートします。続いて、Terraform を使用してコンテナの構成を更新します。作業完了後、このコンテナは最終的に破棄します。
terraform.tfstate
ファイルと .terraform
ディレクトリのバックアップを作成して、安全に保存しておいてください。
Docker コンテナの作成
- Docker Hub の最新の NGINX イメージを使用して
hashicorp-learn
という名前のコンテナを作成し、Cloud Shell の仮想マシン上で、ポート 80(HTTP)経由でコンテナをプレビューします。
- コンテナが実行されていることを確認します。
- Cloud Shell のペインで、[ウェブでプレビュー]、[ポート 8080 でプレビュー] の順にクリックします。
プロキシ サービスのプレビュー用 URL が新しいブラウザ ウィンドウで開き、NGINX のデフォルトのインデックス ページが表示されます。これで、ワークスペースにインポートして Terraform で管理する Docker イメージとコンテナを準備できました。
Terraform へのコンテナのインポート
- サンプル リポジトリのクローンを作成します。
- そのディレクトリに移動します。
このディレクトリには、本ガイドの構成を実現する 2 つの Terraform 構成ファイルが含まれています。
-
main.tf
ファイルでは Docker プロバイダを構成します。 -
docker.tf
ファイルには、前のステップで作成した Docker コンテナを管理するために必要な構成が含まれます。
- Terraform ワークスペースを初期化します。
terraform init -upgrade
を実行してください。
-
Cloud Shell エディタで
learn-terraform-import/main.tf
にアクセスします。 -
provider: docker
リソースを見つけて、host
引数をコメントアウトまたは削除します。
-
次に、
learn-terraform-import/docker.tf
にアクセスします。 -
コメントアウトされたコードの下で、
docker.tf
ファイルの空のdocker_container
リソースを定義します。このリソースは、Terraform リソース IDdocker_container.web
で Docker コンテナを表します。
- インポートするコンテナの名前を見つけます。この例では、前のステップで作成したコンテナになります。
- 次の
terraform import
コマンドを実行して、作成したばかりのdocker_container.web
リソースに既存の Docker コンテナを関連付けます。terraform import では、この Terraform リソース ID と完全な Docker コンテナ ID が必要です。docker inspect -f {{.ID}} hashicorp-learn
コマンドを実行すると、完全な SHA256 コンテナ ID が返されます。
terraform import
で受け入れられる ID はリソースのタイプによって異なり、Terraform にインポートできるリソースごとにプロバイダのドキュメントに記載されています。この例では、Docker プロバイダのドキュメントを参照します。
- Terraform の状態にコンテナがインポートされていることを確認します。
この状態には、インポートした Docker コンテナについて Terraform が認識している情報がすべて含まれています。ただし、terraform import ではリソースの構成は作成されません。
構成の作成
Terraform を使用してこのコンテナを管理するには、Terraform 構成を作成しておく必要があります。
- 次のコードを実行します。
image
と name
が抜けていることを示すエラーが Terraform によって表示されます。Terraform は必須の引数が抜けているリソースのプランを生成できません。
インポートした状態に合わせて docker.tf
の構成を更新する方法は 2 つあります。リソースの現在の状態全体をそのまま構成にインポートする方法か、必要な属性を個別に選択して構成にインポートする方法です。これらの方法は有効な状況がそれぞれ異なります。
-
多くの場合、現在の状態を使用する方が手早く済みますが、構成が過度に細かくなる可能性があります。構成に含める必要があるかどうかにかかわらず、すべての属性が状態に含まれるためです。
-
必要な属性を個別に選択する方法では、構成を管理しやすくなりますが、構成でどの属性を設定する必要があるのかを把握する必要が生じます。
このラボでは、現在の状態をリソースとして使用します。
- Terraform の状態を
docker.tf
ファイルにコピーします。
>
記号は、docker.tf のすべての内容を terraform show
コマンドの出力に置き換えます。この例では問題ありませんが、すでにリソースを管理している構成にリソースをインポートするためには、terraform show
の出力を編集し、構成の完全な置き換えが望ましくない既存のリソースを削除して、新しいリソースを既存の構成に統合する必要があります。
-
docker.tf
ファイルを検査して、実行した terraform show コマンドの出力によって内容が置き換えられていることを確認します。 -
次のコードを実行します。
Terraform に、非推奨の引数(「links」)と一部の読み取り専用の引数(ip_address
、network_data
、gateway
、ip_prefix_length
、id
)に関する警告やエラーが表示されます。
これらの読み取り専用の引数は、Terraform が Docker コンテナの状態に保存する値ですが、Docker によって内部で管理されるため、構成で設定することはできません。Terraform では、構成を使用して links 引数を設定できますが、その場合でも警告は表示されます。links 引数は非推奨であり、Docker プロバイダの今後のバージョンではサポートされない可能性があるためです。
ここで説明する方法では、Terraform の状態で表現されている属性をすべて読み込むため、値がデフォルトと同一であるオプションの属性も構成に含まれます。オプションの属性とそのデフォルト値はプロバイダによって異なり、プロバイダのドキュメントにまとめられています。
- こうしたオプションの属性を選択して削除できます。オプションの属性をすべて削除し、必須属性(
image
、name
、ports
)のみを残します。これらのオプションの属性を削除すると、構成は次のようになります。
実際のインフラストラクチャをインポートする際は、プロバイダのドキュメントで各引数の役割を確認してください。そうすることで、plan 実行時のエラーや警告に対処する方法を見極められます。たとえば、links
引数に関するドキュメントは、Docker プロバイダのドキュメントにあります。
- エラーが解決されていることを確認します。
plan は正常に実行されるはずです。Terraform によってコンテナが更新され、attach
、logs
、must_run
、start
の各属性が追加されることを plan は示しています。
Terraform はこれらの属性を使用して Docker コンテナを作成しますが、Docker はこれらの属性を保存しません。そのため、terraform import
では値が状態に読み込まれていません。構成に対し plan と apply を実行するとき、Docker プロバイダがこれらの属性のデフォルト値を割り当てて状態に保存しますが、実行されるコンテナに影響はありません。
- 変更を適用して、更新された Terraform の構成と状態を、それを反映させる Docker コンテナと同期させるプロセスを完了します。確認プロンプトで「yes」と入力します。
以上で、構成ファイル、Terraform の状態、コンテナがすべて同期され、Terraform を使用して通常どおり Terraform コンテナを管理できるようになりました。
イメージ リソースの作成
場合によっては、terraform import
コマンドを使用しなくてもリソースを Terraform の管理下に置くことができます。Docker イメージなど、1 つの一意の ID やタグで定義されるリソースは、これに該当する場合が多くあります。
docker.tf
ファイルの docker_container.web
リソースは、コンテナの作成に使用されるイメージの SHA256 ハッシュ ID を指定します。Docker はこの方法でイメージ ID を内部で保存するため、terraform import
を実行するとイメージ ID が状態に直接読み込まれます。ただし、イメージ ID はイメージのタグや名前ほど人間が読みやすい形式にはなっておらず、意図に合っていない場合もあります。たとえば、「nginx」イメージの最新バージョンを使用したいとします。
- イメージのタグ名を取得するには、
<IMAGE-ID>
をdocker.tf
のイメージ ID に置き換えて次のコマンドを実行します。
- 次の構成を
docker.tf
ファイルに追加し、このイメージをリソースとして表現します。
docker_container.web
リソースのイメージの値はまだ置き換えないでください。この値を置き換えると、コンテナが破棄、再作成されます。Terraform は docker_image.nginx
リソースをまだ状態に読み込んでいないため、ハードコードされた ID と照合するイメージ ID がありません。このため、Terraform はコンテナを置き換える必要があると判断します。この状況に対処するには、今回のラボの説明どおりに先にイメージを作成したうえで、そのイメージを使用するようコンテナを更新します。
- 状態にイメージ リソースを作成します。
イメージのリソースが作成されたら、コンテナの構成内で参照できます。
-
docker_container.web
のイメージの値を変更し、新しいイメージ リソースを参照します。
- 変更内容を確認します。
docker_image.nginx.latest
は置き換えたハードコード済みのイメージ ID に一致するため、この時点で terraform apply
を実行しても変更内容は表示されません。
Terraform によるコンテナの管理
Terraform で Docker コンテナを管理するように構成したら、Terraform を使用して構成を変更します。
-
docker.tf
ファイルで、コンテナの外部ポートを8080
から8081
に変更します。
- 変更を適用します。
確認プロンプトで「yes
」と入力します。
これにより、コンテナが破棄され、新しいポート構成で再作成されます。
- コンテナが新しい構成のものに置き換えられていることを確認します。
コンテナ ID が変わっていることに注目してください。ポート構成を変更するには、いったん破棄して再作成する必要があるので、これは完全に新しいコンテナになります。
インフラストラクチャの破棄
Docker コンテナと、それを作成するためのイメージを Terraform にインポートしました。
- コンテナとイメージを破棄します。
確認プロンプトで「yes
」と入力します。
- コンテナが破棄されたことを確認します。
制限事項とその他の考慮事項
リソースを Terraform にインポートする際は、いくつか重要なポイントがあります。
terraform import で認識できるのは、Terraform プロバイダから報告されるインフラストラクチャの現在の状態のみです。次の点は認識されません。
- インフラストラクチャが適切に動作しているかどうか
- インフラストラクチャの意図
- インフラストラクチャに対して適用された変更のうち、Terraform によって管理されていないもの(Docker コンテナのファイルシステムの状態など)
インポートにはエラーが起こりやすい手動作業が含まれます。特にリソースをインポートする担当者が、対象のリソースが作成された本来の経緯や理由を理解していないと、エラーが起こりやすくなります。
インポートでは Terraform の状態ファイルに操作を加えます。そのため、新しいインフラストラクチャをインポートする前にバックアップを作成しておくことをおすすめします。
terraform import では、インフラストラクチャ間の関係性は検出、生成されません。
Terraform は、構成で設定する必要がないデフォルトの属性は検出しません。
一部のプロバイダやリソースは terraform import に対応していません。
インフラストラクチャを Terraform にインポートしても、Terraform で破棄、再作成できることにはなりません。たとえば、インポートされたインフラストラクチャが、他の非マネージドのインフラストラクチャや構成に依存している場合があります。
Immutable Infrastructure(不変のインフラストラクチャ)など、Infrastructure as Code(IaC)のベスト プラクティスに従うと、こうした問題の多くは防止できますが、手動で作成されたインフラストラクチャは、IaC のベスト プラクティスに即していない傾向があります。
Terraformer などのツールを利用すると、インフラストラクチャのインポートに伴う一部の手動作業を自動化できます。ただし、こうしたツールは、Terraform そのものに組み込まれているわけではなく、HashiCorp が推奨、支援しているものでもありません。
お疲れさまでした
このラボでは、Terraform を使用してバックエンドや状態を管理する方法を学びました。状態ファイルを管理するためのローカル バックエンドと Cloud Storage バックエンドを作成して、状態を更新し、Terraform に構成をインポートしました。その後、構成を更新し、手動で編集することで Terraform で Docker コンテナを完全に管理できるようにしました。
次のステップと詳細情報
次のリンクから、Terraform に関するその他の実践演習を受講できます。
- Google Cloud Marketplace の Hashicorp
- Hashicorp Learn
- Terraform コミュニティ
- Terraform の Google の例
Google Cloud トレーニングと認定資格
Google Cloud トレーニングと認定資格を通して、Google Cloud 技術を最大限に活用できるようになります。必要な技術スキルとベスト プラクティスについて取り扱うクラスでは、学習を継続的に進めることができます。トレーニングは基礎レベルから上級レベルまであり、オンデマンド、ライブ、バーチャル参加など、多忙なスケジュールにも対応できるオプションが用意されています。認定資格を取得することで、Google Cloud テクノロジーに関するスキルと知識を証明できます。
マニュアルの最終更新日: 2024 年 1 月 26 日
ラボの最終テスト日: 2023 年 12 月 11 日
Copyright 2024 Google LLC All rights reserved. Google および Google のロゴは Google LLC の商標です。その他すべての企業名および商品名はそれぞれ各社の商標または登録商標です。