はじめに
こんにちは!山本です。
自分の認識不足で不用意にAWSコストを積んでしまってチームを混乱させてしまったので自戒のため、備忘のため記事にしました。
最後まで読んでいただけると嬉しいです!!
今回話さないこと
- Cognitoとはなにか
- 各Cognito料金プランの詳細(なにができるのか、違いはなにかなど)
忙しい人のための要約
-
AdminCreateUserAPIでユーザを作成すると、ユーザがログインしていなくても作成時点でMAU(月間アクティブユーザ)としてカウントされる -
FORCE_CHANGE_PASSWORD状態(初回パスワードリセット待ち)であっても関係なくカウントされる
何が起きたか
自作のPythonバッチをECS Taskで実行し、AdminCreateUser APIを使って約1万ユーザをCognitoユーザプールへ一括追加しました。
追加したユーザはすぐにログインするユーザではなく、初回パスワード変更(FORCE_CHANGE_PASSWORD)が必要な状態で作成しており、初回パスワードリセットを完了するまではCognitoユーザプールの料金には加算されないと認識していました。
しかし翌日想定外のCognitoコストが発生していることに気づきました。
何が原因だったのか
1. AdminCreateUserAPIは即MAUにカウントされる
AWS CognitoではMAU(Monthly Active Users)という単位で料金が計算されます。
このMAUの定義がポイントです。
AWS公式の料金ページには、MAUとしてカウントされる操作(IDオペレーション)が以下のように定義されています。
ある暦月内に、顧客のアプリケーションが管理作成または更新、サインアップ、サインイン、サインアウト、トークンの更新、パスワードの変更、ユーザー アカウント属性の更新、ユーザーに対する属性クエリ (AdminGetUser API) など、あるユーザーのために ID オペレーションを生成した場合、そのユーザーは 1 MAU としてカウントされます。
管理作成とあり、これはAdminCreateUser APIに該当していると見受けられます。
つまり、ユーザが一度もログインしていなくても、FORCE_CHANGE_PASSWORD状態であっても、AdminCreateUserを呼んだ時点でそのユーザはMAUとしてカウントされます。
2. CSVインポートとの違い
今回の原因とは関係ないですが、CognitoにはCSVインポート機能でユーザを追加することができます.
インポート自体はIDオペレーションに該当しないため、ユーザが実際にログインするなどのIDオペレーションを行うまでMAUにはカウントされないそうです。
| ユーザ追加方法 | MAUカウントのタイミング |
|---|---|
| AdminCreateUser (API経由) | 作成した時点で即カウント |
| CSVインポート | ログイン等のIDオペレーション実行時 |
すぐにログインしないユーザの一括登録では、この違いが大きなコスト差になることがわかりました。
ただし、CSVインポートについては今回対応予定のユースケースには沿わないと考えていたため、最初から除外していました。
3. Essentialsプランの単価が被害を大きくした
AWS Cognitoには3つの料金プランがあります。
- Lite
- Essentials
- Plus
Terraformなどで特に指定せずユーザプールを作成すると、デフォルトでEssentialsプランが適用されます。
AdminCreateUserでMAUにカウントされること自体はどのプランでも同じですが、プランによって単価が異なります。
| プラン | 10,000 MAU超の単価 | 1万MAU追加時のコスト(無料枠なしの場合) |
|---|---|---|
| Lite | USD 0.0055 | 約 USD 55 |
| Essentials | USD 0.015 | 約 USD 150 |
| Plus | USD 0.020 | 約 USD 200 |
※ Lite / Essentialsとも最初の10,000 MAUは無料枠あり(アカウント単位)。今回は無料枠をすでに使い切っていた。
私の場合、デフォルトのEssentialsプランのまま運用していたため、Liteプランと比較して約3倍のコストが発生しました。
Liteプランにしてれば・・・orz
教訓 / 今後気をつけること
API経由でAdminCreateUserを実行すると即MAUカウントされることを認識する
ユーザがFORCE_CHANGE_PASSWORD状態であっても、API経由で作成した時点でMAUにカウントされます。
「初回パスワードリセットを完了するまではカウントされない」という認識は誤りでした。
すぐにログインしないユーザの一括登録にはCSVインポートなどを検討する
CSVインポートならインポート時点ではMAUにカウントされないため、ユーザが実際にログインするまでコストは発生しません。
ただし、インポート後にパスワードリセットを強制実行したり、AdminGetUserAPIでユーザが追加できたかを確認したりするとその操作でMAUにカウントされるため注意が必要です。
ユーザプールの料金プランを確認する
デフォルトのEssentialsプランはLiteの約3倍の単価です。
Essentials固有の機能が不要であれば、Liteプランへの変更を検討するようにしましょう!
# 対象ユーザプールのプランを確認
aws cognito-idp describe-user-pool \
--user-pool-id {ユーザプールID} \
--query "UserPool.UserPoolTier"
# ESSENTIALSと表示されたらLITEプランへ変更可能
aws cognito-idp update-user-pool \
--user-pool-id {ユーザプールID} \
--user-pool-tier LITE
またはTerraformのリソース定義で明示的にLiteプランを指定する。
resource "aws_cognito_user_pool" "user_pool" {
# ... (既存の設定) ...
# 明示的にLITEを指定
user_pool_tier = "LITE"
}
最後に
今回はCognitoのユーザプール料金の仕組みについて、実際に失敗しつつ経験を積むことができました。
今後もこういった、自身が学んだ知見などをまとめていければと思いますので、暖かく見守っていただけると幸いです。
以上!最後まで読んでいただき、ありがとうございました!!