Amazon Web Services ブログ

クルマのサブスク「KINTO」のアジリティとガバナンスを両立した DBRE の取り組み

本記事は KINTO テクノロジーズ のシニア DBRE エンジニア 粟田啓介氏によるゲスト投稿です。

KINTO テクノロジーズ (KTC) は、クルマのサブスク「KINTO」をはじめとしたさまざまなモビリティサービスを展開しているトヨタ関連グループ会社の一つです。

KTC では、モビリティサービスを提供する基盤として Amazon Web Services 上で Amazon Aurora 等のデータベースを多く運用しており、Database Reliability Engineering (DBRE) を組織として設立し、事業のアジリティとガバナンスを両立するための取り組みを実施しています。

このブログ記事では KTC DBRE による On-Demand な動的でセキュア、かつ利便性の高い踏み台サーバー構築の仕組みについて、検討のプロセスを含めて説明します。

データベース運用上の課題

KTC では、データベース運用を行う際に Amazon EC2 インスタンスで構築・運用している踏み台サーバーを利用しています。

オペレーションを行うユーザーは、専用の EC2 インスタンスに接続します。データベース接続に必要なパスワードは AWS Secrets Manager に保管されたシークレットから取得し、これらの情報を用いて Amazon Aurora データベースに接続します。実行されるオペレーションの監査ログは全て Amazon CloudWatch Logs に格納されます。

運用ガイドラインの改訂

KTC では、事業のフェーズと共に運用ガイドラインを強化してきました。その一部を下記にまとめています。

カテゴリ 概要
ログ
  • 行われたオペレーションが全て記載されていること
  • オペレーションを行なった個人を特定することが容易であること
  • ログの改竄ができないこと
ユーザー・パスワード管理
  • オペレーションに応じた権限が都度付与されること
  • 共通ユーザーを使用しないこと
  • パスワードには十分な長さと複雑さがあること
  • 定期的にパスワードが更新されること
アクセス管理
  • いつ、誰が該当作業を承認したのかがわかること
  • 作業完了後そのアクセスはできなくなること
脆弱性対応
  • 脆弱性への対応が速やかに展開されること

これらのガイドラインは文字だけ見ると当たり前のように見えますが、実際の運用に照らし合わせると完全に準拠するには難しいポイントがあります。

常時起動している EC2 インスタンス

基本的には一度立ち上げたら何か特別なことがない限り停止したりすることはしていません。この間に重大なセキュリティ脆弱性が発覚した場合、それぞれの EC2 インスタンスにセキュリティパッチを適用する等の対応が必要ですが、確実に適用されるかはユーザーオペレーションによる手作業に依存していました。

ちなみに KTC では Qualys という脆弱性診断・管理サービスを使用してこれらを判断しています。

共通ユーザーの利用

KTC ではこれまで共通ユーザーを利用してオペレーションを実施していました。そのため踏み台サーバーにログインできれば、誰でも強力な権限を使ってオペレーションが可能な状態になっていました。また MySQL では、監査ログには使用された DB ユーザーが記録されるため、全て同じ名前のユーザーによるオペレーションとして記録されてしまいます。オペレーションを行なった個人を特定するために CloudTrail や Session Manager ログとの突き合わせが必要になり、時間とコストがかかってしまう状態でした。

承認プロセスの欠落

Secrets Manager に格納されている共通ユーザーとパスワードを利用しているため、常時起動している EC2 インスタンスにログインできれば誰でも自由にデータベースに対してオペレーションできてしまうことになります。また、運用ガイドライン上承認者は全てのアクセスを認識している必要があり、その承認のプロセスを証跡として残しておく必要がありますが、実際の運用では確実にチェックできていると言い切れる状態ではありませんでした。

運用ガイドライン準拠への DBRE の取り組み

ガイドラインへの準拠に必要な上記の 3 つの課題を解決するため、以下のような仕組みを検討しました。

この仕組みでは、作業者が作業をしたいタイミングで Slack からリクエストを送信し、承認者の承認をトリガーとして踏み台用の EC2 インスタンスが自動的に構築されます。構築時には、データベース側にユーザーとパスワードが都度登録され、EC2 インスタンスでは yum update が強制的に実行され、セキュリティ管理にかかるユーザー作業を最小化するようにしています。作業完了時には (リクエスト送信時に指定した時間が経過したら) 構築した EC2 インスタンスは自動的に削除されます。

こうすることで KTC の求めるガイドラインに準拠できる環境ができると仮定しました。その上で、この仕組みをプラットフォームとして全社に横展開することで、会社の求めるガイドラインに全てのプロダクトが適合している状態を目指しました。

コードネーム

私たちはこのプラットフォームのコードネームを「PowerPole (如意棒) 」と名付けました。もともと KINTO の名前の由来は「必要な時にすぐに現れ、思いのままに移動できる「筋斗雲」のように使ってもらいたい」という思いを込めてつけられたものです。PowerPole は「ドラゴンボール」の中でカリン塔と神殿を繋ぎ、神殿に行くことを目的としたアイテムであったことから「データベースに対してオペレーションしたいユーザー」と「データベース (Amazon Aurora)」を繋ぐ、という意味を込めています。

責任分界点

続いて、プロジェクトを進めるにあたり、プロダクト組織と KTC DBRE の間で決めておくべき責任分界点を以下のように整理しました。

カテゴリ プロダクト組織の責任 KTC DBREの責任
コスト
  • オペレーションに必要な踏み台サーバーの稼働にかかるコスト
  • 踏み台を構築する時に必要な AWS サービスに関わるコスト
セキュリティ
  • 承認者はリクエストを送った人がそのオペレーションを行うに適切かどうかを判断する
  • リクエストを送る人はオペレーションを行うにあたって必要最低限の権限を必要最低限の時間でリクエストを送る
  • インスタンス作成後 DM で送られてきた接続情報は他のメンバーに共有しない
  • 構築される踏み台サーバーに対するセキュリティ更新
  • DB 接続に必要な情報はリクエストを送った人に送信された後、どこにも保存されない
  • 作成された DB ユーザーは作成された踏み台サーバーのみからしかアクセスできない
  • 行われたオペレーションのログが適切に保管されている
  • オペレーションの承認ログ等セキュリティ監査に必要な情報を提供する
リソース N/A
  • リクエストに応じて正しく踏み台サーバーが構築されること
  • オペレーションに必要な時間が完了したらデータベースに接続することができなくなること

必要な機能の洗い出し

プロジェクトを進める上で、どのように開発を進めるかは重要なポイントでした。まずは実現したいことを分解して必要な機能を洗い出しました。

  1. 作業者からのリクエストを Slack で受け付け、承認者にメッセージを送る機能
    • 対象の DB Cluster ID
    • 必要な権限 (READ / WRITE / ADMIN で分類)
    • 作業時間 (指定された時間を過ぎたら構築した EC2 インスタンスを Terminate する)
    • 作業開始時間 (今すぐ構築するまたは日時を指定できる)
    • 作業が必要な理由
  2. 承認者は内容を確認して承認か否認を選択する機能
    • 承認だった場合には EC2 インスタンスを構築
    • 否認だった場合には作業者にメッセージを送って終了
  3. EC2 インスタンス構築を行う機能
  4. 対象の Aurora MySQL に対して GRANT を発行する機能
    • GRANT で使用するユーザー名は Slack から送られてきたメールアドレスの @ より前を使用
    • パスワードはワンタイムで、送信されたユーザー以外に誰からも見られなくなる
    • パスワードは十分な文字列長と複雑さを備えたランダムな値を設定
    • 許可するホストは専用に構築された EC2 インスタンスの IP アドレスを指定
  5. 構築したことをお知らせする機能
    • メッセージにはユーザーがすぐに作業できるよう以下の情報を含める
      • SSM Login に必要な URL
      • MySQL 接続コマンド
      • MySQL 接続のためのパスワード
  6. 作成した DB ユーザーを削除する機能
  7. 構築した EC2 インスタンスを Terminate する機能
  8. いつ、誰が、どの Amazon Aurora に、どのような目的で PowerPole の利用を申請して、それをいつ、誰が承認したのかが分かる台帳としての機能

SLO 設定

開発開始前で精緻なものではありませんでしたが、自分達が目指す Service Level を早い段階で設定することは非常に有効でした。なぜならば、明確な目標に合わせた技術選定やアーキテクチャ設計を行うことができたからです。

私たちが実際に決めた SLO 設定は下記の通りです。

  • リクエストの構築成功率が 99% 以上であること
  • リクエストに応じて踏み台サーバーの EC2 インスタンスが 10 分以内に構築されること
  • リクエストの時間が過ぎた EC2 インスタンスとデータベース上に作成されたユーザーが 24 時間を超えて残っている状態にならないこと
  • 構築された踏み台サーバーに対するセキュリティパッチが最新化されていること

このようにかなり甘い定義ですが、それでもこれを意識するのとしないのでは運用設計を考慮した作りが大きく変わってきます。

使用する AWS サービスと開発言語の選択

AWS サービスの選択では、必要な時に必要な分だけ使用できる点や、少ないリソースを最大限活用するという理由から、可能な限り Serverless で実装することを最初から決めていました。その上で、実現したいことを考えて自分達に合う AWS サービスを一つずつ選択していきました。

  1. AWS Lambda
    • コンピュート層の管理が不要
    • 必要なときに必要なだけ処理が実行できる
      • 不要なときには何も起動しない
  2. AWS Step Functions
    • ワークフロー的に処理が流れていく
    • Sleep の機能は地味だが、Lambda 関数では実現できないので非常にありがたい
  3. Amazon DynamoDB
    • Step Functions で使用するステータスや変数管理のための利用
    • 起動毎に DynamoDB に格納することで台帳として十分に活用できる
      • 1 プロセス 1 行で格納し、その後は UPDATE のみ行う設計
  4. AWS Secrets Manager
    • ワンタイムパスワードの格納のための利用
    • 可能な限りシステムから読まれない状態を作る
      • Secret の Name をランダムな値で設定することで分かりづらく作成
      • EC2 インスタンスが構築できたらすぐに削除
  5. API Gateway
    • Slack からのリクエストを受け付け、Lambda 関数を起動するために使用
    • 最初は関数 URL を検討していたが、社内ルールにより API Gateway を使用する方式に方針転換した
  6. CloudWatch Logs
    • 監査ログや SSM Agent ログを適切に利用することでオペレーションの完全性を担保
      • 構築された EC2 インスタンス上で行われたオペレーションが保管されている
      • データベースに流れたクエリは全て監査ログに保管されている
      • ユーザー名が分かりやすいため、いつ、誰が、何をしたのか特定が容易
  7. AMI (Amazon Machine Image) の管理
    • 構築される EC2 インスタンスの起動時間を短縮するために下記を実施
      • データベースオペレーションに必要なパッケージをあらかじめインストール
      • 起動時の yum update にかかる時間を減らすために定期的に更新

開発言語に関しては、クラウドとの親和性やモダンな言語の習得というモチベーションから Go を選択しました。

最終的なアーキテクチャ

Monorepo 管理

上記の構成から分かる通り、このシステムでは複数の AWS サービスや Lambda 関数のコード等を管理しています。

開発自体はうまく行ったとしてもリリースの複雑さという点では非常に頭を悩ませました。そこで取り入れたのが Nx という Monorepo 管理ツールです。Nx を導入したことで、コード管理だけでなく、自分達で管理する AWS サービスの連携までのリリースフローをワンストップで実現することができ、劇的に生産性を上げることが可能となりました。私たちの管理するプラットフォームはいわゆる 3 ステージ制を採用しており、DEV 環境 → STG 環境 → PROD 環境の順番でリリースをしています。

GitHub Actions に Nx を取り入れることによって

  • develop branch へのマージ → STG 環境へのリリース
  • main branch へのマージ → PROD 環境へのリリース

を実現しました。ここでのリリースは Terraform の変更も含めたリリースとなります。

重要なポイントは、DEV 環境以外ではヒトの手が加わることは一切ない状態を作り出せたことです。この Monorepo 管理ツールの詳細は KTC の Tech blog で 「AWSサーバレスアーキテクチャをMonorepoツール – Nxとterraformで構築してみた!」として掲載していますのでぜひご覧ください。

課題の解決

このプラットフォームによって、当初の目的の KTC ガイドラインの準拠が達成できる状態になりました。

カテゴリ KTC ガイドライン PowerPole による対応
ログ
  • 行われたオペレーションが全て記載されていること
  • オペレーションを行なった個人を特定することが容易であること
  • ログの改竄ができないこと
  • CloudWatch Logs を活用して 監査ログ / SSM Agent ログを適切に利用
  • データベースのユーザー名を Slack のメールアドレスの @ より前を使用することで個人の特定が容易
ユーザー・パスワード管理
  • オペレーションに応じた権限が都度付与されること
  • 共通ユーザーを使用しないこと
  • パスワードには十分な長さと複雑さがあること
  • 定期的にパスワードが更新されること
  • オペレーションリクエスト時に必要な権限を申請
  • リクエストの度にデータベースにユーザー登録を行う
  • パスワードは要件を満たすためのプログラムで毎回ランダムに生成
アクセス管理
  • いつ、誰が該当作業を承認したのかがわかること
  • 作業完了後そのアクセスはできなくなること
  • 全てのプロセスを DynamoDB に保管
  • 作業完了後、データベースから使用したユーザーを削除
脆弱性対応
  • 脆弱性への対応が速やかに展開されること
  • EC2 インスタンスが構築されたタイミングで yum update を毎回実施

特にこだわったのは Slack App にインタフェースを寄せたことです。これまでは常時起動している EC2 インスタンスにログインすれば承認不要で実施できた作業が、作業リクエストと作業承認のプロセスを経て、さらにそこから専用の EC2 インスタンスを構築する処理が入ります。このストレスを減らすためにも Slack App から手軽に作業ができる状態を実現しました。また、踏み台サーバー構築完了時に Slack の DM に SSM Login URL や MySQL 接続コマンドを記載することで、すぐに作業開始できるような考慮もされています。

設定した SLO を満たせているか

現在のところ全項目で SLO を満たしている状態になっています。これらは下記の要素を監視することでデータを取得しています。

  • 踏み台サーバーが構築されるにあたって必要なプロセスの状態を監視する
  • 踏み台サーバーが構築されるまでの時間を監視する
  • PowerPole によって作成された踏み台サーバーが残り続けていないかを監視する
  • DB 上のユーザーが残り続けていないかを監視する
  • 定期的に踏み台サーバーに対するセキュリティチェックを行い脆弱性がないかを監視する

PowerPole によってリクエストが承認されてから EC2 インスタンスが構築されるまでの平均時間は 1 分程度です。これは嬉しい誤算でした。最初に SLO を定義したことで、開発段階でいかに効率的に EC2 インスタンスを起動するかを意識できたことで、適切に AMI を更新し、構築後の yum update にかかる時間を極力抑えるように設計できたことが大きかったと思います。

アジリティ vs ガバナンス

ガバナンスを強化するためにアジリティが犠牲になってしまうことはよくあることです。ただし、企業活動を行う上で ガバナンスを適用することは非常に重要です。

だからこそ KTC の DBRE は、クラウドを正しく活用し、ただガバナンスの適用を強要するのではなく、プラットフォームを通じてアジリティとガバナンスを両立する手段を Engineering という方法で提供しました。どのレベルまでこの両立を確保できるかが私たちにとっての腕の見せ所であり、存在意義の一つだと考えています。

DBRE プラットフォームを作る上での心構え

このシステムで実現していることは EC2 インスタンスを必要なときに構築するシンプルな仕組みですが、そこにDBRE としてのナレッジや経験と AWS の技術を組み合わせて「How の部分をモダンで楽しく開発すること」が私たちのスローガンです。

まとめ

KTC DBRE では、AWS を活用してデータベースの Reliability を向上させるためのプラットフォームの構築を進めています。データベースの知識や経験を現場のエンジニアに還元して KTC 全体の Reliability を守る、その手段として私たちは Engineering で解決する道を選択しました。

クラウドを適切に活用してアジリティを確保しつつデータベースのセキュリティとガバナンスを守る、そしてそれをプラットフォームへと昇華させ企業全体に展開することでビジネスに良い影響を与え続けることが重要です。

これが KTC なりの Database Reliability Engineering というアプローチです。

本記事は、AWS シニアソリューションアーキテクトの國政が担当しました。