複数のTerraformモジュールやワークスペースで構成を分割している場合、あるモジュールが管理するリソースの情報(VPCのID、サブネットIDなど)を別のモジュールから参照したいことがあります。terraform_remote_stateデータソースは、別のTerraform構成が持つステートファイルのroot module outputsを読み取るための組み込みデータソースです。
⚠️ セキュリティ上の重要な注意
terraform_remote_stateのoutputsを読み取れるユーザーは、直接のネットワークリクエストによりステートスナップショット全体にもアクセスできます。センシティブなデータを扱うリソースが含まれる場合は使用しないでください(詳細は後述)。
terraform_remote_stateとは
terraform_remote_stateはTerraformの組み込みデータソースで、terraform.io/builtin/terraformプロバイダーによって提供されています。このプロバイダーはプロバイダーの設定なしで使用でき、別途インストールも不要です。
できること:
- リモートバックエンド(S3、GCS、Terraform Cloudなど)に保存されたステートのoutputsを読み取る
- ローカルバックエンドのステートファイルのoutputsを読み取る
- デフォルト値を設定して、outputsが存在しない場合に備える
できないこと:
- root module outputsより深い階層(ネストされたモジュールのoutputsやリソースの詳細)へのアクセス
- outputsとして公開されていないリソースのattributesへの直接アクセス
引数リファレンス
data "terraform_remote_state" "<名前>" {
backend = "<バックエンドタイプ>" # 必須
workspace = "<ワークスペース名>" # オプション
config = { ... } # オプション(ほとんどの場合必要)
defaults = { ... } # オプション
}
| 引数 | 必須 | 型 | 説明 |
|---|---|---|---|
backend | ✅ | string | 使用するバックエンドのタイプ("s3"、"gcs"、"remote"、"local"など) |
workspace | ❌ | string | 対象ワークスペース名(バックエンドがワークスペースをサポートする場合) |
config | ❌ | object | バックエンドの設定(ほとんどのバックエンドで実質必須) |
defaults | ❌ | object | ステートが空またはoutputsが存在しない場合のデフォルト値 |
注意:
config内でネストブロックが必要な場合(例:remoteバックエンドのworkspaces)は、通常のHCLブロック構文ではなくオブジェクト値として指定します。workspaces { ... }ではなくworkspaces = { ... }と書きます。
属性リファレンス
| 属性 | 説明 |
|---|---|
outputs | リモートステートのroot module outputsをすべて含むオブジェクト(Terraform v0.12以降) |
アクセス方法:data.terraform_remote_state.<名前>.outputs.<output名>
基本的な使用例
S3バックエンドのステートを参照する
ネットワーク構成(別のTerraformモジュール)のoutputs:
# network/outputs.tf
output "vpc_id" {
value = aws_vpc.main.id
description = "VPC ID"
}
output "private_subnet_ids" {
value = aws_subnet.private[*].id
description = "プライベートサブネットのIDリスト"
}
アプリケーション構成からネットワーク情報を参照:
terraform {
required_version = ">= 1.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
variable "environment" {
description = "デプロイ環境"
type = string
default = "dev"
}
# ネットワーク構成のステートを参照
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "my-terraform-state"
key = "${var.environment}/network/terraform.tfstate"
region = "ap-northeast-1"
}
}
# AMI をdata sourceで取得
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
# ネットワーク構成のoutputsを利用してEC2インスタンスを作成
resource "aws_instance" "app" {
ami = data.aws_ami.amazon_linux.id
instance_type = "t3.micro"
subnet_id = data.terraform_remote_state.network.outputs.private_subnet_ids[0]
root_block_device {
encrypted = true
}
tags = {
Name = "${var.environment}-app-server"
Environment = var.environment
ManagedBy = "terraform"
}
}
Terraform Cloud(remoteバックエンド)のステートを参照する
data "terraform_remote_state" "vpc" {
backend = "remote"
config = {
organization = "my-org"
workspaces = {
name = "vpc-prod"
}
}
}
resource "aws_instance" "foo" {
ami = data.aws_ami.amazon_linux.id
instance_type = "t3.micro"
subnet_id = data.terraform_remote_state.vpc.outputs.subnet_id
root_block_device {
encrypted = true
}
tags = {
Name = "app-server"
Environment = "prod"
ManagedBy = "terraform"
}
}
ローカルバックエンドのステートを参照する(開発・テスト用)
data "terraform_remote_state" "local_network" {
backend = "local"
config = {
path = "../network/terraform.tfstate"
}
}
defaultsでデフォルト値を設定する
ステートファイルが空の場合やoutputsが存在しない場合の安全策としてdefaultsを使用できます:
variable "environment" {
description = "デプロイ環境"
type = string
default = "dev"
}
data "terraform_remote_state" "shared" {
backend = "s3"
config = {
bucket = "my-terraform-state"
key = "${var.environment}/shared/terraform.tfstate"
region = "ap-northeast-1"
}
defaults = {
vpc_id = "vpc-00000000"
private_subnet_ids = ["subnet-00000000"]
}
}
root module outputsのみアクセス可能
terraform_remote_stateでアクセスできるのは、参照先Terraform構成のroot module outputsのみです。ネストされたモジュールのoutputsには直接アクセスできません。
ネストされたモジュールのoutputsを外部から参照可能にするには、root moduleで明示的に公開する必要があります:
# root module の outputs.tf
module "app" {
source = "..."
}
# ネストモジュールのoutputをroot levelで公開することで terraform_remote_state から参照可能になる
output "app_value" {
value = module.app.example
}
セキュリティに関する重要な注意事項
公式ドキュメントではterraform_remote_stateの使用について重要な警告があります:
公式警告(原文): “Although terraform_remote_state doesn’t expose any other state snapshot information for use in configuration, the state snapshot data is a single object and so any user or server which has enough access to read the root module output values will also always have access to the full state snapshot data by direct network requests. Don’t use terraform_remote_state if any of the resources in your configuration work with data that you consider sensitive.”
要するに、outputsを読める権限 = ステート全体にアクセスできる権限です。センシティブなデータ(データベースパスワード、APIキー等)がステートに含まれる場合は使用を避けてください。
HCP Terraform / Terraform Enterpriseでの推奨代替手段
HCP TerraformまたはTerraform Enterpriseを使用している場合、公式ではterraform_remote_stateよりもtfe_outputsデータソースの使用を推奨しています。tfe_outputsはoutputsのフェッチにワークスペースステートへのフルアクセスを必要としないためよりセキュアです。
# HCP Terraform での推奨方法
data "tfe_outputs" "network" {
organization = "my-org"
workspace = "network-prod"
}
resource "aws_instance" "app" {
subnet_id = data.tfe_outputs.network.values.subnet_id
# ...
}
terraform_remote_stateの代替パターン
公式ドキュメントでは、可能な場合はステートを直接共有するよりも、専用のデータストアを使用することを推奨しています。この方法では共有情報とステートスナップショットに異なるアクセス制御を適用でき、Terraform以外のシステムからもアクセス可能になります:
| データ共有の仕組み | 書き込み | 読み取り |
|---|---|---|
| Amazon SSM Parameter Store | aws_ssm_parameter リソース | aws_ssm_parameter データソース |
| Amazon S3 | aws_s3_object リソース | aws_s3_object データソース |
| Amazon Route53 | aws_route53_record リソース | DNS参照 |
| HashiCorp Consul | consul_key_prefix リソース | consul_key_prefix データソース |
| HCP Terraform | outputsブロック | tfe_outputs データソース |
| Kubernetes ConfigMap | kubernetes_config_map リソース | kubernetes_config_map データソース |
まとめ
terraform_remote_stateは複数のTerraform構成間でoutputsを共有するための組み込みデータソースです。
- 参照できるのはroot module outputsのみ(ネストモジュールは不可)
- セキュリティリスクあり:outputsにアクセスできるユーザーはステート全体にアクセスできる
- HCP Terraform利用時はより安全な
tfe_outputsを推奨 - 可能な場合はSSM Parameter Store等の専用データストアへの切り替えを検討
シンプルなマルチモジュール構成の出力共有には有効ですが、センシティブなデータを扱う環境では代替手段を検討することが重要です。