今年のやらかしを供養する

# はじめに

はじめまして、medibaバックエンドエンジニアの@tmkinoueです。
本記事は「[mediba Advent Calendar 2022](https://qiita.com/advent-calendar/2022/mediba)」4日目の記事です。
年の瀬ということで今年の振り返りをしようと思いますが、仕事のことでまず思い出すのはやらかしたことの記憶でした。ここで記事にしてやらかしを供養したいと思います。


# ① TerraformでCloudFrontの設定変更したときのやらかし

## 環境

Terraform 0.14.11

## 背景

担当しているサービスのフロントエンドサーバーでの新規ページ追加の案件でした。
優先順位の関係で新規ページのビヘイビアを既存のビヘイビアの間に追加しなければいけなかったため悲劇は起こりました…


## 起こった事象

問題が起こったのは追加したビヘイビアではなく、それより下の優先順位に設定していた既存ビヘイビアのページでした。
S3に静的ファイルで設置されているLPのようなページだったのですが、そのビヘイビアに意図しないヘッダー設定がされてしまったため、ページにアクセスできなくなってしまいました。[^1]

[^1]: 今回はTerraformの話をしたいので詳細は割愛しますが類似事例の記事をリンクしておきます 
[CloudFrontのS3 Originにはhostヘッダーを転送してはいけない](https://techblog.kayac.com/do-not-use-cloudfront-s3-origin-with-managed-all-viewer)

## 原因

意図しないヘッダー設定がされてしまったのはTerraformの仕様によるものでした。

Terraform上でヘッダーの設定はOptionalになっています。[^2]

[^2]: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution#headers

アクセスできなくなったページのもともとのビヘイビアにはヘッダーを何も設定していないため、Terraformのコード上ではそのビヘイビアにはヘッダーのパラメータ自体を記載していませんでした。
その結果、CloudFrontに残っている上書き先のビヘイビアのヘッダー設定がそのまま残る形になってしまい、意図しないヘッダー設定がされてしまいました。

## 解説

実際の変更内容は異なりますがこんな感じのコード差分と思っていただければ。

```
+  ordered_cache_behavior {
+    allowed_methods = ["GET", "HEAD"]
+    cached_methods  = ["GET", "HEAD"]
+
+    forwarded_values {
+      cookies {
+        forward = "all"
+      }
+
+      headers = [
+        "Host",
+        "Origin",
+        "Referer",
+      ]
+      query_string = true
+    }
+
+    path_pattern           = "/hoge/*"
+    target_origin_id       = "OriginA" 
+    viewer_protocol_policy = "redirect-to-https"
+  }
  
  ordered_cache_behavior {
    allowed_methods = ["GET", "HEAD"]
    cached_methods  = ["GET", "HEAD"]

    forwarded_values {
      cookies {
        forward = "all"
      }

      # headersは何も設定しないため記載なし
      query_string = true
    }

    path_pattern           = "/fuga/*"
    target_origin_id       = "OriginA"
    viewer_protocol_policy = "redirect-to-https"
  }

  ordered_cache_behavior {
    allowed_methods = ["GET", "HEAD"]
    cached_methods  = ["GET", "HEAD"]

    forwarded_values {
      cookies {
        forward = "all"
      }

      headers = [
        "Host",
        "Origin",
        "Referer",
      ]
      query_string = true
    }

    path_pattern           = "/piyo/*"
    target_origin_id       = "OriginA"
    viewer_protocol_policy = "redirect-to-https"
  }

```

このようにTerraformでビヘイビアを既存のものより高い優先順位に追加しました。
このとき`terraform plan`で差分を確認すると、
```

      ~ ordered_cache_behavior {
          ~ path_pattern           = "/fuga/*" -> "/hoge/*"
            # (11 unchanged attributes hidden)

          ~ forwarded_values {
              ~ headers                 = [
                  + "Host",
                  + "Origin",
                  + "Referer",
                ]
                # (2 unchanged attributes hidden)

                # (1 unchanged block hidden)
            }

            # (1 unchanged block hidden)
        }

      ~ ordered_cache_behavior {
          ~ path_pattern           = "/piyo/*" -> "/fuga/*"
            # (11 unchanged attributes hidden)


            # (3 unchanged blocks hidden)
        }
      + ordered_cache_behavior {
          + allowed_methods        = [
              + "GET",
              + "HEAD",
            ]
          + cached_methods         = [
              + "GET",
              + "HEAD",
            ]
          + compress               = false
          + min_ttl                = 0
          + path_pattern           = "/piyo/*"
          + target_origin_id       = "OriginA"
          + viewer_protocol_policy = "redirect-to-https"

          + forwarded_values {
              + headers                 = [
                  + "Host",
                  + "Origin",
                  + "Referer",
                ]
              + query_string            = true
              + query_string_cache_keys = (known after apply)

              + cookies {
                  + forward = "all"
                }
            }
        }
```


このように既存のビヘイビアを上書きしていき、優先順位が一番下のビヘイビアが新規追加という形になります。
既存のビヘイビアが上書きされる形で変更がある部分だけ差分として表示されますが、ここで注目したいのは
```
          ~ path_pattern           = "/piyo/*" -> "/fuga/*"
```
の部分。`/fuga/*`はヘッダーに何も設定したくないのに`headers`の記載がないため変更されずに`/piyo/*`の設定
```
      headers = [
        "Host",
        "Origin",
        "Referer",
      ]
```
を引き継いでしまい、差分なしのため`terraform plan`で確認した際に表示されていません。

説明のため簡略化していますが、実際には複数のシステムがオリジンとなっており、ビヘイビアの数もたくさんあります。オリジンごとに設定も異なるので、高い優先順位にビヘイビアを新規追加すると大量の差分が出ていたので、問題が起こる前に気づくことができませんでした。


## 対処方法

ヘッダーを何も設定しない場合は、以下のようにTerraform上で記載することで、ヘッダーに何も設定しない状態でビヘイビアを上書きしてくれます。[^3]


[^3]:参考：https://github.com/hashicorp/terraform-provider-aws/issues/19675

```
headers = []
```

こちらの設定を行い対応しました。


# ② EKSで稼働中のシステムを新規クラスターに移行したときのやらかし

## 背景

担当しているサービスでは2020年初頭に一部のシステムのリプレイスを行い、フロントエンドはEKS上で稼働するNuxt.js、フロントエンド及びスマートフォンアプリからリクエストされるAPIサーバーとしてEKS上で稼働するGo言語のアプリケーションという構成になっていました。
2年ほど運用を続けていく中で人員の入れ替わり等もあり、3ヶ月に一度ほどのペースで発生するEKSのサポート終了に合わせてKubernetesのバージョンを一つずつバージョンアップする対応を、通常の開発案件と並行して行っていくのがきつくなっていました。
そこでEKSクラスター新規に作成しなおし、一気に最新のKubernetesバージョンにジャンプアップすることでEKSのサポート終了への対応頻度を減らすことを試みました。
結果として新規クラスターへの移行はうまくいったのですが、その後旧クラスターの後片付け(削除)をしたときにやらかしました…

## 起こった事象

権限周りの設定で、`eksctl`コマンドで作成した際に作られたIAM Roleをそのまま新規クラスターで利用するように設定してしまっていました。
`eksctl`コマンドで旧クラスターを削除した際にIAM Roleも削除してしまい、データベースやその他利用しているAWSサービスに接続できなくなり、サービスが利用できない状態となりました。

## 原因

技術的な話より、チームの組織的な課題が主だと思うので詳細は割愛しますが、一般に公開できる反省点として一つ挙げられるのはスケジュール設定の問題でしょうか。
新規クラスターへの移行対応がEKSのサポート終了期限ぎりぎりとなり、その後の旧クラスター削除対応はEKSのサポート終了後となりました。そのため、旧クラスターで利用していたバージョンでは新規にクラスターを作成できなくなっており、検証環境でクラスター削除してしまうことの抵抗感から削除対応の検証が充分にしなかったことが反省点です。


## 対処方法

緊急対応として、手作業で同様の権限を持ったIAM Roleを作成し、サービスを復旧。
その後Terraformに取り込み、Terroform上で管理し`eksctl`コマンドの裏で実行されているCloudFormationの管理下から外すことで`eksctl`コマンドの影響を受けないようにし、IAM Roleを使い回せるように対応しました。

# 終わりに

上記2つのやらかしは一ヶ月も空かずに起こった出来事でした。良くないことが続く時期だったので会社の同僚とITに関するご利益があると言われる神田明神にお参りにも行きました。
ご迷惑をおかけした方、お世話になった方、その節はどうもありがとうございました。

来年はこのお題目で記事を書かなくて良い一年になることを願っています。