
IAMのパスワードポリシーをLambda(Python3)から変更する
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
LambdaからIAMのパスワードポリシーを変更したので、サンプルとしてコードを置いておきます。ご自由にお使いください。
サンプルコード
先にLambdaで利用するコードを載せておきます。
- LambdaのランタイムはPython3.8で動作確認をしています
- ログの出力や変更後のリソースチェックはしていますが、あくまでサンプルとしてご利用ください
- パスワードポリシーはSecurity Hubの「AWS の基本的なセキュリティのベストプラクティス標準」を満たすように設定しています
IAMのパスワードポリシーを変更する
import json
import boto3
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
PASSWORD_POLICY = {
    "MinimumPasswordLength": 8,
    "RequireSymbols": True,
    "RequireNumbers": True,
    "RequireUppercaseCharacters": True,
    "RequireLowercaseCharacters": True,
    "AllowUsersToChangePassword": True,
}
def update_password_policy():
    iam = boto3.client("iam")
    iam.update_account_password_policy(
        MinimumPasswordLength=PASSWORD_POLICY['MinimumPasswordLength'],
        RequireSymbols=PASSWORD_POLICY['RequireSymbols'],
        RequireNumbers=PASSWORD_POLICY['RequireNumbers'],
        RequireUppercaseCharacters=PASSWORD_POLICY['RequireUppercaseCharacters'],
        RequireLowercaseCharacters=PASSWORD_POLICY['RequireLowercaseCharacters'],
        AllowUsersToChangePassword=PASSWORD_POLICY['AllowUsersToChangePassword'],
    )
def check_password_policy():
    results = {
        'minimum_password_length': False,
        'require_symbols': False,
        'require_numbers': False,
        'require_uppercase_characters': False,
        'require_lowercase_characters': False,
        'allow_users_to_change_password': False,
    }
    iam = boto3.client("iam")
    res_password_policy = iam.get_account_password_policy()["PasswordPolicy"]
    results['minimum_password_length'] = res_password_policy['MinimumPasswordLength'] == PASSWORD_POLICY['MinimumPasswordLength']
    if not results['minimum_password_length']:
        logger.error(
            f'MinimumPasswordLength is not equal. {PASSWORD_POLICY["MinimumPasswordLength"]} expect but {res_password_policy["MinimumPasswordLength"]} ')
    results['require_symbols'] = res_password_policy['RequireSymbols'] == PASSWORD_POLICY['RequireSymbols']
    results['require_numbers'] = res_password_policy['RequireNumbers'] == PASSWORD_POLICY['RequireNumbers']
    results['require_uppercase_characters'] = res_password_policy['RequireUppercaseCharacters'] == PASSWORD_POLICY['RequireUppercaseCharacters']
    results['require_lowercase_characters'] = res_password_policy['RequireLowercaseCharacters'] == PASSWORD_POLICY['RequireLowercaseCharacters']
    results['allow_users_to_change_password'] = res_password_policy['AllowUsersToChangePassword'] == PASSWORD_POLICY['AllowUsersToChangePassword']
    return results
def lambda_handler(event, context):
    update_password_policy()
    is_resources = {
        'password_policy': False
    }
    check_results = check_password_policy()
    is_resources['password_policy'] = all(check_results.values())
    if not all(is_resources.values()):
        logger.error("Failed to update password policy")
        logger.error(json.dumps(check_results))
        logger.error(
            f"is_resources: {is_resources}"
        )
        raise Exception('Fail to check reource')
    logger.info("Succeeded in updating IAM password policy")
    logger.info(
        f"is_resources: {is_resources}"
    )
    return {
        "is_resources": is_resources
    }
やってみる
Lambdaを実行する
デフォルトでは以下の項目で設定されているので、これを変更していきます。
- パスワードの最小長は8文字、最大長は128文字です。
- 次の文字タイプの組み合わせのうち少なくとも3つ:大文字、小文字、数字、記号
! @ # $ % ^ & * ( ) _ + - = [ ] { } | '- AWSアカウント名またはメールアドレスと同一ではありません
参考:デフォルトのパスワードポリシー
上記の設定を更新して以下の5項目へ変更します。
- パスワードの最小文字数は 8 文字
- 1 文字以上のアルファベット大文字 (A~Z) を必要とする
- 1 文字以上のアルファベット小文字 (a~z) を必要とする
- 少なくとも 1 つの数字が必要
- 少なくとも 1 つの英数字以外の文字が必要 (! @ # $ % ^ & * ( ) _ + - = { } | ')
- ユーザーにパスワードの変更を許可する
コードを貼り付けてDeployした状態です。(LambdaのIAMロールや実行時間は適宜調整してください。)テストイベントはデフォルトのまま実行します。

実行が完了すると、以下のようにレスポンスや実行ログが出力されます。

Responseにはリソースの状態が出力されます。成功していればpassword_policyの値にtrueが入っているはずです。
Function Log には有効化が成功したことを示すログを出力しています。
コンソールを確認すると、想定した通りのパスワードポリシーが設定されていることが確認できました。

パスワードの最小文字数 12 文字に変更してみる
8文字ではなく12文字を最小文字数に設定したい場合は、以下の定数を定義している部分を変更してください。
import json
import boto3
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
PASSWORD_POLICY = {
    "MinimumPasswordLength": 12,
    "RequireSymbols": True,
    "RequireNumbers": True,
    "RequireUppercaseCharacters": True,
    "RequireLowercaseCharacters": True,
    "AllowUsersToChangePassword": True,
}
...
上記のように変更してLambdaへデプロイして実行すると、12文字が最小文字数として設定できました。

おわりに
LambdaからIAMのパスワードポリシーを更新してみました。別のパスワードポリシーへ変更したい場合にも、ある程度参考にできる部分はあるかと思います。
Control Tower環境であれば以下の仕組みと組み合わせることで、アカウント発行時の自動化フローを作成できます。活用方法の1つとしてご検討ください。












