05. resource と data
Terraform の主役は resource。「これを作って」と命令するブロックです。一方 data は「これを読んで」と既存リソースを参照するブロック。さらにライフサイクル(作り直しや削除保護)の制御も学びます。
resource ブロック
resource "<TYPE>" "<NAME>" {
# arguments...
}
- TYPE: provider が定義する型(
aws_instance、aws_s3_bucketなど) - NAME: HCL 内の呼び名。Git で管理する自分用ラベル。AWS の名前ではない
resource "aws_s3_bucket" "logs" {
bucket = "my-app-logs-20260510"
tags = {
Name = "my-app-logs"
Env = "dev"
}
}
他リソースの属性を参照する
形は <TYPE>.<NAME>.<ATTRIBUTE>。Terraform はこの参照を見て依存順を勝手に決めます。
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id # ← VPC の id を参照
cidr_block = "10.0.1.0/24"
}
resource "aws_security_group" "web" {
vpc_id = aws_vpc.main.id # ← 同じく
name = "web"
}
各 resource がどんな属性を返すかは、provider のドキュメントの「Attribute Reference」セクションを見ます(例: aws_vpc なら id, arn, default_security_group_id など)。
依存関係(暗黙と明示)
上の例のように、あるリソースが別のリソースの属性を参照していれば、暗黙の依存関係 が自動で作られます。Terraform は「VPC を先に作ってから subnet を作る」と判断します。
属性参照がないのに順序を強制したい時だけ depends_on:
resource "aws_iam_role_policy" "ssm" {
role = aws_iam_role.ec2.id
policy = data.aws_iam_policy_document.ssm.json
}
resource "aws_instance" "web" {
ami = data.aws_ami.al2023.id
instance_type = "t3.micro"
iam_instance_profile = aws_iam_instance_profile.ec2.name
# SSM ポリシーが先に attach されてから起動して欲しい(暗黙の依存はないので明示)
depends_on = [aws_iam_role_policy.ssm]
}
使いすぎ注意
depends_on は 本当に必要な時だけ。属性参照で済むなら参照のほうが意図が明確で、リファクタも壊れにくい。
data ソース
「すでに存在するもの」を Terraform に読ませるブロック。新しくは何も作りません。
data "aws_ami" "al2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
# 参照は data.<TYPE>.<NAME>.<ATTR>
resource "aws_instance" "web" {
ami = data.aws_ami.al2023.id # ← AMI ID を毎回最新に
instance_type = "t3.micro"
tags = {
Account = data.aws_caller_identity.current.account_id
Region = data.aws_region.current.name
}
}
resource と data の使い分け
| resource | data | |
|---|---|---|
| 役割 | 作る/変える/消す | 読むだけ |
| state に書く | はい | 読み込んだ結果は持つが、消えても無害 |
| 典型例 | 新しい VPC を作る | 会社共通 VPC の ID を引いて使う |
lifecycle ─ 作り直しと削除保護
リソースの「変化のさせ方」を制御するメタブロック。
resource "aws_security_group" "web" {
name_prefix = "web-"
vpc_id = aws_vpc.main.id
lifecycle {
create_before_destroy = true # 新しい SG を先に作ってから古いのを消す
}
}
resource "aws_db_instance" "main" {
# ...
lifecycle {
prevent_destroy = true # destroy しようとするとエラー(DB を守る)
ignore_changes = [
password, # この属性の差分は無視(外で変更)
tags["LastBackup"], # ネストした要素も指定可
]
}
}
resource "aws_instance" "web" {
# ...
lifecycle {
precondition {
condition = data.aws_ami.al2023.architecture == "x86_64"
error_message = "x86_64 の AMI を使ってください。"
}
postcondition {
condition = self.public_dns != ""
error_message = "Public DNS が割り当てられていません。"
}
}
}
主な lifecycle 引数
| 引数 | 役割 | 使う場面 |
|---|---|---|
create_before_destroy | 置換時に新を先に作る | SG, ELB など名前一意で停止が許されないもの |
prevent_destroy | destroy をエラーに | 本番 DB、本番 S3 バケット |
ignore_changes | 属性差分を無視 | 外部ツールが書き換える tag、自動更新される password |
replace_triggered_by | 別リソース変更で強制再作成 | ASG が起動テンプレ更新で再起動して欲しい |
precondition / postcondition | 事前・事後検証 | 入力 AMI が想定アーキテクチャか等 |
メタ引数の早見表
メタ引数 は、どの resource でも共通で使える特別な引数です(プロバイダ固有ではない)。
| メタ引数 | 役割 | 章 |
|---|---|---|
count | 同じものを N 個作る | 07 |
for_each | map / set から複数作る | 07 |
provider | 使う provider のエイリアスを指定 | 本章末 |
depends_on | 明示的依存 | 本章上 |
lifecycle | 作り直し制御 | 本章上 |