Terraform

Terraform の count メタ引数で複数インスタンスを安全に生成する

2026-04-19
NicheeLab編集部

count はリソースやモジュールを同形で複数生成するためのメタ引数。0 台〜N 台をシンプルに表現できる。

試験では count.index、スプラット演算子([*])、条件付き作成(? 1 : 0)と、for_each との違いが頻出。

count の基本と適用範囲

count はメタ引数で、単一のリソース定義から N 個の同形インスタンスを生成する。count に数値を与えるだけで 0 台(未作成)〜 N 台を切り替えられる点が特徴。参照は必ずインデックス付きになるため、1 台でも [0] の添字が必要になる。

count はリソースだけでなくモジュールにも使える。for_each と同時には使えないため、どちらか一方を選択する。参照は resource.type.name[index].attribute、モジュールは module.name[index].output のようになる。

  • count は数値式。plan 時に確定できない式はエラーになる可能性がある。
  • count = 0 の場合はインスタンスは作られない(空のリスト扱い)。
  • count.index は 0 始まり。属性参照に使える。
  • 同じ定義から同形のインスタンスを作る用途に向く(名前付き識別が不要な場合)。

実務パターン: 条件付き作成と N 台展開

最も実務で使うのは「フラグで作成を切り替える(count = var.enabled ? 1 : 0)」と「同形のリソースを N 台展開する(count = var.size)」の 2 パターン。後者では、命名やタグに count.index を織り込むとデバッグしやすい。

count=0 を取りうるリソースを参照する場合は、参照時にガード(try や length チェック)を入れて計画の評価時点でのエラーを避ける。

  • 条件付き作成時は try(resource[0].attr, null) のように安全に参照する。
  • N 台展開時は命名規則に index を入れ、外部依存がない同形構成にする。

条件付き作成と 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 とスプラット演算子

count.index はインスタンス固有の 0 始まりインデックス。命名、配列からの値の取り出し、タグ付けなどに活用できる。1 台構成でも count を使ったなら参照は [0] が必要になる点を忘れない。

複数インスタンスから特定属性を一括で取り出すにはスプラット演算子([*])が便利。resource.type.name[*].attribute はリストを返し、他モジュールやデータソースへ渡しやすい。

  • 単一参照: resource.name[0].id
  • 一括参照: resource.name[*].id
  • モジュール出力の一括参照: module.mod[*].output_name

変更時の挙動と計画の安定性

count は数の増減や、index に依存する属性の変更で差分が大きくなりやすい。特に、index ベースで名前や CIDR を割り当てる構成で、元となる配列の順序を変えると、多数のリソースが置換になる。

count の値は plan 時に評価可能である必要がある。適用時まで未確定の値(他リソースの未確定属性など)に依存すると、計画が立てられずエラーになる。

破壊的な差分を抑えるには、入力の順序を固定(ソート)する、index に依存しない識別を求めるなら for_each を使う、lifecycle を適切に設計する、といった対策を取る。

  • 配列の順序変更は index ベースの割当を巻き込み、広範囲に置換を引き起こしうる。
  • count が 3→2 に減ると index=2 が破棄される。1→2 に増えると index=1 が新規作成される。
  • 計画時に未確定な値に依存した count は避ける。

count と for_each の使い分け(比較表あり)

両者は複数インスタンス生成の手段だが、識別子の扱いと変更耐性が異なる。名前付きで個別性を持たせたい場合は for_each、同形で数だけ揃えたい場合は count が適する。Associate 試験でもこの選択は頻出。

  • キーが安定しているなら for_each の方が差分が小さく保てる。
  • 台数ベースで十分なら count が最小記述で読みやすい。
項目countfor_each備考
識別子連番(0..n-1)任意のキー(文字列/数値)キーの安定性が差分最小化に効く
並び順/安定性順序依存(index 再割当)キー依存(順序非依存)for_each は順序変更に強い
増減時の影響末尾削減・途中欠番で再割当該当キーのみ追加/削除運用差分が読みやすいのは for_each
典型用途同形 N 台、フラグで有無切替名前付きサブネット、マップ/セット駆動要件に応じて併用
参照res[idx].attr / res[*].attrres["key"].attr / res[*].attrモジュールも同様の書式
モジュール対応現在の安定版で両方利用可能

モジュールでの count と出力の扱い

モジュールにも count を適用できる。module.vpc[0] のようにインデックス付きで個別参照し、module.vpc[*].vpc_id のようにスプラットで一括取得も可能。モジュールの出力はリスト化されるので、上位モジュールから他のモジュールやリソースへ安全に渡せる。

count=1 の場合でも module.vpc[0].output の形になる点はリソースと同じ。count=0 を取りうるときは try(module.vpc[0].output, null) のようにガードを入れるとよい。

  • モジュール出力の集約は module.mod[*].out でリスト化。
  • 個別参照は module.mod[index].out。
  • count=0 を許容するときは try で安全に参照。

モジュール count の構成イメージ

root modulemodule "vpc" { count = 2 }vpc (index 0)module.vpc[0].vpc_idvpc (index 1)module.vpc[1].vpc_idroot module → module.vpc[0] / module.vpc[1] → outputs

問題で確認

Associate

問題 1

リスト var.cidr_blocks の順序に基づき、count と count.index を使ってサブネットの CIDR を割り当てています。var.cidr_blocks の並び順を入れ替えた場合、Terraform の挙動として最も適切なのはどれですか?

  1. 多くのサブネットが置換対象となる可能性が高い(index ベースの割当が変わるため)
  2. Terraform が自動で以前のインデックスと CIDR の対応を保持し、置換は発生しない
  3. apply 時に count が無視され、常に 1 つだけ作成される
  4. depends_on を書けば順序を固定でき、差分は出なくなる

正解: 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) のように保護します。

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

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の記事一覧 (101件)
© 2026 NicheeLab All rights reserved.