20
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

TerraformのバージョンアップでInvalid indexが出た時の対処

Posted at

小ネタです。

ACMをterraformで作る方法が使えなくなってた件

これまでterraformでACMを作成する方法として

https://dev.classmethod.jp/articles/acm-cert-by-terraform/
こちらの記事を参考に作っていました。

それで、問題の部分は以下の部分です。
こちらは上記の記事から引用しています。

resource aws_route53_record cert_validation {
  zone_id = data.aws_route53_zone.route53-zone.zone_id
  name    = aws_acm_certificate.cert.domain_validation_options[0].resource_record_name
  type    = aws_acm_certificate.cert.domain_validation_options[0].resource_record_type
  records = [aws_acm_certificate.cert.domain_validation_options[0].resource_record_value]
  ttl     = 60
}

しかし、最新版のawsプロバイダーではList型からSet型へ変わってしまうことで、以下のように差分が発生します。

$ tf plan

Error: Invalid index

  on aws_route53.tf line 30, in resource "aws_route53_record" "acm_example_jp_cert":
  30:   name    = aws_acm_certificate.example_jp.domain_validation_options[0]["resource_record_name"]

This value does not have any indices.

確かにドキュメントを読むと、
3.8.0だとSet of 2.70.0だとlist ofになってますね。

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate#domain_validation_options
https://registry.terraform.io/providers/hashicorp/aws/2.70.0/docs/resources/acm_certificate#domain_validation_options

このことはTerraform0.13 にアップグレードしたとき、という話がよくありますが、どちらかというとプラグインの問題のはずです。

こちらの方は、for_eachを用いてstate mvにて対応しています。
SANsの時に複数の値が入ってくることがあり、そのためにSet/Listになっているので、
for_eachで作成することは理にかなっています。

私も最初この方法をとろうとしました。
しかしstate mvだと普段と流れが異なるため、手順を作って、レビューして、云々・・・と普通より面倒だったので、
コードのほうを変えて差分をなくす方法をとりました。
一時しのぎ。

tolistを使う方法

ということで、あまり理には適っていませんが、以下でも対処できました。

resource "aws_route53_record" "cert_validation" {
  zone_id = data.aws_route53_zone.route53-zone.zone_id
  name    = tolist(aws_acm_certificate.cert.domain_validation_options)[0].resource_record_name
  type    = tolist(aws_acm_certificate.cert.domain_validation_options)[0].resource_record_type
  records = [tolist(aws_acm_certificate.cert.domain_validation_options)[0].resource_record_value]
  ttl     = 60
}

ListじゃなければListにすればいいじゃないか、ということで組み込み関数を利用する方法です。
新規に作成する場合はfor_eachを使ったほうがいいでしょう。

まとめ

terraformには組み込み関数がそこそこあります。
for_each使うときにtosetなんかはよく使いますね。

これらを使いすぎると可読性は落ちると思いますが、
便利なので必要に応じて使っていくと良いと思いました。

20
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?