OpenWork Tech Blog

社員クチコミサービスを運営しているオープンワークエンジニアによるテックブログです。

今年やらかしたこと 2022 (インフラ・エディション)

インフラチームの小川です。

密かにシリーズ化を企んでいるやらかし記事です。各々のもやもやを供養するとともに、改めて再発防止に努めたいという想いを込めて記事化します。

techblog.openwork.co.jp

今年はインフラにまつわるお話を 3 本ご紹介します。

開発環境のテストによって本番バッチが一部起動できなくなった

事象

開発環境での負荷テストによってバッチ処理が 1000 件ほど同時に行われた。これにより、本番環境のバッチが一部起動できなくなった。

原因

まず、以下のような前提がある。

  • 各バッチは独立した Fargate タスクとして動く
  • タスクの起動に必要な秘匿情報を、 SSM Parameter Store から取得している
  • 開発と本番の各リソースが同じ AWS アカウント上にある

今回、比較的イレギュラーな負荷テストにより大量のメール送信バッチを起動したことで、Parameter Store のスロットリングが生じてしまった。スロットリングにより Fargate タスクが起動できなくなった。

加えて開発と本番が同じアカウント上にあるため、結果として本番バッチも起動できない瞬間が生じてしまった。

起動できなかったバッチはのちほど再実行を実施してリカバリ。

再発防止策

開発と本番で AWS アカウントを分ける。

編集部コメント

開発環境だからと安心してテストしたところ、本番環境に影響が出てしまった案件です。特にスロットリングはどこで発生するかが読みにくく厄介です。 AWS アカウントの未分離による問題は去年も発生していたこともあり、いよいよ今年は分離に着手していく予定です。

弊社の場合、1 アカウントで巨大なアプリケーションを構成しているため膨大な作業が想像されますが、より健全な AWS 環境に変えていくため意を決し手を入れていきます。

膨大な AWS 料金を発生させた

事象

本来不要な ECS Fargate タスクが 100 件超・数日間起動し続けて、無駄な AWS 料金を発生させてしまった。

原因

通常、アプリケーションは自動化されたパイプラインでリリースされるが、これは追加で手動対応が必要なリリースを行った際に発生した事象。 直接的にはリリース時の手順に不備があったためにやらかしたことだが、長時間動作しているタスクが存在することを検知できなかったことも問題だった。

再発防止策

  • AWS Budget アラートの設定: 高額料金の発生を検知できるようにした
  • ECS タスク起動時のタイムアウト追加: 意図しない長時間実行が発生しないようにした
  • リリースフローを改善する(仕掛り): 手順ミスが発生しないように自動化する

編集部コメント

監視・通知の大切さを実感させられる一件です。AWS サポートの方とも相談しながら、再発防止策を決めていきました。

クレデンシャルの無効化によってリリースが失敗するようになった

事象

厳密には 2023 年の出来事となってしまうが、この記事を書いているときにやらかしてしまったため追加。

利用中の SaaS でセキュリティインシデントが発生したため、関係する GitHub のクレデンシャルを無効化したところリリースパイプラインが動かなくなった。

原因

プロダクトのリリースに利用している CodePipeline は、GitHub からソースコードをチェックアウトする。そのための GitHub トークンを無効化させてしまったことが原因。

前もって以下のようなコマンドで影響範囲の洗い出しを行い、ヒットした CodePipeline については新しいトークンに切り替えを行っていた。

# Terraform のリモートステート (S3) から tfstate の一覧を作成し、トークンを grep
for f in $(aws s3 ls s3://<Remote State Bucket>/ --recursive | grep .tfstate | awk '{print $4}'); do
  aws s3 cp s3://<Remote State Bucket>/$f - | grep '******1234 (Token Value)' && echo "  <- $f"
done
                      "OAuthToken": "******1234",
  <- foo/bar/terraform.tfstate
       :

だが、tfstate に生のトークンが記載されるのは最新の AWS Provider における挙動で、古い AWS Provider (恐らく v3.24.0 未満) は hash-*** のようにハッシュ化された値を tfstate に残していた。この影響で上記 grep での洗い出しに漏れが生じ、今回の問題が起こった。

再発防止策

検討中。洗い出し方法に不備がないかどうかを証明するのは難しい。

他方、CodePipeline の GitHub 連携は今回のような OAuth Token を用いる v1 ではなく、 Codestar Connection を使った v2 が現時点では推奨されている。これを用いることでトークンを利用せずの連携が可能となるため、既存の CodePipeline は v2 に置き換えていきたい。

編集部コメント

様々なサービスと連携しているとその分だけクレデンシャルの管理量も増えてきます。「クレデンシャルの無効化をしなければならない」という状況にいざ陥ったときのことを想定して、シナリオを思い描けていると安心かもしれません。

むすび

システムが複雑化・高機能化すればするほど「やらかし」の魔の手が伸びてきます。インフラチームも大小様々なシステムを管理するようになりました。チームメンバー全員が全システムの細部まで理解することはきわめて難しいです。シンプルにシステムを構築していくのは当然ですが、伝え方、すなわちドキュメントの書き方も磨いていかねばなと感じている今日このごろです。

良いシステム、良いドキュメントについて一緒に考えてみませんか。

www.openwork.co.jp