「count/for_each depends on resource attributes」エラーの原因と解決方法

1. 概要

  • 「The ‘count’ value depends on resource attributes that cannot be determined until apply」エラー
  • for_eachの同様のエラー
  • 原因:planフェーズで未知の値をcount/for_eachに渡している
  • 解決方法(変数化・data source分離・-targetフラグ)

Terraformはplanフェーズでcountfor_eachの値を確定する必要があります。この値がapply後にしか決まらないリソースの属性(未知の値)に依存していると、このエラーが発生します。


2. エラーメッセージ

Error: Invalid count argument

  on main.tf line X, in resource "aws_instance" "web":
   X:   count = length(aws_security_group.web.ingress)

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on, and then apply normally.

3. エラーの再現例

terraform {
  required_version = ">= 1.9"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

variable "environment" {
  description = "環境名"
  type        = string
  default     = "dev"
}

resource "aws_security_group" "web" {
  name   = "${var.environment}-web-sg"
  vpc_id = aws_vpc.main.id

  tags = {
    Name        = "${var.environment}-web-sg"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

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

  tags = {
    Name        = "${var.environment}-main"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

data "aws_ami" "amazon_linux_2023" {
  most_recent = true
  owners      = ["amazon"]
  filter {
    name   = "name"
    values = ["al2023-ami-*-x86_64"]
  }
}

# ❌ エラー: aws_security_group.webのidはapplyまで確定しない
resource "aws_instance" "web" {
  count = length(aws_security_group.web.ingress)  # ← applyまで不明

  ami           = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.micro"

  root_block_device {
    volume_size = 20
    volume_type = "gp3"
    encrypted   = true
  }

  tags = {
    Name        = "${var.environment}-web-${count.index}"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

4. 解決方法1: 変数で数を直接指定する(推奨)

variable "web_instance_count" {
  description = "Webインスタンス数"
  type        = number
  default     = 2
}

# ✅ 変数で直接数を指定(planフェーズで確定できる)
resource "aws_instance" "web" {
  count = var.web_instance_count

  ami           = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.micro"

  root_block_device {
    volume_size = 20
    volume_type = "gp3"
    encrypted   = true
  }

  tags = {
    Name        = "${var.environment}-web-${count.index + 1}"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

5. 解決方法2: -targetで段階的にapplyする(応急処置)

# ステップ1: 先にセキュリティグループだけapply
terraform apply -target=aws_security_group.web

# ステップ2: 通常のapply(countの値が確定した状態で実行)
terraform apply

-targetは応急処置として有効ですが、恒久的な解決策には変数化を推奨します。


6. for_each の同様エラー

# ❌ エラー: applyまで確定しない値をfor_eachに渡す
resource "aws_iam_role_policy_attachment" "attachments" {
  for_each = aws_iam_policy.custom  # ← countと同じくplanで確定できない場合がある

  role       = aws_iam_role.app.name
  policy_arn = each.value.arn
}

# ✅ 修正: あらかじめわかっているsetをfor_eachに渡す
variable "policy_names" {
  description = "アタッチするポリシー名のセット"
  type        = set(string)
  default     = ["ReadOnlyAccess", "CloudWatchFullAccess"]
}

resource "aws_iam_role_policy_attachment" "attachments" {
  for_each = var.policy_names

  role       = aws_iam_role.app.name
  policy_arn = "arn:aws:iam::aws:policy/${each.value}"
}

7. まとめ

状況対処法
countに任意リソースの属性を使っている変数で数を直接指定する
どうしても動的に決まる場合-targetで依存リソースを先にapply
for_eachに動的な値を使っている変数のset/mapに変換する

8. 関連記事


9. まとめ

  • countfor_eachの値はplanフェーズで確定している必要がある
  • applyまで確定しないリソース属性(新規作成リソースのIDなど)をcountに使うとエラー
  • 根本解決は変数化(var.instance_countのように直接数を指定)
  • 応急処置として-targetで依存リソースを先にapplyしてから再度applyする

動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/meta-arguments/count#the-count-value-depends-on-resource-attributes