AWS CLIのupdate-user-poolコマンドでCognitoユーザープールを更新する

先日ハマったのでメモ。

 

 

[cliで更新時デフォルト値に戻る問題]

Amazon CognitoにはユーザープールとIDプールの2つのオブジェクトがある。それぞれ、ユーザープールが認証を、IDプールが認可を管理するのに利用できる。

aws.amazon.com

 

ユーザープールをマネジメントコンソールで見るとこのようになっている。

f:id:kidani_a:20211002224114p:plain

 

このユーザープールのタグをAWS CLIで追加しようとすると、以下のようになる。

aws cognito-idp update-user-pool \
  --user-pool-id ap-northeast-1_XXXXXXXXX \
  --user-pool-tags TagKey3=TagVal3

 

しかし、実行結果は下の画像のようになり、予期していたものとは異なる。

f:id:kidani_a:20211002224242p:plain

 

カスタム属性やパスワードポリシー、アプリクライアントの設定は破棄されていない。しかし、メール、MFA、アドバンスドセキュリティ、トリガーの設定がデフォルト値に戻ってしまっている。 

 

チームメンバーから指摘されて、よくよくドキュメントを読んでみると、たしかに下記の一文が書かれていた。

If you don't provide a value for an attribute, it will be set to the default value.

(私訳:属性値を指定しない場合、デフォルト値に設定されます)

docs.aws.amazon.com

 

これはちょっと困る...。

 

[回避策1: tag-resourceコマンド]

回避策の一つとしてはまずtag-resourceコマンドがある。

docs.aws.amazon.com

 

こちらを実行すると、タグを純粋に追加できるので、update-user-poolコマンドのように既存のタグが削除されることもないし、他の設定箇所がデフォルト値に戻ることもない。

 

しかし、このコマンドはタグの追加についてしか使えない。

タグ以外のユーザープールの設定を変更したい場合にはやはりupdate-user-poolコマンドを利用するしかない。

 

[回避策2: jqでがんばる]

もうちょっと何かいい方法はないものか、と思って検索してみるとGitHubのissueが見つかった。やはり同様に困っているひとがいるようだ。

github.com

 

issueのやりとりを最後まで読み進めると、以下のコマンドで、既存の設定値を残したまま特定の属性のみ更新できるらしい。

# 利用可能な設定のキーを取得する
config_keys=$(aws cognito-idp update-user-pool --generate-cli-skeleton | jq 'keys')

# 現在のユーザープールの設定値を取得し、更新用データを作成する
# 注意:AdminCreateUserConfig.UnusedAccountValidityDaysは
# Policies.PasswordPolicy.TemporaryPasswordValidityDaysの設定を利用している場合無効なので削除する current_config=$(aws cognito-idp describe-user-pool --user-pool-id "対象のプールID" | jq --argjson whitelist "${config_keys}" '.UserPool | . + {UserPoolId:.Id} | with_entries(select(.key as $a | any($whitelist[]; . == $a))) | del(.AdminCreateUserConfig.UnusedAccountValidityDays)') # 取得した設定と合わせて、更新したいパラメータを指定する
# (ここではトリガーするLambda関数の設定) aws cognito-idp update-user-pool --lambda-config "PostConfirmation=${api_function_arn}" --cli-input-json "${current_config}"

 

実際に、CloudShellで上記コマンドを実行してみると、既存の設定値を維持したまま設定を変更できた。

 

[回避策3: マネジメントコンソール]

AWS CLIでがんばらずに、ユーザープール1個だけなら設定変更をマネジメントコンソール経由でやるのが速い。

前述のjq方式のようなことを、裏側でよしなにやってくれるらしく、1箇所設定を変更しても他の設定がデフォルト値に戻るようなことはない。

 

どうせならこのマネジメントコンソールの挙動をAPIとして実装して欲しかった......。

 

[まとめ]

  • AWS CLIでCognitoユーザープールの設定更新をする際、未指定の属性はデフォルト値に戻るので注意が必要
  • どうしてもCLIでやるならjqなどでがんばれば実現できる
  • 対象が少なければ、CLIでがんばらなくてもマネジメントコンソールでやればよい