[小ネタ]Lambda-backed custom resourcesでIAMパスワードポリシーのアカウント設定を変更する

新しいAWSアカウントを作成するタイミングでIAMパスワードポリシーのアカウント設定を有効にしたい方向け
2022.02.23

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、おんづか(@onzuka_muscle)です!

こちらのブログを参考にアカウントが特定OUに所属したタイミングでLambdaを実行し、IAMパスワードポリシーのアカウント設定を変更してみました。

IAMパスワードポリシーのアカウント設定」はIAMのメニューから確認できます。

デフォルトでは上記のポリシーになっているのですがここを変更します。

注意点

  • Lambdaが実行された後もLambda , IAMロール , CloudWatch Logsといったリソースは残ります
    • 必要に応じて削除してください
  • あくまでサンプルコードです
    • エラーハンドリング・ロギングについてはそこそこなので必要に応じてカスタマイズしてください
  • 変更後のパスワードポリシーは要件に応じて書き換えてください

テンプレート

AWSTemplateFormatVersion: "2010-09-09"
# ------------------------------------------------------------#
#  IAM パスワードポリシーのアカウント設定を変更する Lambda-backed custom resources
# ------------------------------------------------------------#
Parameters:
  RoleName:
    Type: String
  FunctionName:
    Type: String

Resources:
  # ------------------------------------------------------------#
  #  Lambda-backed custom resources
  # ------------------------------------------------------------#
  UpdateAccountPasswordPolicy:
    Type: Custom::UpdateAccountPasswordPolicy
    Properties:
      ServiceToken: !GetAtt "LambdaFunction.Arn"

  # ------------------------------------------------------------#
  #  Lambda 関数
  # ------------------------------------------------------------#
  LambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Ref FunctionName
      Description: Lambda for change account settings IAM password policy
      Role: !GetAtt "LambdaExecutionRole.Arn"
      Runtime: "python3.8"
      Handler: index.lambda_handler
      Timeout: 60
      Code:
        ZipFile: |
          import boto3
          import cfnresponse
          from logging import getLogger, INFO

          logger = getLogger()
          logger.setLevel(INFO)


          def update_account_password_policy(event, context):
            logger.info('[START] update_account_password_policy')
            logger.info("boto3 version:{}".format(boto3.__version__))

            try:
                response = boto3.client('iam').update_account_password_policy(
                  MinimumPasswordLength=14,
                  RequireSymbols=True,
                  RequireNumbers=True,
                  RequireUppercaseCharacters=True,
                  RequireLowercaseCharacters=True,
                  AllowUsersToChangePassword=False,
                  MaxPasswordAge=90,
                  PasswordReusePrevention=24,
                  HardExpiry=False
              )
                if response['ResponseMetadata']['HTTPStatusCode'] == 200:
                    logger.info("  enable success")
                else:
                    logger.info("  enable failed")
                logger.info('[END] update_account_password_policy')
            except Exception as e:
                logger.error(e)
                cfnresponse.send(event, context, cfnresponse.FAILED,{'Response': 'Failure'})
                exit()


          def lambda_handler(event, context):
            if event['RequestType'] == 'Create':
                # Create時に実行したい処理 --> パスワードポリシーの設定
                update_account_password_policy(event, context)
                cfnresponse.send(event, context, cfnresponse.SUCCESS,{'Response': 'Success'})
            if event['RequestType'] == 'Delete':
                # Delete時に実行したい処理 --> 無し
                cfnresponse.send(event, context, cfnresponse.SUCCESS,{'Response': 'Success'})
            if event['RequestType'] == 'Update':
                # Update時に実行したい処理 --> 無し
                cfnresponse.send(event, context, cfnresponse.SUCCESS,{'Response': 'Success'})

  # ------------------------------------------------------------#
  #  Lambda 関数用の IAM ロール
  # ------------------------------------------------------------#
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref RoleName
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: "lambda.amazonaws.com"
            Action: "sts:AssumeRole"
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
      Policies:
        - PolicyName: FullAccessPasswordPolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - "iam:GetAccountPasswordPolicy"
                  - "iam:DeleteAccountPasswordPolicy"
                  - "iam:UpdateAccountPasswordPolicy"
                Resource: "*"

動作確認

意図した通りに設定できていました。

おわり

サンプルコードになりますが需要あるかなと思いブログにしました。

こちらのブログのようにCloudFormation StackSetsと組み合わせることで新しく作成したアカウントの「IAMパスワードポリシーのアカウント設定を変更」する作業を効率化できます。

誰かのお役に立てば嬉しいです。