1. 概要
- 「The ‘for_each’ map includes keys derived from resource attributes that cannot be determined until apply」エラー
countエラーとの違い- 原因とよくある発生パターン
- 解決方法(
toset()・変数化・段階的apply)
for_eachではcountと同様に、planフェーズで確定できない値をキーに使うとエラーになります。ただしfor_eachの場合、キー(key)が未知であることが問題であり、値(value)が未知の場合とは異なります。
2. エラーメッセージ
Error: Invalid for_each argument
on main.tf line X, in resource "aws_route53_record" "records":
X: for_each = aws_instance.web
The "for_each" map includes keys derived from 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 for_each depends on.
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"
}
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
resource "aws_instance" "web" {
count = 3
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"
}
}
# ❌ エラー: aws_instance.web の id はapplyまで確定しない
resource "aws_eip_association" "web" {
for_each = { for i, inst in aws_instance.web : inst.id => inst }
# ^^^^^^ applyまで不明
instance_id = each.value.id
allocation_id = "eipalloc-xxxxx"
}
4. 解決方法1: 既知の値をキーに使う(推奨)
# ✅ countのインデックスをキーに使う(planフェーズで確定できる)
resource "aws_eip_association" "web" {
for_each = { for i in range(3) : i => aws_instance.web[i] }
instance_id = each.value.id
allocation_id = "eipalloc-xxxxx"
}
# ✅ さらに良い方法: 変数のsetをfor_eachに使い、インスタンスもfor_eachで作る
variable "web_servers" {
description = "Webサーバーの定義"
type = set(string)
default = ["web-1", "web-2", "web-3"]
}
resource "aws_instance" "web" {
for_each = var.web_servers
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}-${each.key}"
Environment = var.environment
ManagedBy = "terraform"
}
}
# for_eachのキーが var.web_servers(planで確定済み)なのでエラーにならない
resource "aws_eip" "web" {
for_each = var.web_servers
tags = {
Name = "${var.environment}-${each.key}-eip"
Environment = var.environment
ManagedBy = "terraform"
}
}
5. 解決方法2: -targetで段階的にapply(応急処置)
# ステップ1: インスタンスだけ先にapply
terraform apply -target=aws_instance.web
# ステップ2: インスタンスのIDが確定した状態で全体apply
terraform apply
6. countとfor_eachエラーの違い
| 比較 | countエラー | for_eachエラー |
|---|---|---|
| エラーになる場所 | countの数が未知 | for_eachのキーが未知 |
| 値が未知でもエラー? | はい | キーが既知なら値が未知でもOK |
| よくある原因 | length(resource.attr) | { for x in resource : x.id => x } |
| 応急処置 | -target | -target |
7. 関連記事
- for_each の使い方 — for_eachの基本と活用
- err_invalid_count — count依存エラー — countの同様エラー
- err_cycle — 循環参照エラー — 別の依存関係エラー
- よくあるエラー集 — common_errors — 他のエラー一覧
- count — 同じリソースを複数作成する
- 「Inconsistent result types」エラーの解決方法
8. まとめ
for_eachのキーがapplyまで確定しない属性(新規リソースのIDなど)に依存するとエラー- 根本解決は
for_eachのキーに変数やリテラルなど「planで確定できる値」を使う - インスタンスを
countで作る場合はrange(n)でキーを生成する - インスタンスも
for_eachで作るなら変数のsetを共通のキーとして使う - 応急処置は
-targetで依存リソースを先にapply
動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/meta-arguments/for_each