バックアップデータがあると思って安心していたのに、いざ障害時に取得できていなかったことが発覚したり、ネットワークアクセスの制限を強化しようと設定をいじったら、自分すらアクセスできない状態にして手詰まりになったり……もっとヒヤッとする事態も含め、IT業界には「本当にあった怖い話」がいろいろある。

 クラウドサービスの利用料金がいつの間にかに膨大になる「クラウド破産」もその一つだ。検索してみると、便利だからとあれもこれもとクラウドサービスを利用していたら料金が想像以上に大きく膨らんでしまい、課金額を見て目を回した経験談がいくつかのブログにつづられている。

 システムインテグレーションやセキュリティサービスを提供するラックも、そんな経験をしてしまった企業の一つだ。同社のエンジニアである阿久津悠人さん(セキュリティソリューション統括部 ソリューション推進第二部 クラウドソリューションサービスグループ)は、AWSで構築した検証環境である設定ミスをしてしまった。

 その結果、1日1回行うはずだった処理が1分間に160万回発生してしまい、約300万円のコスト超過につながったという。事故はどんな原因で起こってしまったのか。当事者である阿久津さんや、対処に当たった土井秀記さん(同)、片桐貴之さん(同)、田端俊さん(セキュリティソリューション統括部 プラットフォーム・サービス第三部 エンタープライズITサービス第二グループ)に、インシデントの詳細と得られた教訓を聞いた。

●事件はエンジニアが自由に試せる「検証環境」で起こった

 まず、トラブルの背景を整理する。ラックによれば、昨今のクラウド化の流れを反映してか、クラウドサービスを活用したシステムインテグレーションの案件が増えているという。変化するニーズに応えるには、エンジニアも普段からクラウドサービスに触れ、最新の機能を自らの手で試して知見をためることが重要になる。

 そこで同社では、エンジニア向けにクラウド、例えばAWSの検証環境を用意し、自由に利用できるようにしてきた。「何かシステムを完成させる手前の検証環境というよりは、エンジニア自身が学習し、スキルを向上させたり、資格取得を支援したりするための環境として用意してきた」と土井さん。しかし今回のクラウド破産は、この検証環境で起こってしまった。

●1日1回の処理が1分で160万回超に 不幸が重なり起きた想定外の課金

 課金につながった処理を書いた阿久津さんによると、原因になった仕組みは、クラウドベースの認証サービスである「Okta」のログを、長期にわたって保管できないかというアイデアを形にしたものだった。サーバレス実行環境「AWS Lambda」で記述した処理は以下のような仕組みだ。

1. OktaからJSON形式のログを取得し、Amazon S3上に配置する

2. ファイルが配置されたことをログ取得サービス「AWS CloudTrail」で検知したら、それをフラグとしてアプリケーション間のデータを接続する「Amazon EventBridge」が起動し、Amazon S3に配置されたJSONファイルをCSVに変換する

 しかし、Amazon EventBridgeのルール設定に考慮漏れがあった。本来ならば除外すべきだった変換後のCSVファイルに対してもAWS CloudTrail側でファイル配置を検知し、フラグを立てるという動作を行ってしまった。

 「これが、無限ループの橋渡しの役割になってしまった」と阿久津さん。これにより、本来は1日1回行うはずだった処理が1分に160万回以上発生していたという。環境設定というよりは、オペレーション上の問題だったといえるだろう。

 状況をさらに悪くさせたのは、このロジックを試したのがゴールデンウイーク直前の4月28日だったことだ。「谷間の平日も含めて、休んでいるメンバーが大多数という状況だった」(土井さん)

 クラウド破産のリスクはたびたび指摘されており、ある程度経験のあるエンジニアなら当然考慮している。クラウド事業者側もそうしたニーズを踏まえ、課金に関するアラートを出す仕組みを用意している。

 ラックも1日1回、毎朝午前9時半に課金額を関係者に通知する他、想定外の費用が発生した場合にはアラートを出す仕組みを構築していた。平日ならば、PCや手元のiPhoneでそのアラートをチェックできたはずだった。しかし長期休暇に入ってしまったため、アラートに気付き、対処するまでに時間がかかってしまった。

 「4月29日からこのロジックが動き始めたが、ゴールデンウイークに入ってしまったため、課金情報をチェックする人がいなかった。結果として、5月4日の朝に届いた費用を見て初めて事態を把握した」(土井さん)

 5月2日時点では0円だった課金が、3日にはいきなり146万円に。この通知を受けて担当者が対応を開始した5月4日夕方の時点では約300万円の課金が確定した状況となっていた。「普段から金額をウォッチしていたが、大幅に金額が跳ね上がっている状況を見て、まずは対応を進めなければと考えた」(田端さん)

●備えはしていたはずなのに それでも事故が起こった理由

 ただ、ラックも今回起きたようなトラブルを想定していなかったわけではない。同社はセキュリティサービスを手掛けてきた経験を基に、コスト超過やセキュリティインシデントについて、有事を想定した対策をしてきたという。

 例えばコスト超過に対しては、アクセス管理サービス「AWS Service Control Policies」を活用。機械学習などであまりに多くのデータを処理して課金額が跳ね上がりそうな場合は、相談の上で可否を判断し、セキュリティとコストの観点を加味しながら対応していた。

 セキュリティも同様だ。検証環境でもAWSのセキュリティ機能「Amazon GuardDuty」「Security Hub」などを活用。設定ミスなど、本来あるべき設定からの逸脱があれば把握できる仕組みを整えていたという。

 「例えば、未熟なエンジニアがAWSを使う際に、インターネットに向けてポートを無制限に開放してしまうようなネットワーク設定を入れてしまった場合にはAmazon GuardDutyやAWS Security Hubで検知し『今、無制限のアクセスが設定されています』といった通知が入るようになっている。これを受けて、設定を改善するようアナウンスすることで、自由にさせつつ締めるべきところは締めてきた」(土井さん)

 セキュリティチームでは週に1回、定例会を実施。Amazon GuardDutyやAWS Security Hubのログをメンバー内で確認して、どれは問題ないか、どれはリスクがありそうかといった事柄を話し合っていた。大量のアラートの中から深刻なものとそうでないものを切り分けられる体制も整えていたという。

 ただ、あまりに規則をガチガチに固めてしまうとエンジニアの自由度が失われ、新機能をスピーディーに検証したくてもできない事態になりかねない。「セキュリティは絞りつつ、でも、エンジニアの『やりたい』には応えていきたいというのが管理者チームの希望」(土井さん)。

 そこで、検証環境に限っては本番システムやその検証システムで行うゲートレビュー(次工程への移行に際するチェック工程)を省き、スピード感を担保する方針で運営していた。ただ、今回の事故はこの方針が裏目に出てしまった。

●不幸中の幸いで切り分けは迅速に、事前のセキュリティ対策が奏功

 事故の発生後、管理チームが最初に疑ったのは課金を通知するツールの不具合、そして、セキュリティインシデントの発生だった。

 「まずセキュリティインシデントを疑った。機密情報や顧客情報は一切保存していなかったが、何者かに侵入され、外部のWebサイトにDDoS攻撃が行われてしまった可能性や、マイニングなど他の処理が動いてしまったのではないかという可能性を考えた」(土井さん)

 しかし前述の通り、検証環境チームではセキュリティに関してはあらかじめ対策を施していたことから、セキュリティに問題があった可能性は低かった。週に1回の定例ミーティングの場で定点観測を行っていたこともあり、確認すべきデータもそろっていたという。

 「前週と比較しても、セキュリティ的に何も大きなイベントが起きているようには見えなかった。5月4日を中心にログイン履歴を確認しても不正なログインをされた痕跡はなかったことが確認できたので、早いタイミングで、セキュリティインシデントの可能性は非常に少ないと判断し、切り分けることができた」(土井さん)

 次に確認したのは、AWSのサービス別の利用料だ。ここでAmazon S3とAmazon CloudWacth、AWS CloudTrailの課金が多く、さらに前月に比べAWS Lambdaの稼働状況が非常に多いことが判明。調査を進め、問題のロジックにたどり着き、対処につながったという。

 「エンジニアが自由に技術検証ができる基盤を運営していくのがわれわれの役割であり、各ロジックの中身までは立ち入っていなかった。ただ、これが原因だろうというのは早いタイミングで把握できた」(土井さん)

●ミスは起こることを前提に、素早く気付き、対応する仕組み作りを

 今回の大量課金事件を踏まえてラックではさまざまな角度から振り返りを行い、どうすべきかを議論したという。結果として、ロジックの実装だけでなく、システム運用にも不備があったと捉えている。

 「まず、休日にかかわる時期のチェック体制がなかったことが反省点として挙げられる。休日でも異常に気付き、のろしを挙げる対応が必要だろうと考えている。またロジックについては、意図しない無限ループを起こさないよう、有識者による技術的なレビューを行うべきだった」(土井さん)

 「コストのチェックは1日に1回行っていたが、その1日で一気に数十万から100万円を超える課金が行われてしまうと手の打ちようがない。そこでAWS CloudTrailを用いてAPIの実行回数を把握・可視化し、想定外の何かがぐるぐる回っているような事態が起きた場合には通知する仕組みを入れた」(土井さん)

 そもそも、原因が社員向けの技術検証環境であり、重要なデータが何もなかったことから「何かが起きる」ことを想定していなかったのが根本的な問題だった可能性もある。「今回の事故を防げるポイントはいくつかあったと思う。ただ、やはりそういったミスは起きるものだと想定した上で準備していかなければいけない」(土井さん)

 一方で、Amazon GuardDutyでの監査や、AWS Security Hubによってアクセス元のIPアドレスを制限するといった従来の施策が無意味だったわけではない。原因を早期に切り分ける上で役立ったと片桐さんは振り返る。

 今後はさらに、「CSPM」(Cloud Security Posture Management、クラウドサービスの設定を管理し、ミスがあったときに通知するツール)と呼ばれるソリューションの活用も検討している。設定の妥当性を検証したり、アカウント管理や新規サービス利用時の手順・プロセスを標準化したりし、運用が適切かどうか見ていくような仕組みも重要と考えているという。

 「これで十分かといわれると難しいが、やれるところはやってきた。今後も同じようにやっていく」(土井さん)

 トラブルに見舞われたラックだが、クラウド利用を萎縮させたり、利用環境に制限を加えたりといった対応はしない方針という。セキュリティインシデントと同様に、事故を起こした人を責めるのではなく、報告したことに感謝し、問題を改善して再発防止に取り組む動きを追求していくとしている。

 「未熟なメンバーであってもそれを守れる仕組みを整え、エンジニアのやりたいことがやれるよう、ひいてはクライアントのためになるエンジニアを育てていきたい」(土井さん)