Recovery)対策kameこんにちは!かめでございます。CognitoのユーザプールのDR対策に関して検討する機会がありましたので、ご紹介します。今回、あるプロジェクトでのDR要件として、near-0のRPO(目標復旧時点)が求められるケースがありました。そのプロジェクトは認証機構を用いるのですが、プロジェクトの制約でクラウドプロバイダーとしてはAWSしか利用できないという制約があり、認証機構としてはCognitoを利用する前提となっていました。Cognitoはバックアップやクロスリージョンレプリケーションのような仕組みは標準では提供しておりません。そのため今回は、near-0のRPOを実現するために、準リアルタイムでのユーザープールバックアップ&レストアを行えるような仕組みを検討してみました。リファレンスアーキテクチャ」を試してみる」も公開されています。こちらのアーキテクチャについてざっくり言うと、Congitoユーザープールに登録されている全ユーザー情報を定期的にダンプし、別リージョンで復旧することができるようになっています。今回目標とするnear-0でのRPOを目指すためには、ユーザー数が多い状況で全ユーザ情報をダンプする方法では満たせないため、別の手段を検討しました。リファレンスアーキテクチャ」を試してみる」に記載の制約と同等の、以下の制約が存在しますので、要件に応じて採用可否の検討を行ってください。リファレンスアーキテクチャ」を試してみる」より_以下の場合、このソリューションを用いたバックアップは行なえません。ユーザープールで多要素認証が有効になっている場合。メールと電話番号の両方が許可されている場合。ユーザーのパスワードをエクスポートする機能を提供しないため、パスワードはバックアップされません。リストアされたユーザープールを使用する際には、ユーザーにパスワードをリセットしていただくようご依頼ください。属性を対応させる必要があります。属性の対応関係を確認するために利用できます。経由で登録されたユーザー情報のみバックアップできます。サードパーティの認証(ソーシャルログイン)を使用して登録されたユーザーの情報はバックアップされません。ソーシャルログイン経由で登録されたユーザーは、リストア先のユーザープールに切り替わった段階で再度ログインしていただくようご依頼ください。プロバイダーの設定も引き継がれないため、リストア先のユーザープールでバックアップ元と同様に設定してください。ユーザープールのアドバンスドセキュリティ機能をご使用の場合、ログイン履歴はバックアップされません。ロールの情報はバックアップされません。記憶済みデバイスの情報はバックアップされません。上記に加えて本サンプルコードでは以下の制約が発生します。成功してもバックアップが完全にそれに同期している保証はありません。Congitoにユーザーがサインアップ成功してから、LambdaがDynamoDBに情報を書き込むまでの間に障害等が発生し、書き込みが不可能となった場合に、データの欠落が発生します。リファレンスアーキテクチャ」のフルバックアップと組み合わせて利用するのが望ましいかと考えていますが、どう組み合わせるのがベストなのかは考えてみようかと思っています)Cognitoにおけるメールアドレス変更処理に関しては、以下のブログに記載の通り、メールアドレス変更後にログインできなくなるという現象が発生します。この現象を回避するためには、変更後のメールアドレスの検証処理を自前で構築しないといけませんが、今回の例ではその処理を省略しているため、ご注意ください。APIの認証処理は省略しています。ワークロードの認証機構に併せて実装ください。準リアルタイムでのバックアップを実現するための仕組みは、フルバックアップのリファレンスアーキテクチャから比べると構成としてはかなり単純なものになります。確認後のLambdaトリガーにLambdaを登録することで、サインアップが完了したユーザの情報がリアルタイムで得られるので、ユーザがサインアップしたタイミングでユーザ個別でのバックアップを行うことができるという点になります。このトリガーで得られた情報をDynamoDBグローバルテーブルを用いて即座にユーザーデータをバックアップリージョンへ転送します。ユーザープールへのデータ復旧につきましては、要件によってはバックアップリージョンへの切り替えタイミングで一括で行えば良いケースも多いと思いますが、今回の例では、バックアップリージョン内のCognitoユーザープールへのデータ復旧もリアルタイムで実施しています。StreamsにてLambdaをトリガし、データ変更内容をバックアップリージョンのCognitoユーザープールへと復旧します。APIを作成し、ユーザ情報更新/削除を行うようにしています。IaCソースコード今回はCDKを用いてインフラストラクチャーを展開するためのコードを作成しました。メインリージョンはus-east-1、バックアップリージョンはap-northeast-1としています。--allでデプロイを行ってください。動作確認サインアップまず新規ユーザとしてサインアップを行ってみましょう。今回メインリージョンで作成したCognitoにアクセスし、MainUserPoolを選択します。次にユーザープール内の「アプリケーションの統合」タブを開いたときの下部に、作成されたアプリケーションクライアントが表示されていますので、これを選択します。「ホストされたUI」の項目内に「ホストされたUIを表示」ボタンがありますので、これをクリックします。その後サインアップ画面で適切な情報を入力し、サインアップを実行します。その後サインアップ時に指定したメールアドレスに確認用メールが来るため、確認処理を実行してください。サインアップが完了したら、ユーザープールにユーザーが作成されていることを確認してください。新規ユーザー情報はDynamoDBのus-east-1/ap-northeast-1リージョンのテーブルにもレコードとして記録されていることが確認できます。バックアップリージョンのCognitoユーザープール(BackupUserPool)にも同様の情報でユーザーが復元されています。制約でも申し上げたとおり、メインリージョンで設定されたパスワードはバックアップできないため、バックアップリージョンのユーザープールでサインイン処理を行う場合はパスワードリセットが必要になります。APIを作成しています。Gateway内に「userConfig」APIが作成されているため、選択してください。PUTメソッドを選択し、テストボタンを押下します。パスは作成したユーザーのユーザー名、リクエスト本文はJSON形式で変更後のメールアドレスを指定し、テストを実行してください。テスト実行後、メインリージョン/バックアップリージョンのCognitoユーザープール内のユーザー情報が変更されていること、DynamoDB上のレコードも変更されていることが確認できます。APIで行えるようにしています。ユーザー情報の変更と同様に、「userConfig」を選択肢、今度はDELETEメソッドを選択します。パスは作成したユーザーのユーザー名を指定し、テストを実行してください。テスト実行後、メインリージョン/バックアップリージョンのCognitoユーザープール内のユーザー情報が削除されていること、DynamoDB上のレコードも削除されていることが確認できます。ソースコードリポジトリ今回のサンプルコードは以下のリポジトリでMITライセンスにて公開しています。https://github.com/tak-kam/cognito-dr最後にこのように、制約付きではありますが、Cognitoユーザープールの準リアルタイムバックアップが可能であることが確認できました。ウェブサービス株式会社(DWS)公式ブログ記事URLをコピーしました。