はじめに
terraform_remote_state を使うと、コード分離された別のフォルダなどで動作する Terraform の State ファイル内の Output の値を参照することができる
ここでは、Google Cloud 向けの Terraoform コードをもとに、GCS
をバックエンドストレージにしている例で試した結果を記載する
(その他対応バックエンド. AWS, Azure の例は記載されているドキュメント紹介のみ記載)
terraform_remote_state
を使用することで、prod
, dev
などで環境をフォルダで分けて同じことをするコード構成などで (フォルダ分離して中身はほぼコピペなような構成で)、
参照するバックエンド(バケット名)を変えるだけで複数の参照データを置き換えることも可能になる
(prefix
を同じくする構成であれば。コピペ時に値の置き換えミスなどが起きにくくできる)
以降に試した結果などを記載するが、公式ドキュメントがわかりやすいのでそちらを参照するでも十分理解できる内容になっている
(公式ドキュメント : gcs, s3, azurerm)
GCS Backend / Google Cloud で試す
参照先ドキュメントリンク
ここでは、プロジェクト作成時の課金アカウントを他で作成したアカウントIDと課金アカウントを値参照し、
プロジェクトが所属するフォルダを作成する際に親フォルダのIDを参照するように、
GCS をバックエンドにしているステートファイルから ID を取得する
terraform_remote_state
は output したデータのみが参照可能なので、
参照先コードに参照したいデータのoutput
を追加して外部から参照可能にする
下記コード例での実施環境などの補足 (追加前の環境説明記事)
- workspace を使用している
- ここでは
dev
を指定している
- ここでは
- project を作成するコードの追加
- project 作成コードは元になるコードは以下に projects フォルダを作成して別コードフォルダで実施している
- 追加 project の中身の内容は別記事参照
- terraform_remote_state を試すこととは直接関係なく、これを作る際にこれを試したという意味
- ここでの GCS の参照先(親フォルダなどの作成先)の
prefix
はterraform/state
(実施環境の値)
- 実施内容 : プロジェクトを作成するフォルダIDと課金IDを他のステートファイルを参照して取得する
- プロジェクト側
- data.terraform_remote_state.state.outputs.organization_service_folder_id
- data.terraform_remote_state.state.outputs.host_billing_account
- 参照先側
- output "organization_service_folder_id"
- output "host_billing_account"
- プロジェクト側
コード記載例全体 : https://github.com/suzuyu/terraform-public/releases/tag/v1.2.0
# 環境の値になる variables の定義は、ここでは記載を省略している
# ステートファイルの参照
data "terraform_remote_state" "state" {
backend = "gcs"
workspace = "dev" # workspace を使用している場合は指定する. workspace を使用してない場合は指定不要
config = {
bucket = var.terraform_state_bucket_name # 参照する GCS を指定する
prefix = "terraform/state" # 参照する Terraform が指定している prefix を記載する
}
}
# フォルダの作成で parent フォルダの参照に data.terraform_remote_state を使用
resource "google_folder" "folder" {
display_name = var.folder_name
parent = data.terraform_remote_state.state.outputs.organization_service_folder_id # 組織のサービス向けフォルダ ID を参照して、配下にフォルダを作成する
}
# プロジェクト作成で billing_account (課金アカウント) の ID を他のプロジェクトのものと同じになるように data.terraform_remote_state を使用
resource "google_project" "main" {
name = var.project_id
project_id = var.project_id
billing_account = data.terraform_remote_state.state.outputs.host_billing_account # SharedVPC の host プロジェクトの課金 ID を参照して、同じ課金アカウントを使用する
folder_id = google_folder.folder.name
}
参照先コードで output 未設定の場合は、terraform_remote_state で参照できるように output の追加をする
# 環境の値になる variables の定義は、ここでは記載を省略している
# backend
terraform {
backend "gcs" {
bucket = "YOUR_TERRAFORM_GCS_BUCKET"
prefix = "terraform/state"
}
}
# サービス向けフォルダ
resource "google_folder" "organization_service_folder" {
display_name = "service"
parent = join("/", ["organizations", var.gcp_common.org_id])
}
+ # terraform_remote_state で参照できるように output の追加
+ output "organization_service_folder_id" {
+ value = google_folder.organization_service_folder.id
+ }
# ホストプロジェクト
resource "google_project" "host_project" {
name = var.host_project_name
project_id = var_host_project_name
billing_account = var.gcp_common.billing_account
folder_id = google_folder.host_host_folder.name
depends_on = [
google_folder.host_host_folder,
]
}
+ # terraform_remote_state で参照できるように output の追加
+ output "host_billing_account" {
+ value = google_project.host_project.billing_account
+ }
AWS, Azure の場合 / ドキュメント参照先・ドキュメント先の記載コード例
AWS, Azure でも基本的に対応することは変わらないので、試すことは省略して、
下記ドキュメントリンクと、ドキュメント先記載のコード例を抜粋して紹介する
基本的には backend
で種類を指定して、config
でパラメータを指定する terraform.backend の際と同じように値を設定するだけ
S3 Backend / AWS
ドキュメントリンク (下記コード例もドキュメントから抜粋)
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "terraform-state-prod"
key = "network/terraform.tfstate"
region = "us-east-1"
}
}
Azure Storage / Azure
ドキュメントリンク (下記コード例もドキュメントから抜粋)
data "terraform_remote_state" "foo" {
backend = "azurerm"
config = {
storage_account_name = "terraform123abc"
container_name = "terraform-state"
key = "prod.terraform.tfstate"
}
}
おわりに
terraform_remote_state を試した
terraform コードをフォルダ分離して管理する場合、場合によっては分離されたリソースの値参照する場合にはこちらが有用そう
terragrunt を使用するとさらに管理に良いらしいので比較検討をするのが良さそう
参照