Terraform

Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義

2026-04-19
NicheeLab編集部

Terraformの最小単位はResourceブロックです。クラウド上の実体(例: VPC, インスタンス, バケット)を宣言し、計画・適用の対象となる基本構成要素です。

本稿では公式ドキュメントの挙動に基づき、試験で問われやすい観点と現場でハマりがちなポイントを整理します。

Resourceブロックの基本構造と命名

Resourceブロックは provider が提供するリソースタイプと、一意なローカル名の組み合わせで定義します。1モジュール内で同じタイプ・同名の重複は不可です。属性(引数)を与えて希望状態を宣言します。

タイプは provider により定義され、慣例として provider 接頭辞(例: aws_, azurerm_, google_)がつきます。ローカル名は英数字とアンダースコアが利用でき、後続の参照に使われます。

  • 最小構成: resource "<TYPE>" "<NAME>" { ... }
  • 同一モジュール内で NAME はユニークにする
  • 属性は map, list, object などの HCL 表現を利用
  • 出力時の参照は type.name.attribute 形式
ブロック種別目的典型例
resourceインフラ実体を作成・更新・削除resource "aws_s3_bucket" "logs" { ... }
data既存情報の読み取り(作成はしない)data "aws_iam_policy_document" "example" { ... }
module再利用可能な構成の呼び出しmodule "vpc" { source = "..." }
locals式の結果をローカル変数として再利用locals { common_tags = { ... } }
outputモジュール外へ値をエクスポートoutput "bucket_name" { value = aws_s3_bucket.logs.id }

最小のResourceブロック例

resource "aws_s3_bucket" "logs" {
  bucket = "nicheelab-logs-${var.env}"
  tags = {
    Project = "NicheeLab"
    Env     = var.env
  }
}

output "bucket_id" {
  value = aws_s3_bucket.logs.id
}

依存関係とDAG: 暗黙と明示

Terraformは参照関係から自動的にDAG(有向非循環グラフ)を構築し、並列実行と順序制御を行います。別リソースの属性を使えば暗黙の依存が作られます。

参照できないが順序を保証したい場合のみ depends_on を使います。過剰な depends_on は並列性を下げるため、まずは参照で済むかを検討します。

  • 暗黙依存: 他リソースの属性参照により自動で順序が決まる
  • 明示依存: depends_on = [resource.type.name] を必要最小限で
  • 循環参照はエラーとなるため設計段階で分解する

リソース依存のDAGイメージ

aws_vpc.main(作成が先)aws_subnet.app(VPCに依存)aws_instance.web(Subnetに依存)aws_vpc.main → aws_subnet.app → aws_instance.web

暗黙依存と明示依存の例

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "app" {
  vpc_id            = aws_vpc.main.id  # 参照により暗黙依存
  cidr_block        = "10.0.1.0/24"
  availability_zone = var.az
}

resource "null_resource" "post_config" {
  # ファイル生成など外部要件で順序を保証したいときのみ
  depends_on = [aws_subnet.app]

  triggers = {
    stamp = timestamp()
  }
}

メタ引数: count / for_each / provider / lifecycle

count は整数で単純な繰り返し、for_each はキー付きコレクションで個別識別が必要な場合に使います。provider はエイリアスで特定の資格情報やリージョンを選択可能です。

lifecycle は作成・置換の振る舞いを制御しますが、便利だからと多用すると差分解消が難しくなるため、明確な理由があるときのみ設定します。

  • count.index は0始まり。参照は resource.type.name[count.index]
  • for_each は各要素を resource.type.name[each.key] で参照
  • provider = aws.us_east のようにエイリアス選択が可能
  • lifecycle は create_before_destroy / prevent_destroy / ignore_changes など

count と for_each、provider エイリアスの例

provider "aws" {
  region = var.region
}

provider "aws" {
  alias  = "dr"
  region = var.dr_region
}

# count: 単純なN個
resource "aws_iam_user" "ops" {
  count = var.ops_user_count
  name  = "ops-${count.index}"
}

# for_each: 名前で個別管理
resource "aws_s3_bucket" "team" {
  for_each = toset(var.team_names)
  bucket   = "nicheelab-${each.key}-bucket"
  provider = aws  # 明示省略可
}

# DR側へ明示的に作成
resource "aws_s3_bucket" "team_dr" {
  for_each = toset(var.team_names)
  bucket   = "nicheelab-${each.key}-bucket-dr"
  provider = aws.dr
}

# 参照例
output "team_buckets" {
  value = { for k, v in aws_s3_bucket.team : k => v.id }
}

引数(arguments)と属性(attributes)の違い、参照の基本

arguments は設定可能な入力で、attributes は作成後にTerraformが知り得る出力・読み取り値を含みます。plan で computed と表示される属性は適用後に確定します。

他リソースの属性を参照する場合は type.name.attr を使い、複合属性はドット記法や index でアクセスします。循環参照にならないように、入力値に出力属性を安易に組み込まない設計が重要です。

  • 設定可能かどうかはproviderリソースのスキーマで決まる
  • computed属性は適用後に確定し、planでunknownとなることがある
  • 出力にまとめておくとモジュール境界をまたぐ参照が明確になる

属性参照と出力の例

resource "aws_s3_bucket" "logs" {
  bucket = "nicheelab-logs-${var.env}"
  tags = var.common_tags
}

resource "aws_s3_bucket_policy" "logs" {
  bucket = aws_s3_bucket.logs.id  # 属性参照により依存
  policy = data.aws_iam_policy_document.allow_put.json
}

data "aws_iam_policy_document" "allow_put" {
  statement {
    actions   = ["s3:PutObject"]
    resources = ["${aws_s3_bucket.logs.arn}/*"]
    principals { type = "AWS" identifiers = [var.app_role_arn] }
  }
}

output "logs_bucket_arn" {
  value = aws_s3_bucket.logs.arn
}

ライフサイクル制御: create_before_destroy / prevent_destroy / ignore_changes

置換が必要な属性変更では、通常は destroy → create の順序となります。create_before_destroy を使うと先に新規作成し、切替後に古いものを削除します。名前衝突や制約があるリソースでは失敗することがあるため注意します。

prevent_destroy は誤削除防止に有効ですが、計画どおりに削除できなくなるため、意図をチームで共有し、必要に応じて一時的に外して変更を適用します。ignore_changes は手動変更を一時的に無視できますが、長期運用ではドリフトの温床になりやすいです。

  • create_before_destroy は切替時のダウンタイム回避に有効
  • prevent_destroy は厳格運用の重要資産で使用(例: 共有VPC)
  • ignore_changes は一時措置とし、恒久化しない方針を明文化

lifecycle の典型パターン

resource "aws_lb" "public" {
  name               = "nicheelab-pub"
  internal           = false
  load_balancer_type = "application"

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_s3_bucket" "archive" {
  bucket = "nicheelab-archive-${var.env}"
  lifecycle {
    prevent_destroy = true
    ignore_changes  = [tags]  # タグを手動変更する運用の暫定対応
  }
}

実務TipとAssociate試験の押さえ所

命名は将来の参照と検索性を優先して、type.name で役割が推測できるようにします。タグや共通設定は locals にまとめ、各Resourceで再利用します。

試験では、暗黙依存の理解、count と for_each の使い分け、lifecycle 各項目の意味、data と resource の違いが頻出です。コードを読んで挙動を説明できるレベルを目指しましょう。

  • locals で共通タグを一元化し、各リソースへ適用
  • 必要最小限の depends_on、過度な明示依存は避ける
  • 出力(output)はモジュール境界の契約として設計
  • terraform plan の差分理由を文章で説明できるように練習

locals と再利用の小例

locals {
  common_tags = {
    Project = "NicheeLab"
    Owner   = var.owner
  }
}

resource "aws_s3_bucket" "app" {
  bucket = "nicheelab-app-${var.env}"
  tags   = local.common_tags
}

output "app_bucket" {
  value = aws_s3_bucket.app.id
}

問題で確認

Associate

問題 1

あるモジュールで、サブネットIDを他のリソースの引数として渡しています。計画ではサブネット作成後に依存リソースが作成される順序が示されています。この状況で depends_on を追加すべきか、最も適切な選択はどれですか?

  1. A. 追加不要。属性参照による暗黙依存が構築済みであるため。
  2. B. 念のため depends_on を必ず追加するべき。
  3. C. for_each を使えば depends_on は不要になる。
  4. D. lifecycle の create_before_destroy を設定すれば順序が保証される。

正解: A

他リソースの属性を参照していれば暗黙依存が自動で設定されます。順序保証のために depends_on を追加する必要はありません。参照できないが順序制御が必要な場合のみ depends_on を使います。

よくある質問

resource 名の命名規則はありますか?

HCLとしては英数字とアンダースコアが使え、モジュール内でユニークである必要があります。実務では役割や環境がわかるように接頭辞・接尾辞(例: web, db, prod, dev)を組み合わせると保守性が上がります。

resource と data の違いは何ですか?

resource はインフラ実体の作成・更新・削除を対象にします。data は既存情報の参照のみで、作成は行いません。依存関係の扱いはどちらも同様で、参照により暗黙依存が構築されます。

depends_on はいつ使うべきですか?

他リソースの属性を直接参照できないが順序保証が必要なときのみです。例として、外部プロビジョニング(null_resourceのprovisioner等)や、明示的に順序を待つ必要があるリソースを扱う場合です。過剰に使うと並列性が落ちます。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Terraform

Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける

Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...

Terraform

Terraform Authoring & Ops Pro: 上位資格の範囲と対策

上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...

Terraform

Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす

Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...

Terraform

Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義

Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...

Terraform

Terraform Data Source徹底理解:既存リソースの参照で壊さず足す

Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...

Terraformの記事一覧 (102件)
© 2026 NicheeLab All rights reserved.