サイトアイコン 協栄情報ブログ

AWS CloudFormationでCognitoユーザープールを作成してみました。


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

前提

・CloudFormationのテンプレートをyaml形式で作成する
・関連するIAMやLamdbaを同時作成すること
・パスワードポリシーを下記にすること

  1. 最小長:8桁
  2. 数字を必要とする:はい
  3. 特殊文字を要求する:はい
  4. 大文字を必要とする:はい
  5. 小文字を必要とする:はい

作成手順

CloudFormationテンプレートを使って、AWS CloudFormationコンソール上でスタックの作成手順を説明します。

CloudFormationテンプレート

Cognito-Userpool.yaml

AWSTemplateFormatVersion: "2010-09-09"
Description: "Example template including Cognito Identity Pool and User Pool."
Parameters:
  SystemId:
    Type: String
    Description: >-
      Your System Id. For example:CpiDev3
    ConstraintDescription: System Id is required
    Default: ''

Resources:
  # ユーザープールの作成
  UserPool:
    Type: "AWS::Cognito::UserPool"
    Properties:
      Policies:
        PasswordPolicy:
          MinimumLength: 8
          RequireUppercase: true
          RequireLowercase: true
          RequireNumbers: true
          RequireSymbols: true
      UserPoolName:
        !Join
          - ''
          - - 'cup-'
            - !Ref SystemId
            - '-TestUserPool'
      MfaConfiguration: 'OFF'
      AdminCreateUserConfig:
        AllowAdminCreateUserOnly: false
        UnusedAccountValidityDays: 7

  # ユーザープールにアプリクライアントを作成
  UserPoolClient:
    Type: "AWS::Cognito::UserPoolClient"
    Properties:
      UserPoolId:
        Ref: UserPool
      ClientName:
        !Join
          - ''
          - - 'cupc-'
            - !Ref SystemId
            - '-TestUserForCognito'
      RefreshTokenValidity: 30

  # ユーザーを追加
  AdminCreateUser:
    Type: Custom::CustomResource
    Properties:
      ServiceToken: !GetAtt CognitoAdminCreateUserFunction.Arn
      UserPoolId:
        Ref: UserPool
      UserName: TestUser
      # 仮パスワード
      Password: Hoge_001

  # ユーザープールにユーザーを作成するLambda関数
  CognitoAdminCreateUserFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName:
        !Join
          - ''
          - - 'lmd-'
            - !Ref SystemId
            - '-CognitoUserForTestUser'
      Handler: index.handler
      Role: !GetAtt CognitoFunctionExecutionRole.Arn
      Code:
        ZipFile: !Sub |
          import cfnresponse
          import boto3
          def handler(event, context):
            print(event['RequestType'])
            # スタック削除時にも実行されるので、処理せずに終了させる
            if event['RequestType'] == 'Delete':
              cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
              return

            # UserPoolIDを取得する
            user_pool_id = event['ResourceProperties']['UserPoolId']
            print(f'user_pool_id: {user_pool_id}')

            # ユーザー名、パスワードを取得する
            username = event['ResourceProperties']['UserName']
            password = event['ResourceProperties']['Password']

            # 検証用のユーザーを作成する
            response_data = {}
            try:
              client = boto3.client('cognito-idp')
              response_data = client.admin_create_user(
                UserPoolId=user_pool_id,
                Username=username,
                TemporaryPassword=password,
                MessageAction='SUPPRESS'
              )

              # Datetime型のままなので文字列に変換する
              response_data['User']['UserCreateDate'] = \
                response_data['User']['UserCreateDate'].strftime('%c')
              response_data['User']['UserLastModifiedDate'] = \
                response_data['User']['UserLastModifiedDate'].strftime('%c')

            except Exception as e:
              print("error: " + str(e))
              response_data = {'error': str(e)}
              cfnresponse.send(event, context, cfnresponse.FAILED, response_data)
              return

            print(response_data)
            cfnresponse.send(event, context, cfnresponse.SUCCESS, response_data)
      Runtime: python3.6

  # Lambda関数実行用のロール
  CognitoFunctionExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: 
        !Join
          - ''
          - - 'irl-'
            - !Ref SystemId
            - '-CognitoFunctionExecutionRole'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: root
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
              - logs:CreateLogGroup
              - logs:CreateLogStream
              - logs:PutLogEvents
            Resource: "arn:aws:logs:*:*:*"
          # Cognitoの操作権限を付与する
          - Effect: Allow
            Action:
              - cognito-idp:*
            Resource: "arn:aws:cognito-idp:*:*:userpool/*"

AWS CloudFormationコンソール上でスタックの作成

AWS コンソールをログインし、CloudFormationを開きます。
その後、「スタックの作成」⇒「新しいリソースを使用(標準)」をクリックし、テンプレートを指定して「次へ」をクリックします。

パラメータを入力して「次へ」をクリックします。

「次へ」をクリックします。

「AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。」をチェックし、「スタックの作成」をクリックします。

作成後の動作確認

スタックのリソースタブを開き、ステータスが「CREATE_COMPLETE」であることを確認します。

ユーザー作成時のLambdaのログを確認します。

Cognito画面を確認します。
・全般設定

・ユーザーとグループ
アカウントのステータスが「FORCE_CHANGE_PASSWORD」であることを確認します。

・アプリクライアント

参考

AWS::Cognito::UserPool

モバイルバージョンを終了