aws_s3_bucket_website_configuration の routing_rules の削除が反映されない

2022/07/12に公開
lib version
Terraform 1.2.3
hashicorp/aws 4.22.0

まずは routing_rules 指定ナシで apply してみる

main.tf の内容はこんな感じ。

resource "aws_s3_bucket" "b" {
  bucket = "example.com"
}

resource "aws_s3_bucket_website_configuration" "c" {
  bucket = aws_s3_bucket.b.bucket
  index_document {
    suffix = "index.html"
  }
}

実行してみる。

$ terraform apply
...
aws_s3_bucket.b: Creating...
aws_s3_bucket.b: Creation complete after 3s [id=example.com]
aws_s3_bucket_website_configuration.c: Creating...
aws_s3_bucket_website_configuration.c: Creation complete after 0s [id=example.com]

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

ちゃんと実行できた。コンソールで内容を確認して問題ないことが確認できた。

routing_rules を指定してみる

aws_s3_bucket_website_configuration でリダイレクトルールを指定する場合
rouging_rule ブロックを使うか routing_rules に文字列を渡すかの二通りがあるんだけども、前者はココらへんの issueにもある通り replace_key_withreplace_key_prefix_with に空文字を指定したい場合に意図した動作にならない。なので後者の routing_rules を使う方向で実装する。
また、 main.tf に直接ヒアドキュメントで書き込むのも出来るけど、色々見通し悪くなりそうなので別ファイルにして読み込ませることにする。

ルールの内容はこんな感じ。 404 の場合にはトップページへリダイレクトするっていう良く見るやつ。

[
  {
    "Condition": {
      "HttpErrorCodeReturnedEquals": "404"
    },
    "Redirect": {
      "ReplaceKeyWith": "",
      "HttpRedirectCode": "307"
    }
  }
]

main.tf の変更はこうなった。

resource "aws_s3_bucket_website_configuration" "c" {
  bucket = aws_s3_bucket.b.bucket
  index_document {
    suffix = "index.html"
  }
+  routing_rules = file("routing_rules.json")
}

terraform plan してみるとちゃんと変更が反映予定になっているのが確認できる。

$ terraform plan
...
Terraform will perform the following actions:

  # aws_s3_bucket_website_configuration.c will be updated in-place
  ~ resource "aws_s3_bucket_website_configuration" "c" {
        id               = "example.com"
      + routing_rules    = jsonencode(
            [
              + {
                  + Condition = {
                      + HttpErrorCodeReturnedEquals = "404"
                    }
                  + Redirect  = {
                      + HttpRedirectCode = "307"
                      + ReplaceKeyWith   = ""
                    }
                },
            ]
        )
        # (3 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

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

続けて apply も実行して実際に反映させる。追加する場合は問題ない事が確認できた。

routing_rules 消してみる

次にさっき追加した routing_rules をコメントアウトしてみる。

resource "aws_s3_bucket_website_configuration" "c" {
   index_document {
     suffix = "index.html"
   }
-  routing_rules = file("routing_rules.json")
+  #routing_rules = file("routing_rules.json")
 }

apply した結果

$ terraform apply
...
No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

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

まさかの No changes 。

タイトルにもある問題はコレ。リダイレクトルールを削除したいのに反映されない。空文字列をつっこんでみても null つっこんでみても結果は同じ。
Terraform での S3 まわりの設定方法が過渡期っぽいのでそれの影響もありそうな気がしつつも、これが仕様なのか不具合なのかが判断できずでなんとも気持ち悪い :-(
これに関してはそれらしい issue も見つけることができなかったので、ちょっとあがいてみることに。

正解は "null" でした

null や空文字は Terraform 側で判断してなかったことにされてしまってるっぽいので、文字列としては評価されつつ最終アウトプットの JSON としては null となる "null" をつっこんでみる。

resource "aws_s3_bucket_website_configuration" "c" {
   index_document {
     suffix = "index.html"
   }
-  #routing_rules = file("routing_rules.json")
+  routing_rules = "null"
 }

apply してみると

$ terraform apply
...
Terraform will perform the following actions:

  # aws_s3_bucket_website_configuration.c will be updated in-place
  ~ resource "aws_s3_bucket_website_configuration" "c" {
        id               = "example.com"
      ~ routing_rules    = jsonencode(
          ~ [ 
              - { 
                  - Condition = {
                      - HttpErrorCodeReturnedEquals = "404"
                    }
                  - Redirect  = {
                      - HttpRedirectCode = "307"
                      - ReplaceKeyWith   = ""
                    }
                },
            ] -> null
        )
        # (3 unchanged attributes hidden)



        # (2 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
...
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

まさかとは思ったけども意図したとおりに反映された!コンソールで確認してもちゃんとリダイレクトルールが削除されてた。
もんにょりした挙動で時間も溶かしてしまったけども、なんとか解決策が見つけれてめでたしめでたし :-)

Discussion