このチュートリアルでは、Terraform の状態を Cloud Storage バケットに保存する方法について説明します。
デフォルトでは、Terraform はローカルの terraform.tfstate
という名前のファイルに状態を保存します。複数のユーザーが Terraform を同時に実行していて、各マシンが現在のインフラストラクチャを独自に認識している場合は、このデフォルト構成が原因でチームでの Terraform の使用が難しくなる場合があります。
このページでは、このような問題を回避するために、Cloud Storage バケットを参照するリモート状態を構成する方法について説明します。リモート状態は Terraform バックエンドの機能です。
目標
このチュートリアルでは、次の方法について説明します。
- Terraform を使用して、Terraform の状態を保存する Cloud Storage バケットをプロビジョニングする。
- Terraform 構成ファイルにテンプレートを追加して、ローカル バックエンドから Cloud Storage バケットに状態を移行する。
費用
このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
Cloud Storage では、ストレージ、読み取り / 書き込みオペレーション、下り(外向き)ネットワーク、レプリケーションで費用が発生します。
このチュートリアルの Cloud Storage バケットでは、オブジェクトのバージョニングを有効にして、デプロイの履歴を保持しています。オブジェクトのバージョニングを有効にすると、ストレージ費用が増加します。これは、古い状態のバージョンを削除するようにオブジェクトのライフサイクル管理を構成することで軽減できます。
始める前に
-
In the Google Cloud console, activate Cloud Shell.
Cloud Shell には Terraform がプリインストールされています。
ローカルシェルを使用している場合は、次の操作を行います。
- Terraform をインストールします。
-
Create local authentication credentials for your user account:
gcloud auth application-default login
If an authentication error is returned, confirm that you have configured the gcloud CLI to use Workforce Identity Federation.
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud Storage API:
gcloud services enable storage.googleapis.com
-
Grant roles to your user account. Run the following command once for each of the following IAM roles:
roles/storage.admin
gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
- Replace
PROJECT_ID
with your project ID. -
Replace
USER_IDENTIFIER
with the identifier for your user account. For examples, see Represent workforce pool users in IAM policies. - Replace
ROLE
with each individual role.
別の方法として、次の権限を含むカスタム IAM ロールを作成することもできます。
storage.buckets.create
storage.buckets.list
storage.objects.get
storage.objects.create
storage.objects.delete
storage.objects.update
バケットとバケットに保存されている状態ファイルへのアクセスを制御することをおすすめします。バケットに対する管理者権限は、少数のユーザー(メインのクラウド管理者と、代替またはバックアップ管理者として機能するユーザーなど)にのみ付与してください。それ以外のデベロッパーには、バケット内のオブジェクトへの書き込みと読み取りのみを許可する権限を付与してください。
- Replace
環境を準備する
Terraform サンプルを含む GitHub リポジトリのクローンを作成します。
git clone https://github.com/terraform-google-modules/terraform-docs-samples.git --single-branch
作業ディレクトリを変更します。
cd terraform-docs-samples/storage/remote_terraform_backend_template
Terraform ファイルを確認する
main.tf
ファイルを確認してみましょう。cat main.tf
出力は次のようになります。
このファイルでは、次のリソースを記述しています。
random_id
: Cloud Storage バケットの名前を一意にするために、Cloud Storage バケット名に追加されます。google_storage_bucket
: 状態ファイルを保存する Cloud Storage バケット。このバケットの構成では、次のプロパティが使用されています。- バケット内にオブジェクトが存在する場合にバケットが削除されないように、
force_destroy
はfalse
に設定されています。この設定により、バケット内の状態情報が誤って削除されることはありません。 - バケットの内容が誤って一般公開されないように、
public_access_prevention
はenforced
に設定されています。 - アクセス制御リストではなく IAM 権限を使用して、バケットとそのコンテンツへのアクセスを制御できるように、
uniform_bucket_level_access
はtrue
に設定されています。 - 以前のバージョンの状態がバケットに保持されるように、
versioning
は有効に設定されています。
- バケット内にオブジェクトが存在する場合にバケットが削除されないように、
local_file
: ローカル ファイル。このファイルの内容に従って、Terraform はバケット作成後に Cloud Storage バケットをリモート バックエンドとして使用します。
Cloud Storage バケットをプロビジョニングする
Terraform を初期化します。
terraform init
terraform init
を初めて実行する場合、main.tf
ファイルで指定した Cloud Storage バケットはまだ存在していません。そのため、Terraform は、状態をローカル ファイル システムに保存するために、ローカル バックエンドを初期化します。構成を適用して、
main.tf
ファイルに記述されているリソースをプロビジョニングします。terraform apply
プロンプトが表示されたら、「
yes
」と入力します。terraform apply
を初めて実行する場合、Terraform は状態を保存する Cloud Storage バケットをプロビジョニングします。また、ローカル ファイルも作成します。Terraform はこのファイルの内容に従って Cloud Storage バケットをリモート バックエンドとして使用し、状態を保存します。
状態を Cloud Storage バケットに移行する
Terraform の状態をリモートの Cloud Storage バックエンドに移行します。
terraform init -migrate-state
Terraform は状態ファイルがすでにローカルに存在することを検出し、状態を新しい Cloud Storage バケットに移行するように求めます。プロンプトが表示されたら、「
yes
」と入力します。
このコマンドを実行すると、Terraform の状態が Cloud Storage バケットに保存されます。Terraform は、コマンドを実行する前にこのバケットから最新の状態を pull し、コマンドを実行した後に最新の状態をバケットに push します。
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
プロジェクトを削除する
このページで使用したリソースに対して Google Cloud アカウントで課金されないようにするには、次の操作を行います。
main.tf
ファイルを開きます。google_storage_bucket.default
リソースで、force_destroy
の値をtrue
に更新します。更新した構成を適用します。
terraform apply
プロンプトが表示されたら、「
yes
」と入力します。状態ファイルを削除します。
rm backend.tf
バックエンドをローカルとして再構成します。
terraform init -migrate-state
プロンプトが表示されたら、「
yes
」と入力します。次のコマンドを実行して、Terraform リソースを削除します。
terraform destroy
プロンプトが表示されたら、「
yes
」と入力します。