★ 初級

05. resource と data

Terraform の主役は resource。「これを作って」と命令するブロックです。一方 data は「これを読んで」と既存リソースを参照するブロック。さらにライフサイクル(作り直しや削除保護)の制御も学びます。

resource ブロック

resource "<TYPE>" "<NAME>" {
  # arguments...
}
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 の使い分け

resourcedata
役割作る/変える/消す読むだけ
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_destroydestroy をエラーに本番 DB、本番 S3 バケット
ignore_changes属性差分を無視外部ツールが書き換える tag、自動更新される password
replace_triggered_by別リソース変更で強制再作成ASG が起動テンプレ更新で再起動して欲しい
precondition / postcondition事前・事後検証入力 AMI が想定アーキテクチャか等

メタ引数の早見表

メタ引数 は、どの resource でも共通で使える特別な引数です(プロバイダ固有ではない)。

メタ引数役割
count同じものを N 個作る07
for_eachmap / set から複数作る07
provider使う provider のエイリアスを指定本章末
depends_on明示的依存本章上
lifecycle作り直し制御本章上