0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[aws_route53_record バージョン] terraform apply時の `but it already exists]` エラーに対するトラブルシューティング。

Posted at

目的

terraform apply 時の、but it already exists]エラーに対するトラブルシューティング方法を知る。

結論

上記エラーの場合は、tfstate ファイルにはリソースが存在しなくて、実際のインフラにはそのリソースが存在する場合に起きる。
terraform import コマンドで tfstate にも反映してあげる。

説明

今回のエラーが起きた場面

(1)

下記は、SSL証明書の検証のために、CNAME レコードを作成している。
aws_acm_certificate.acmcert.domain_validation_options が、複数の CNAME レコードの情報を持っているということである。

envs/dev/aws_route53_record.tf
resource "aws_route53_record" "r53r_acmcertvalidation" {
  for_each = {
    for dvo in aws_acm_certificate.acmcert.domain_validation_options : dvo.domain_name => {
      name   = dvo.resource_record_name
      type   = dvo.resource_record_type
      record = dvo.resource_record_value
    }
  }

  zone_id = aws_route53_zone.r53zone.zone_id
  name    = each.value.name
  type    = each.value.type
  ttl     = 300
  records = [each.value.record]
}

(2)

terraform applyを実施すると下記のエラーが出た。
※ CIで実行していたり、docker コンテナやterragrunt を使っていたりして分かりにくいですが、terraform applyを実行しているものと考えてください。

$ Run docker exec terraformmy-tfcontainer-1 sh -c "(cd envs/${TARGET_ENV} && terragrunt apply -auto-approve)"
...
15:47:50.598 STDERR terraform: │ Error: creating Route53 Record: operation error Route 53: ChangeResourceRecordSets, https response error StatusCode: 400, RequestID: abc12345-xxxx-xxxx-xxxx-xxxxxxxxxxxx, InvalidChangeBatch: [Tried to create resource record set [name='_example-validation.dev.example.com.', type='CNAME'] but it already exists]
15:47:50.598 STDERR terraform: │ 
15:47:50.598 STDERR terraform: │   with aws_route53_record.r53r_acmcertvalidation["dev.example.com"],
15:47:50.598 STDERR terraform: │   on aws_route53_record.tf line 2, in resource "aws_route53_record" "r53r_acmcertvalidation":
15:47:50.598 STDERR terraform: │    2: resource "aws_route53_record" "r53r_acmcertvalidation" {
15:47:50.598 STDERR terraform: │ 
15:47:50.598 STDERR terraform: ╵

上記エラーは、tfstate ファイルにはリソースが存在しなくて、実際のインフラにはそのリソースが存在する場合に起きる。
tfstate ファイルと実際のインフラ状態に齟齬があるので、よろしくない状況である。
今回の例では、CNAME レコードが、tfstate にうまく反映されていないということである。

トラブルシューティング

(1)

tfstate ファイルと、実際のインフラに齟齬が起きたときに、一番手っ取り早く解決できる可能性があるのは、terraform refresh である。
terraform refreshは、tfstate ファイルと、実際のインフラの齟齬を解消する。
しかし、terraform refreshは万能ではない。
terraform refreshは、tfstate と実際のインフラ状態の齟齬をなくすというのは少し語弊があり、正確には、tfstate と tfstate(terraform) で管理されている実際のインフラ状態との齟齬をなくすのである。
今回、terraform refreshをしても、CNAME は tfstate の管理対象にはならなかったので、terraform applyをしたときにエラーが起きた。CNAMEが実際のインフラに存在するのにも関わらず、terraform apply は tfstate の情報を信じてCNAMEの作成を試みたが、すでに作成してあったのでエラーが起きた。

(2)

次に、公式ドキュメントを参考にして、terraform importの実行を試みる。
下記のコマンドで成功した。
※ 相変わらず、dockerコンテナなどを使っていて分かりにくくてすみません。
※ ID とかの文字列は機密情報のため、適当に改変しています。
Z0256789SDF6HDFJJ4EF がゾーンIDで、_89098748f6b765436ghjk0567f67c900.dev.example.com が レコードのname です。
※ AWSコンソールからCNAMEレコードの情報を見ればわかりますが、他のレコードと違って、name がdev.example.comではなくて、_89098748f6b765436ghjk0567f67c900.dev.example.comのようになっているので注意してください。
※ envs/dev/aws_route53_record.tfの r53r_acmcertvalidation リソースはforループで作成されているので、どれを使うのかを明示するために、[\\\"dev.example.com\\\"]と書いています。
["dev.example.com"] ではなくて、[\\\"dev.example.com\\\"] と書いている理由は、コンテナにコマンドを渡すために、エスケープしているだけです。

~/TerraformMy$ sudo docker exec terraformmy-tfcontainer-1 sh -c "(cd envs/dev && terraform import aws_route53_record.r53r_acmcertvalidation[\\\"dev.example.com\\\"]
 Z0256789SDF6HDFJJ4EF__89098748f6b765436ghjk0567f67c900.dev.example.com_CNAME)"
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?