😽

AWS ACMでDNS検証を実装しようとしたら詰まった

2023/01/07に公開

以下のようにTerraformでAWS ACM証明書作成と検証を実装

# ACM
## certification
resource "aws_acm_certificate" "example" {
  domain_name = aws_route53_record.example.name
  subject_alternative_names = []
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}

## DNS validation
resource "aws_route53_record" "example_certificate" {
  name = aws_acm_certificate.example.domain_validation_options[0].resource_record_name
  type = aws_acm_certificate.example.domain_validation_options[0].resource_record_type
  records = [aws_acm_certificate.example.domain_validation_options[0].resource_record_value]

  zone_id = aws_route53_zone.test_example.id
  ttl = 60
}

## wait until validation
resource "aws_acm_certificate_validation" "example" {
  certificate_arn = aws_acm_certificate.example.arn
  validation_record_fqdns = [aws_route53_record.example_certificate.fqdn]
}

以下のようなエラーを吐いた

web-app % terraform apply

Error: Invalid index

  on main.tf line 311, in resource "aws_route53_record" "example_certificate":
 311:   name = aws_acm_certificate.example.domain_validation_options[0].resource_record_name

This value does not have any indices.

Error: Invalid index

  on main.tf line 312, in resource "aws_route53_record" "example_certificate":
 312:   type = aws_acm_certificate.example.domain_validation_options[0].resource_record_type

This value does not have any indices.

Error: Invalid index

  on main.tf line 313, in resource "aws_route53_record" "example_certificate":
 313:   records = [aws_acm_certificate.example.domain_validation_options[0].resource_record_value]

This value does not have any indices.

どうやらAWS providerバージョンが原因みたい。

AWS Provider3.0.0以降はlistタイプからsetタイプに変更になったらしい。

TerraformによるDNS認証のレコード登録で「Invalid index」のエラー - Qiita

for each文に修正してみた

# ACM
## certification
resource "aws_acm_certificate" "example" {
  domain_name = aws_route53_record.example.name
  subject_alternative_names = []
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}
## DNS validation
resource "aws_route53_record" "example_certificate" {
  for_each = {
    for dvo in aws_acm_certificate.example.domain_validation_options : dvo.domain_name => {
      name   = dvo.resource_record_name
      record = dvo.resource_record_value
      type   = dvo.resource_record_type
    }
  }
  name            = each.value.name
  records         = [each.value.record]
  type            = each.value.type
  zone_id = aws_route53_zone.test_example.id
  ttl = 60
}

## wait until validation
resource "aws_acm_certificate_validation" "example" {
  certificate_arn = aws_acm_certificate.example.arn
  validation_record_fqdns = [for record in aws_route53_record.example_certificate : record.fqdn]
}

再度実行したが、また別のエラーが

% terraform apply    

Error: Reserved argument name in resource block

  on main.tf line 314, in resource "aws_route53_record" "example_certificate":
 314:   for_each = {

The name "for_each" is reserved for use in a future version of Terraform.

どうやらバージョンが古く、for eachが使えないっぽい

for_eachはterraform0.12.6以降に追加された機能みたいなので、アップデートが必要

https://github.com/terraform-aws-modules/terraform-aws-vpc/issues/364

% terraform --version
Terraform v0.12.5
+ provider.aws v3.37.0

Your version of Terraform is out of date! The latest version
is 1.3.7. You can update by downloading from www.terraform.io/downloads.html

terraform0.12.6にアップデート

% tfenv install 0.12.6
Installing Terraform v0.12.6
Downloading release tarball from https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_darwin_amd64.zip
############################################################################################################################## 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_SHA256SUMS
Not instructed to use Local PGP (/opt/homebrew/Cellar/tfenv/3.0.0/use-{gpgv,gnupg}) & No keybase install found, skipping OpenPGP signature verification
Archive:  /var/folders/qs/fyy3yr496v758vzmt7v_tdkm0000gn/T/tfenv_download.XXXXXX.4HKg53xS/terraform_0.12.6_darwin_amd64.zip
  inflating: /opt/homebrew/Cellar/tfenv/3.0.0/versions/0.12.6/terraform  
Installation of terraform v0.12.6 successful. To make this your default version, run 'tfenv use 0.12.6'

% tfenv list
  0.12.6
* 0.12.5 (set by /opt/homebrew/Cellar/tfenv/3.0.0/version)
  0.12.4

% tfenv use 0.12.6
Switching default version to v0.12.6
Default version (when not overridden by .terraform-version or TFENV_TERRAFORM_VERSION) is now: 0.12.6
% tfenv list      
* 0.12.6 (set by /opt/homebrew/Cellar/tfenv/3.0.0/version)
  0.12.5
  0.12.4

% terraform --version
Terraform v0.12.6
+ provider.aws v3.37.0

Your version of Terraform is out of date! The latest version
is 1.3.7. You can update by downloading from www.terraform.io/downloads.html

今度はうまくいった

% terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_acm_certificate.example will be created
  + resource "aws_acm_certificate" "example" {
      + arn                       = (known after apply)
      + domain_name               = "hoge-test.com"
      + domain_validation_options = [
          + {
              + domain_name           = "hoge-test.com"
              + resource_record_name  = (known after apply)
              + resource_record_type  = (known after apply)
              + resource_record_value = (known after apply)
            },
        ]
      + id                        = (known after apply)
      + status                    = (known after apply)
      + subject_alternative_names = (known after apply)
      + validation_emails         = (known after apply)
      + validation_method         = "DNS"
    }

  # aws_acm_certificate_validation.example will be created
  + resource "aws_acm_certificate_validation" "example" {
      + certificate_arn         = (known after apply)
      + id                      = (known after apply)
      + validation_record_fqdns = (known after apply)
    }

  # aws_route53_record.example_certificate["hoge-test.com"] will be created
  + resource "aws_route53_record" "example_certificate" {
      + allow_overwrite = (known after apply)
      + fqdn            = (known after apply)
      + id              = (known after apply)
      + name            = (known after apply)
      + records         = (known after apply)
      + ttl             = 60
      + type            = (known after apply)
      + zone_id         = "Z07533702B9OA0PHM9C9U"
    }

Plan: 3 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_acm_certificate.example: Creating...
aws_acm_certificate.example: Creation complete after 6s [id=arn:aws:acm:ap-northeast-1:741420225566:certificate/8d6a2d1d-cda1-4d9c-a2b7-4b2a74eb3185]
aws_route53_record.example_certificate["hoge-test.com"]: Creating...
aws_route53_record.example_certificate["hoge-test.com"]: Still creating... [10s elapsed]
aws_route53_record.example_certificate["hoge-test.com"]: Still creating... [20s elapsed]
aws_route53_record.example_certificate["hoge-test.com"]: Still creating... [30s elapsed]
aws_route53_record.example_certificate["hoge-test.com"]: Still creating... [40s elapsed]
aws_route53_record.example_certificate["hoge-test.com"]: Creation complete after 42s [id=Z07533702B9OA0PHM9C9U__84cd1dfeb27d7fab6f21457edee2257e.hoge-test.com._CNAME]
aws_acm_certificate_validation.example: Creating...
aws_acm_certificate_validation.example: Creation complete after 1s [id=2023-01-07 12:09:49.356 +0000 UTC]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Discussion