はじめに
はじめまして、medibaバックエンドエンジニアの@tmkinoueです。
本記事は「mediba Advent Calendar 2022」4日目の記事です。
年の瀬ということで今年の振り返りをしようと思いますが、仕事のことでまず思い出すのはやらかしたことの記憶でした。ここで記事にしてやらかしを供養したいと思います。
① TerraformでCloudFrontの設定変更したときのやらかし
環境
Terraform 0.14.11
背景
担当しているサービスのフロントエンドサーバーでの新規ページ追加の案件でした。
優先順位の関係で新規ページのビヘイビアを既存のビヘイビアの間に追加しなければいけなかったため悲劇は起こりました…
起こった事象
問題が起こったのは追加したビヘイビアではなく、それより下の優先順位に設定していた既存ビヘイビアのページでした。
S3に静的ファイルで設置されているLPのようなページだったのですが、そのビヘイビアに意図しないヘッダー設定がされてしまったため、ページにアクセスできなくなってしまいました。1
原因
意図しないヘッダー設定がされてしまったのはTerraformの仕様によるものでした。
Terraform上でヘッダーの設定はOptionalになっています。2
アクセスできなくなったページのもともとのビヘイビアにはヘッダーを何も設定していないため、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
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に関するご利益があると言われる神田明神にお参りにも行きました。
ご迷惑をおかけした方、お世話になった方、その節はどうもありがとうございました。
来年はこのお題目で記事を書かなくて良い一年になることを願っています。
-
今回はTerraformの話をしたいので詳細は割愛しますが類似事例の記事をリンクしておきます
CloudFrontのS3 Originにはhostヘッダーを転送してはいけない ↩ -
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution#headers ↩
-
参考:https://github.com/hashicorp/terraform-provider-aws/issues/19675 ↩