Tocyukiのブログ

ギターと柔術とプログラミングが好き!

【Terraform】 countからfor_eachへ書き換えたらスプラット演算子の動きが変わった

いままでcountで記述していたものをfor_eachに直してみたところスプラット演算子の動きが変わったのでメモ

状況

いままではVPCのサブネットリソースをcountで複数作ってそれをoutputで他のモジュールに渡して利用しておりました

resource "aws_subnet" "private_data" {
  count                   = length(var.azs)
  vpc_id                  = aws_vpc.vpc.id
  cidr_block              = cidrsubnet(aws_vpc.vpc.cidr_block, 8, 11 + count.index)
  availability_zone       = element(var.azs, count.index)
  map_public_ip_on_launch = false
}

output "data_private_subnets" {
  value = aws_subnet.private_data
}

他のモジュールで使うときはこんな感じで使ってた

resource "aws_db_subnet_group" "db" {
  name        = "${var.name}-${terraform.workspace}-db-subnet"
  description = "Database Subnet Group for ${var.name}-${terraform.workspace}"
  subnet_ids  = var.data_private_subnets[*].id # この部分
}

そんでもって、for_eachを使って書き直したのがこちら

resource "aws_subnet" "private_db" {
  for_each          = var.azs
  cidr_block        = cidrsubnet(aws_vpc.vpc.cidr_block, 8, index(values(var.azs), each.value) + 11)
  availability_zone = each.value
  vpc_id            = aws_vpc.vpc.id
  map_public_ip_on_launch = false
}

すると以下のようなエラーが出るようになった

Error: Unsupported attribute

  on modules/aws/database/subnet_group.tf line 4, in resource "aws_db_subnet_group" "db":
   4:   subnet_ids  = var.data_private_subnets[*].id

This object does not have an attribute named "id".

Issue

とりあえずIssueを漁ってみたら以下が見つかった

github.com

github.com

Issueを読んでみると以下のように修正すれば大丈夫っぽいことがわかった

The short answer is that if you were to modify your code to values(aws_route53_record.record)[*].fqdn it will work as you're expecting it to.

修正

Issueに書いてあるとおり、aws_db_subnet_groupのリソース作成部分を以下のように修正したら問題なく動くようになった

resource "aws_db_subnet_group" "db" {
  name        = "${var.name}-${terraform.workspace}-db-subnet"
  description = "Database Subnet Group for ${var.name}-${terraform.workspace}"
  subnet_ids  = values(var.private_subnets_db)[*].id # この部分
}

おわりに

for_each便利だけど思わぬ落とし穴?にハマってしまいました