Terraformの最小単位はResourceブロックです。クラウド上の実体(例: VPC, インスタンス, バケット)を宣言し、計画・適用の対象となる基本構成要素です。
本稿では公式ドキュメントの挙動に基づき、試験で問われやすい観点と現場でハマりがちなポイントを整理します。
Resourceブロックは provider が提供するリソースタイプと、一意なローカル名の組み合わせで定義します。1モジュール内で同じタイプ・同名の重複は不可です。属性(引数)を与えて希望状態を宣言します。
タイプは provider により定義され、慣例として provider 接頭辞(例: aws_, azurerm_, google_)がつきます。ローカル名は英数字とアンダースコアが利用でき、後続の参照に使われます。
| ブロック種別 | 目的 | 典型例 |
|---|---|---|
| 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
}Terraformは参照関係から自動的にDAG(有向非循環グラフ)を構築し、並列実行と順序制御を行います。別リソースの属性を使えば暗黙の依存が作られます。
参照できないが順序を保証したい場合のみ depends_on を使います。過剰な depends_on は並列性を下げるため、まずは参照で済むかを検討します。
リソース依存のDAGイメージ
暗黙依存と明示依存の例
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 エイリアスの例
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 は作成後にTerraformが知り得る出力・読み取り値を含みます。plan で computed と表示される属性は適用後に確定します。
他リソースの属性を参照する場合は type.name.attr を使い、複合属性はドット記法や index でアクセスします。循環参照にならないように、入力値に出力属性を安易に組み込まない設計が重要です。
属性参照と出力の例
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
}置換が必要な属性変更では、通常は destroy → create の順序となります。create_before_destroy を使うと先に新規作成し、切替後に古いものを削除します。名前衝突や制約があるリソースでは失敗することがあるため注意します。
prevent_destroy は誤削除防止に有効ですが、計画どおりに削除できなくなるため、意図をチームで共有し、必要に応じて一時的に外して変更を適用します。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] # タグを手動変更する運用の暫定対応
}
}命名は将来の参照と検索性を優先して、type.name で役割が推測できるようにします。タグや共通設定は locals にまとめ、各Resourceで再利用します。
試験では、暗黙依存の理解、count と for_each の使い分け、lifecycle 各項目の意味、data と resource の違いが頻出です。コードを読んで挙動を説明できるレベルを目指しましょう。
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 を追加すべきか、最も適切な選択はどれですか?
正解: A
他リソースの属性を参照していれば暗黙依存が自動で設定されます。順序保証のために depends_on を追加する必要はありません。参照できないが順序制御が必要な場合のみ depends_on を使います。
resource 名の命名規則はありますか?
HCLとしては英数字とアンダースコアが使え、モジュール内でユニークである必要があります。実務では役割や環境がわかるように接頭辞・接尾辞(例: web, db, prod, dev)を組み合わせると保守性が上がります。
resource と data の違いは何ですか?
resource はインフラ実体の作成・更新・削除を対象にします。data は既存情報の参照のみで、作成は行いません。依存関係の扱いはどちらも同様で、参照により暗黙依存が構築されます。
depends_on はいつ使うべきですか?
他リソースの属性を直接参照できないが順序保証が必要なときのみです。例として、外部プロビジョニング(null_resourceのprovisioner等)や、明示的に順序を待つ必要があるリソースを扱う場合です。過剰に使うと並列性が落ちます。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける
Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...
Terraform Authoring & Ops Pro: 上位資格の範囲と対策
上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...
Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす
Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...
Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義
Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...
Terraform Data Source徹底理解:既存リソースの参照で壊さず足す
Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...