1. 概要
terraform_dataリソースとは何か(Terraform 1.4以降)null_resourceとの違いinputとtriggers_replaceの使い方- プロビジョナーとの組み合わせ
- 実際のユースケース
terraform_dataはTerraform 1.4で導入された組み込みリソースです。null_resource(HashiCorp Null Providerが必要)の代替として、追加プロバイダー不要で任意のトリガーによるリソース更新を実現します。
2. terraform_data vs null_resource
| 比較 | terraform_data | null_resource |
|---|---|---|
| 利用可能バージョン | Terraform 1.4以降 | 全バージョン |
| 必要なプロバイダー | 不要(組み込み) | hashicorp/nullが必要 |
input属性 | あり(stateに保存できる) | なし |
triggers_replace | あり | triggers(同等) |
| 推奨 | ✅ 新規コードではこちら | 後方互換性のみ |
3. 基本構文
resource "terraform_data" "名前" {
# オプション: stateに保存する任意の値
input = <任意の値>
# オプション: 変化するとリソースが再作成される条件
triggers_replace = <監視する値>
}
4. triggers_replace — 特定の変化で再実行する
triggers_replaceの値が変わるとterraform_dataリソースが再作成され、紐づくプロビジョナーが再実行されます。
terraform {
required_version = ">= 1.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
variable "environment" {
description = "環境名"
type = string
default = "dev"
}
variable "app_version" {
description = "デプロイするアプリバージョン"
type = string
default = "1.0.0"
}
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux_2023.id
instance_type = "t3.micro"
root_block_device {
volume_size = 20
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "${var.environment}-web"
Environment = var.environment
ManagedBy = "terraform"
}
}
# app_versionが変わるたびにデプロイスクリプトを再実行
resource "terraform_data" "deploy" {
triggers_replace = {
instance_id = aws_instance.web.id
app_version = var.app_version
}
provisioner "remote-exec" {
connection {
type = "ssh"
host = aws_instance.web.public_ip
user = "ec2-user"
private_key = file("~/.ssh/id_rsa")
}
inline = [
"cd /app && git pull",
"systemctl restart app",
]
}
}
5. input — 計算結果をstateに保存する
inputに値を設定すると、その値がoutput属性としてstateに保存され、他のリソースから参照できます。
locals {
# 複雑な計算の結果
server_config = {
ami_id = data.aws_ami.amazon_linux_2023.id
instance_type = var.environment == "prd" ? "t3.medium" : "t3.micro"
environment = var.environment
}
}
# 計算結果をstateに保存
resource "terraform_data" "server_config" {
input = local.server_config
}
output "resolved_ami_id" {
description = "使用するAMI ID"
value = terraform_data.server_config.output["ami_id"]
}
6. null_resourceからの移行
# 旧コード(null_resource)
# resource "null_resource" "deploy" {
# triggers = {
# version = var.app_version
# }
# provisioner "local-exec" {
# command = "echo 'Deploying version ${var.app_version}'"
# }
# }
# 新コード(terraform_data)
resource "terraform_data" "deploy" {
triggers_replace = var.app_version
provisioner "local-exec" {
command = "echo 'Deploying version ${var.app_version}'"
}
}
7. 関連記事
- lifecycle の使い方 — replace_triggered_byとの組み合わせ
- moved ブロック — null_resourceからterraform_dataへの移行時にstateアドレスを変更する
- resourceブロック — 基本構文と使い方
- depends_on — 明示的な依存関係を宣言
- check ブロック — インフラのアサーション検証
- precondition / postcondition — ライフサイクル中の条件検証
8. まとめ
terraform_dataはTerraform 1.4以降で使える組み込みリソースnull_resourceの代替として追加プロバイダー不要で利用できるtriggers_replaceの値が変わると再作成されプロビジョナーが再実行されるinputに値を保存すればoutput属性から他のリソースが参照できる- 新規コードでは
null_resourceよりterraform_dataを使うことを推奨
動作確認バージョン: Terraform >= 1.4 公式ドキュメント: https://developer.hashicorp.com/terraform/language/resources/terraform-data