count はリソースやモジュールを同形で複数生成するためのメタ引数。0 台〜N 台をシンプルに表現できる。
試験では count.index、スプラット演算子([*])、条件付き作成(? 1 : 0)と、for_each との違いが頻出。
count はメタ引数で、単一のリソース定義から N 個の同形インスタンスを生成する。count に数値を与えるだけで 0 台(未作成)〜 N 台を切り替えられる点が特徴。参照は必ずインデックス付きになるため、1 台でも [0] の添字が必要になる。
count はリソースだけでなくモジュールにも使える。for_each と同時には使えないため、どちらか一方を選択する。参照は resource.type.name[index].attribute、モジュールは module.name[index].output のようになる。
最も実務で使うのは「フラグで作成を切り替える(count = var.enabled ? 1 : 0)」と「同形のリソースを N 台展開する(count = var.size)」の 2 パターン。後者では、命名やタグに count.index を織り込むとデバッグしやすい。
count=0 を取りうるリソースを参照する場合は、参照時にガード(try や length チェック)を入れて計画の評価時点でのエラーを避ける。
条件付き作成と N 台展開の基本例
# 例: 条件付きで NAT Gateway を 1 台だけ作成
variable "enable_nat" {
type = bool
default = false
}
resource "aws_nat_gateway" "nat" {
count = var.enable_nat ? 1 : 0
allocation_id = var.enable_nat ? aws_eip.nat[0].id : null
subnet_id = var.enable_nat ? aws_subnet.public[0].id : null
tags = {
Name = var.enable_nat ? "nat-0" : null
}
}
# 参照する側での安全なガード
output "nat_gateway_id" {
value = try(aws_nat_gateway.nat[0].id, null)
}
# 例: 同形な Web サーバを N 台作成
variable "web_count" {
type = number
default = 3
}
resource "aws_instance" "web" {
count = var.web_count
ami = var.ami_id
instance_type = var.instance_type
tags = {
Name = format("web-%02d", count.index)
}
}
# すべての ID をまとめて取得(スプラット)
output "web_ids" {
value = aws_instance.web[*].id
}count.index はインスタンス固有の 0 始まりインデックス。命名、配列からの値の取り出し、タグ付けなどに活用できる。1 台構成でも count を使ったなら参照は [0] が必要になる点を忘れない。
複数インスタンスから特定属性を一括で取り出すにはスプラット演算子([*])が便利。resource.type.name[*].attribute はリストを返し、他モジュールやデータソースへ渡しやすい。
count は数の増減や、index に依存する属性の変更で差分が大きくなりやすい。特に、index ベースで名前や CIDR を割り当てる構成で、元となる配列の順序を変えると、多数のリソースが置換になる。
count の値は plan 時に評価可能である必要がある。適用時まで未確定の値(他リソースの未確定属性など)に依存すると、計画が立てられずエラーになる。
破壊的な差分を抑えるには、入力の順序を固定(ソート)する、index に依存しない識別を求めるなら for_each を使う、lifecycle を適切に設計する、といった対策を取る。
両者は複数インスタンス生成の手段だが、識別子の扱いと変更耐性が異なる。名前付きで個別性を持たせたい場合は for_each、同形で数だけ揃えたい場合は count が適する。Associate 試験でもこの選択は頻出。
| 項目 | count | for_each | 備考 |
|---|---|---|---|
| 識別子 | 連番(0..n-1) | 任意のキー(文字列/数値) | キーの安定性が差分最小化に効く |
| 並び順/安定性 | 順序依存(index 再割当) | キー依存(順序非依存) | for_each は順序変更に強い |
| 増減時の影響 | 末尾削減・途中欠番で再割当 | 該当キーのみ追加/削除 | 運用差分が読みやすいのは for_each |
| 典型用途 | 同形 N 台、フラグで有無切替 | 名前付きサブネット、マップ/セット駆動 | 要件に応じて併用 |
| 参照 | res[idx].attr / res[*].attr | res["key"].attr / res[*].attr | モジュールも同様の書式 |
| モジュール対応 | 可 | 可 | 現在の安定版で両方利用可能 |
モジュールにも count を適用できる。module.vpc[0] のようにインデックス付きで個別参照し、module.vpc[*].vpc_id のようにスプラットで一括取得も可能。モジュールの出力はリスト化されるので、上位モジュールから他のモジュールやリソースへ安全に渡せる。
count=1 の場合でも module.vpc[0].output の形になる点はリソースと同じ。count=0 を取りうるときは try(module.vpc[0].output, null) のようにガードを入れるとよい。
モジュール count の構成イメージ
Associate
問題 1
リスト var.cidr_blocks の順序に基づき、count と count.index を使ってサブネットの CIDR を割り当てています。var.cidr_blocks の並び順を入れ替えた場合、Terraform の挙動として最も適切なのはどれですか?
正解: A
count は数値インデックスでインスタンスを識別するため、入力の順序が変わると index に基づく割当(名前や CIDR など)がずれ、多数の入れ替えが発生しうる。以前の対応関係を自動保持する仕組みはない。順序固定には for_each でキーを安定させるのが有効。
count と for_each はどちらを使えばよいですか?
同形リソースを台数だけで増減するなら count、個別に安定した識別子(名前や ID)で管理したいなら for_each が適します。差分の最小化や後からの変更耐性を優先するなら for_each を選ぶのが無難です。
count=0 になりうるリソースを他から参照するとエラーになります。どう防げますか?
try(resource[0].attr, null) や length(resource) > 0 ? resource[0].attr : null のように参照側でガードしてください。count=0 のとき、リソース参照は空リストになるため、直接 [0] を取ると評価時エラーになります。
モジュールに count を使ったとき、出力はどう参照しますか?
個別参照は module.mod[index].output、複数の出力をまとめて取得するなら module.mod[*].output です。count=1 のときも [0] が必要で、count=0 の可能性があるなら try(module.mod[0].output, null) のように保護します。
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を用いた既存リソース参照の基本、選択基準、評価順序、...