システム障害のおわびとまなび

はじめに

こんにちは、freee株式会社でCDO(最高開発責任者)をしている平栗です。 2018年10月31日に、freeeで起こしてしまったシステム障害について、その原因と対策、障害からの学びについて共有したいと思います。 この記事はfreee Developers Advent Calendarの22日目になります。

おわび

まず、約2時間半にわたりfreeeの全サービスを停止し、皆様に多大なるご迷惑をおかけしましたことを、改めてお詫び申し上げます。 今回の障害を大きな学びと成長の機会とし、今後の再発防止と業務改善に取り組んでまいります。

障害の経緯

2018年10月31日12時34分~15時00分の2時間26分の間、freeeの全サービスを一時停止し、すべてのサービスがご利用できなくなりました。 以下、復旧までの経緯です。

  • 11時24分 特定の機能が利用できなくなっていると、社内から不具合報告があがり、エンジニアチームで調査を開始
  • 11時30分 サポートチームからも、お客様から問い合わせがきていると共有
  • 11時56分 多くのリリースフラグ(リリースフラグについては後述)がオフになっていることに気づく
  • 12時34分 リリースフラグオフが原因と判断し、ただちに影響範囲を把握することが困難であったため、お客様のデータ保護のため全サービスを一時停止
  • 15時00分 影響範囲調査の結果、お客様のデータの毀損・漏洩がないことを確認し、サービスを再開

お客様のデータへの影響

お客様のデータ保護の観点からサービスを停止しましたが、変更されたリリースフラグの影響をすべて調査した結果、お客様のデータの漏洩・毀損等は一切ございませんでした。

リリースフラグとは

リリースフラグとは、システムの機能オン/オフを機動的に切り替えるための仕組みで、主に新機能のリリース管理に利用しています。 リリース直後の機能について不具合があった場合に、再度デプロイ作業をすることなく、システムの管理画面上から機動的にフラグをオフにして即座に切り戻すことができます。 基本的には、新しい機能が使えるかどうか以外システムへの影響はなく、リリースフラグはオンでもオフでもシステムは正常に作動するように設計されています。

障害の原因

システム障害の最初の原因は、リリースフラグ変更作業上のオペレーションミスでした。それにより意図せず多くのリリースフラグがオフになってしまい、お客様のデータへの影響がないと即座に判断することができず、データ保護を最優先に考え、サービスを一時停止しました。

原因の深掘りと対策

なぜオペレーションミスが起こったか

前述の通り、リリースフラグ自体は、本来オンでもオフでもシステムは正常に動作するように設計されています。リリースの切り戻しをより素早く行えるよう、システムの管理画面上で簡単に変更できるようにしていました。

具体的には、管理画面上ではリリースフラグが一覧表示になっており、フラグを変更するボタンをクリックして確認するだけで、変更可能でした。 意図したリリースフラグと一行ずれたものを押してしまうミスが起こりやすい状態になっていました。 対策として、一覧画面での変更をやめ、個別のリリースフラグの画面に遷移した上で変更をするようにし、変更する際にはリリースフラグの名前の入力をするようにしました。

オペレーション上も、リリースフラグの誤操作によるリスクは低いと考えていたので、作業時の確認を徹底するフローができていませんでした。 これに関しては、フォーム画面に必要事項を入力すると、作業上の注意項目がのった手順書が自動で作成される仕組みをつくり、月次モニタリング運用を行うことにしました。 また、手順書をつくる対象作業の見直しとその結果の周知も実施しました。

リリースフラグ自体は、今後も素早い切り戻しのために必要だと考えていて、その中でいかにミスの起こりにくい仕組みを実現できるかが難しいポイントだと思っています。 今後運用していく中で、リスクを適切に評価しながら改善していきたいと思っています。

なぜ影響範囲を即座に判断できなかったか

繰り返しになりますが、リリースフラグ自体は、本来オンでもオフでもシステムは正常に動作するように設計されています。それなのに影響範囲をすぐに判断できなかったのは、以下の3点がネックになったからでした。

1点目は、意図せずオフになったフラグが多かったことです。数が多いことで、すぐに影響範囲を正確に判断することが難しくなっていました。

2点目は、どのフラグがオフになったのかすぐにわからなかったことです。リリースフラグの変更はリスクが低いと考えていたこと、頻繁に操作するものではなかったことから、どのフラグがいつ・どう変更されたのかが、管理画面上ですぐわかるようになっていませんでした。activity_logや、直前のDBの状態を調べる必要がありました。

3点目は、古いリリースフラグが残っていたことでした。リリースフラグは主にリリース直後の切り戻しに使うのですが、リリース後経過観察をした上で削除する場合もあり、そのまま消されずに残っていたものが多くありました。そして負債化し、そのフラグの影響範囲を読むことが難しくなっていました。

対策として、1点目については、リリースフラグの大掃除大会を実施し、リリースフラグの数を大幅に減らすことにしました。数年間の負債が溜まり続けた結果、簡単に終わる作業ではないですが、障害を契機にエンジニアチーム全体で取り組んでいます。

2点目については、リリースフラグが変更されたときに、変更ログを自動的に社内SNS (slack) に飛ばす仕組みを作り、変更履歴をすぐに追えるようにしました。

3点目については、リリースフラグの管理体制を作ることにしました。リリースフラグの目的、残存期間の目安、期間を超過した場合のアクション、残存させ続ける条件等を定め、月次モニタリング運用に組み込むことにしました。

障害からのまなび

障害からの大きな学びは、開発上のリスクをサービスの成長とともに適切に評価しなおしていくことの大事さと難しさでした。 今回のシステム障害の原因となったリリースフラグでは、使いだした当初は障害につながるリスクは低いと思っていましたが、数年たつうちに、あっという間にリリースフラグもそれを扱うエンジニアも大きく増え、潜在的にリスクが増していました。 リリースフラグだけでなく、サービス全体としても、ユーザーさんの数、ユーザーさんの質、扱うデータの性質がどんどん変化していく中で、それらの変化を適切に捉えた上で、開発全体のリスク評価をしなければいけません。

10月31日のシステム障害から2ヶ月がたち、障害の原因分析とすぐに行う対策の完了に目処がついてきたので、来月からは改めて開発全体のリスクの再評価に取り組む予定です。 社内においてこれまで見落としてきたリスクがなぜ見落とされたのかを分解整理しつつ、社外の知見も借りながら、年単位で開発プロセスを振り返り、リスクを最小化していく努力を続けていきたいと思っています。

最後に

重ねて、利用者の皆様にシステム障害によりご迷惑、ご心配をお掛けしましたことをお詫び申し上げるとともに、お客様への価値を安全に、かつ最大最速で届けられるようfreeeの開発体制を進化させ続けていきたいと思います。

つきましては、freeeの開発基盤を進化させていくエンジニアを募集しております。 興味があれば、ぜひご連絡ください!

jobs.jobvite.com

明日は、freeeの銀行同期基盤を支えるgoエンジニア、しみっちょです!