AWS
cognito
ALB

CloudFormationでCognito User Pool(E メールアドレスおよび電話番号)

CloudFormationでCognito

最近では、ALBの組み込み認証など、AWS Cognitoを使う場面が増えてきた気がします。
ユーザ管理をマネージドでできるのは利点だと思います。
今回は、CloudFormationで、Cognito User PoolやIndentity Pool等を作成します。
なお、User Poolを作成する際に、「E メールアドレスおよび電話番号 - ユーザーは、E メールアドレスまたは電話番号を「ユーザー名」として使用してサインアップおよびサインインできます。」を指定します。
これは、2018年7/5現在、Cognito User Poolの日本語ドキュメントに書かれていないようで、いい感じの日本語の記事がなかったので記述します。

英語ドキュメントには書かれています。
AWS::Cognito::UserPool

マネージドコンソールでいうと、次のやつを選択した状態です。
スクリーンショット 2018-07-06 22.03.37.png

以下、CFnのテンプレートです。
今回は、E メールアドレスでログインを想定しています。
ポイントは、UserPoolのUsernameAttributes:です。
今回は、 emailを指定しています。
電話番号でログインする場合は、phone_number です。

その他、
UserPoolClinetは、javascript等から使用する想定でシークレットを無効にしています。
UserPool以外は、そのままですが、IdentityPoolを作成し、払い出す権限のRole等を記述しています。

実行は次の通りです。
$ aws cloudformation deploy --template ./cognito.yaml --stack-name Test --capabilities CAPABILITY_IAM

AWSTemplateFormatVersion: "2010-09-09"
Description: "Cognito Identity Pool and User Pool."
Resources:
  UserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: !Sub "${AWS::StackName}Users"
      AdminCreateUserConfig:
        AllowAdminCreateUserOnly: false
      UsernameAttributes:
        - email
      AutoVerifiedAttributes:
        - email
      Policies:
        PasswordPolicy:
          MinimumLength: 8
      Schema:
        - Name: email
          AttributeDataType: String
          DeveloperOnlyAttribute: false
          Mutable: true
          Required: true
  UserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      ClientName: !Sub "${AWS::StackName}Users-client"
      GenerateSecret: false
      RefreshTokenValidity: 7
      UserPoolId:
        !Ref UserPool
  IdentityPool:
    Type: AWS::Cognito::IdentityPool
    Properties:
      AllowUnauthenticatedIdentities: false
      IdentityPoolName: !Sub "${AWS::StackName}Users"
      CognitoIdentityProviders:
        - ClientId: !Ref UserPoolClient
          ProviderName: !Sub "cognito-idp.${AWS::Region}.amazonaws.com/${UserPool}"
  AuthenticatedPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - mobileanalytics:PutEvents
              - cognito-sync:*
              - cognito-identity:*
            Resource:
              - "*"
  AuthenticatedRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action: "sts:AssumeRoleWithWebIdentity"
            Principal:
              Federated: cognito-identity.amazonaws.com
            Condition:
              StringEquals:
                "cognito-identity.amazonaws.com:aud": !Ref IdentityPool
              ForAnyValue:StringLike:
                "cognito-identity.amazonaws.com:amr": authenticated
      ManagedPolicyArns: 
        - !Ref AuthenticatedPolicy
  RoleAttachment:
    Type: AWS::Cognito::IdentityPoolRoleAttachment
    Properties:
      IdentityPoolId: !Ref IdentityPool
      Roles:
        authenticated: !GetAtt AuthenticatedRole.Arn

Outputs:
  UserPoolId:
    Value: !Ref UserPool
    Export:
      Name: !Sub "${AWS::StackName}-UserPool"
  UserPoolArn:
    Value: !GetAtt UserPool.Arn
    Export:
      Name: !Sub "${AWS::StackName}-UserPoolArn"
  UserPoolClientId:
    Value: !Ref UserPoolClient
    Export:
      Name: !Sub "${AWS::StackName}-UserPoolClient"
  IdentityPoolId:
    Value: !Ref IdentityPool
    Export:
      Name: !Sub "${AWS::StackName}-IdentityPool"