Amazon Cognito ユーザープールをCloudFormationで作成し、SES設定等のカスタマイズもしてみた

Amazon Cognito ユーザープールをCloudFormationで作成し、SES設定等のカスタマイズもしてみた

Clock Icon2024.10.01

はじめに

以前、管理者主導でユーザー登録を行う運用ケースにおける、Amazon Cognito ユーザープールの設定すべき値や作成方法を解説しました。

https://dev.classmethod.jp/articles/amazon-cognito-user-pool-admin-managed-registration/

構成は以下の通りです。

cm-hirai-screenshot 2024-09-25 11.11.06

今回は、そのユーザープールをAWS CloudFormationで作成します。
さらに、ユーザープール作成後、以下の順序でCloudFormationを使用してALBとの統合やCognitoドメインをカスタムドメインへの変更なども行います。

  1. Cognito ユーザープールを作成
  2. ユーザー作成
  3. ALBと統合
  4. Cognitoドメインをカスタムドメイン
  5. メールドメインをSESに変更

CloudFormation を使用することで、Cognito ユーザープールの作成から各種設定まで、インフラストラクチャをコードとして管理できます。
これにより、環境の再現性が高まり、開発からテスト、本番環境への展開がスムーズになります。

前提条件

  • 本記事では、Cognitoユーザープールの作成に焦点を当てています。その他の環境構築については、以下の記事を参考に、下記の構成で事前に完了していることを前提としています。
  • 以下の記事を参考に、SES IDを事前に作成済みであること
    https://dev.classmethod.jp/articles/registered-free-domain-on-route53-and-authenticated-ses/
  • Amazon Route 53 パブリックホストゾーン(または他のDNSプロバイダー)で以下の設定が完了していること(example.comは仮のドメイン名です。各自が取得したドメイン名に置き換えてください)
    • ホスト名example.comを作成済み
    • レコード名example.comに対して、AレコードでALBのDNS名を値として設定済み
    • レコード名auth.example.comを、Hosted UIのログイン画面用カスタムドメインとして使用予定
  • 東京リージョンとバージニアリージョンで、ドメイン名example.com(*.example.comを含む)のACM証明書が発行済みであること

Cognitoユーザープール作成

以下のCloudFormationテンプレートを使用してスタックを作成します。

AWSTemplateFormatVersion: 2010-09-09
Description: Cognito User Pool

Parameters:
  DomainName:
    Type: String
    Description: Domain name for the callback URL (e.g., example.com)
    Default: example.com
  UserPoolName:
    Type: String
    Description: User Pool name
    Default: admin-managed-user-pool

Resources:
  CognitoUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: !Ref UserPoolName
      Policies:
        PasswordPolicy:
          MinimumLength: 8
          RequireLowercase: true
          RequireNumbers: true
          RequireSymbols: true
          RequireUppercase: true
          TemporaryPasswordValidityDays: 7
      AdminCreateUserConfig:
        AllowAdminCreateUserOnly: true
      AccountRecoverySetting:
        RecoveryMechanisms:
          - Name: verified_email
            Priority: 1
      UsernameConfiguration:
        CaseSensitive: false
      VerificationMessageTemplate:
        DefaultEmailOption: CONFIRM_WITH_CODE
      MfaConfiguration: 'ON'
      EnabledMfas:
        - SOFTWARE_TOKEN_MFA
      Schema:
        - Name: email
          AttributeDataType: String
          Mutable: true
          Required: true
      EmailConfiguration:
        EmailSendingAccount: COGNITO_DEFAULT

  CognitoUserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      UserPoolId: !Ref CognitoUserPool
      ClientName: !Ref UserPoolName
      GenerateSecret: true
      ExplicitAuthFlows:
        - ALLOW_USER_SRP_AUTH
        - ALLOW_REFRESH_TOKEN_AUTH
      PreventUserExistenceErrors: ENABLED
      AllowedOAuthFlows:
        - code
      AllowedOAuthScopes:
        - email
        - openid
        - phone
      AllowedOAuthFlowsUserPoolClient: true
      SupportedIdentityProviders:
        - COGNITO
      CallbackURLs:
        - !Sub https://${DomainName}/oauth2/idpresponse
      LogoutURLs: []

  CognitoUserPoolDomain:
    Type: AWS::Cognito::UserPoolDomain
    Properties:
      Domain: !Ref UserPoolName
      UserPoolId: !Ref CognitoUserPool

Outputs:
  UserPoolDomain:
    Description: Domain of the Cognito User Pool
    Value: !Sub ${CognitoUserPoolDomain}.auth.${AWS::Region}.amazoncognito.com
  CallbackURL:
    Description: Callback URL for the Cognito User Pool Client
    Value: !Sub https://${DomainName}/oauth2/idpresponse

ドメイン名とユーザープール名をパラメータとして記載し、スタックを作成します。
cm-hirai-screenshot 2024-09-25 8.57.07

スタックを作成すると、ユーザープールが作成されます。

ユーザーを追加

次に、ユーザープールにサンプルユーザーを追加します。以下のテンプレートを使用してスタックを更新します。

AWSTemplateFormatVersion: 2010-09-09
Description: Cognito User Pool

Parameters:
  DomainName:
    Type: String
    Description: Domain name for the callback URL (e.g., example.com)
    Default: example.com
  UserPoolName:
    Type: String
    Description: User Pool name
    Default: admin-managed-user-pool
+  CognitoUserEmail:
+    Type: String
+  CognitoUserName:
+    Type: String

Resources:
  CognitoUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: !Ref UserPoolName
      Policies:
        PasswordPolicy:
          MinimumLength: 8
          RequireLowercase: true
          RequireNumbers: true
          RequireSymbols: true
          RequireUppercase: true
          TemporaryPasswordValidityDays: 7
      AdminCreateUserConfig:
        AllowAdminCreateUserOnly: true
      AccountRecoverySetting:
        RecoveryMechanisms:
          - Name: verified_email
            Priority: 1
      UsernameConfiguration:
        CaseSensitive: false
      VerificationMessageTemplate:
        DefaultEmailOption: CONFIRM_WITH_CODE
      MfaConfiguration: 'ON'
      EnabledMfas:
        - SOFTWARE_TOKEN_MFA
      Schema:
        - Name: email
          AttributeDataType: String
          Mutable: true
          Required: true
      EmailConfiguration:
        EmailSendingAccount: COGNITO_DEFAULT

  CognitoUserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      UserPoolId: !Ref CognitoUserPool
      ClientName: !Ref UserPoolName
      GenerateSecret: true
      ExplicitAuthFlows:
        - ALLOW_USER_SRP_AUTH
        - ALLOW_REFRESH_TOKEN_AUTH
      PreventUserExistenceErrors: ENABLED
      AllowedOAuthFlows:
        - code
      AllowedOAuthScopes:
        - email
        - openid
        - phone
      AllowedOAuthFlowsUserPoolClient: true
      SupportedIdentityProviders:
        - COGNITO
      CallbackURLs:
        - !Sub https://${DomainName}/oauth2/idpresponse
      LogoutURLs: []

  CognitoUserPoolDomain:
    Type: AWS::Cognito::UserPoolDomain
    Properties:
      Domain: !Ref UserPoolName
      UserPoolId: !Ref CognitoUserPool

+  UserPoolUser:
+    Type: AWS::Cognito::UserPoolUser
+    Properties:
+      UserPoolId: !Ref CognitoUserPool
+      Username: !Ref CognitoUserName
+      DesiredDeliveryMediums:
+        - EMAIL
+      UserAttributes:
+        - Name: email
+          Value: !Ref CognitoUserEmail
+        - Name: email_verified
+          Value: 'true'

Outputs:
  UserPoolDomain:
    Description: Domain of the Cognito User Pool
    Value: !Sub ${CognitoUserPoolDomain}.auth.${AWS::Region}.amazoncognito.com
  CallbackURL:
    Description: Callback URL for the Cognito User Pool Client
    Value: !Sub https://${DomainName}/oauth2/idpresponse

ユーザー名とユーザーのメールアドレスをパラメータとして指定し、スタックを更新します。
cm-hirai-screenshot 2024-09-25 9.07.16
スタック作成後、メールアドレスに、ユーザー名とパスワードが送信されます。
cm-hirai-screenshot 2024-09-25 8.51.15

マネジメントコンソールからもユーザーが確認できます。
cm-hirai-screenshot 2024-09-25 9.08.15

この設定により、管理者主導のユーザー登録プロセスを実現し、セキュアなユーザー管理が可能になります。
管理者がユーザーを作成し、初期パスワードを設定することで、不正なアカウント作成を防ぎ、より厳格なユーザー管理が可能となります。

ALBと統合

続いて、アプリケーションにログインできるようにユーザープールをALBと統合します。以下のテンプレートを使用してスタックを更新します。

AWSTemplateFormatVersion: 2010-09-09
Description: Cognito User Pool

Parameters:
  DomainName:
    Type: String
    Description: Domain name for the callback URL (e.g., example.com)
    Default: example.com
  UserPoolName:
    Type: String
    Description: User Pool name
    Default: admin-managed-user-pool
  CognitoUserEmail:
    Type: String
  CognitoUserName:
    Type: String
+  ExistingALBListenerArn:
+    Type: String
+    Description: ARN of the existing ALB Listener (usually the HTTPS:443 listener)
+    Default: arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:listener/app/alb-name/xxxx/xxxx
+  ExistingTargetGroupArn:
+    Type: String
+    Description: ARN of the existing Target Group
+    Default: arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:targetgroup/tg-name/xxxx

Resources:
  CognitoUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: !Ref UserPoolName
      Policies:
        PasswordPolicy:
          MinimumLength: 8
          RequireLowercase: true
          RequireNumbers: true
          RequireSymbols: true
          RequireUppercase: true
          TemporaryPasswordValidityDays: 7
      AdminCreateUserConfig:
        AllowAdminCreateUserOnly: true
      AccountRecoverySetting:
        RecoveryMechanisms:
          - Name: verified_email
            Priority: 1
      UsernameConfiguration:
        CaseSensitive: false
      VerificationMessageTemplate:
        DefaultEmailOption: CONFIRM_WITH_CODE
      MfaConfiguration: 'ON'
      EnabledMfas:
        - SOFTWARE_TOKEN_MFA
      Schema:
        - Name: email
          AttributeDataType: String
          Mutable: true
          Required: true
      EmailConfiguration:
        EmailSendingAccount: COGNITO_DEFAULT

  CognitoUserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      UserPoolId: !Ref CognitoUserPool
      ClientName: !Ref UserPoolName
      GenerateSecret: true
      ExplicitAuthFlows:
        - ALLOW_USER_SRP_AUTH
        - ALLOW_REFRESH_TOKEN_AUTH
      PreventUserExistenceErrors: ENABLED
      AllowedOAuthFlows:
        - code
      AllowedOAuthScopes:
        - email
        - openid
        - phone
      AllowedOAuthFlowsUserPoolClient: true
      SupportedIdentityProviders:
        - COGNITO
      CallbackURLs:
        - !Sub https://${DomainName}/oauth2/idpresponse
      LogoutURLs: []

  CognitoUserPoolDomain:
    Type: AWS::Cognito::UserPoolDomain
    Properties:
      Domain: !Ref UserPoolName
      UserPoolId: !Ref CognitoUserPool

  UserPoolUser:
    Type: AWS::Cognito::UserPoolUser
    Properties:
      UserPoolId: !Ref CognitoUserPool
      Username: !Ref CognitoUserName
      DesiredDeliveryMediums:
        - EMAIL
      UserAttributes:
        - Name: email
          Value: !Ref CognitoUserEmail
        - Name: email_verified
          Value: 'true'

+  ALBListenerRule:
+    Type: AWS::ElasticLoadBalancingV2::ListenerRule
+    Properties:
+      Actions:
+        - Type: authenticate-cognito
+          Order: 1
+          AuthenticateCognitoConfig:
+            UserPoolArn: !GetAtt CognitoUserPool.Arn
+            UserPoolClientId: !Ref CognitoUserPoolClient
+            UserPoolDomain: !Ref CognitoUserPoolDomain
+        - Type: forward
+          Order: 2
+          TargetGroupArn: !Ref ExistingTargetGroupArn
+      Conditions:
+        - Field: host-header
+          Values: 
+            - !Ref DomainName
+      ListenerArn: !Ref ExistingALBListenerArn
+      Priority: 1

Outputs:
  UserPoolDomain:
    Description: Domain of the Cognito User Pool
    Value: !Sub ${CognitoUserPoolDomain}.auth.${AWS::Region}.amazoncognito.com
  CallbackURL:
    Description: Callback URL for the Cognito User Pool Client
    Value: !Sub https://${DomainName}/oauth2/idpresponse

作成済みのALBのリスナールールとターゲットグループのARNをパラメータとして指定し、スタックを更新します。
cm-hirai-screenshot 2024-09-25 9.20.17

スタック更新後、リスナールールに反映されたことが確認できます。

cm-hirai-screenshot 2024-09-25 9.21.12

ブラウザでhttps://example.com/にアクセスしてみると、Hosted UI画面に遷移しました。

cm-hirai-screenshot 2024-09-25 9.22.56

上記の赤枠の通り、Cognitoドメインが利用されているので、次章でカスタムドメインに変更します。

ALB との統合により、アプリケーションへのアクセス制御を簡単に実装できます。ユーザーは Cognito による認証を経てからアプリケーションにアクセスすることになり、セキュリティが向上します。
また、ALB が認証を処理するため、アプリケーション側の実装を簡素化できます。

カスタムドメイン

次に、Cognitoドメインをカスタムドメインに変更します。以下のテンプレートを使用してスタックを更新します。

AWSTemplateFormatVersion: 2010-09-09
Description: Cognito User Pool

Parameters:
  DomainName:
    Type: String
    Description: Domain name for the callback URL (e.g., example.com)
    Default: example.com
  UserPoolName:
    Type: String
    Description: User Pool name
    Default: admin-managed-user-pool
  CognitoUserEmail:
    Type: String
  CognitoUserName:
    Type: String
  ExistingALBListenerArn:
    Type: String
    Description: ARN of the existing ALB Listener (usually the HTTPS:443 listener)
    Default: arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:listener/app/alb-name/xxxx/xxxx
  ExistingTargetGroupArn:
    Type: String
    Description: ARN of the existing Target Group
    Default: arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:targetgroup/tg-name/xxxx
+  CertificateArn:
+    Type: String
+    Description: >-
+      ARN of the ACM certificate for the custom domain. 
+      This certificate MUST be in the us-east-1 (N. Virginia) region, 
+      regardless of the region where this stack is deployed.
+    Default: arn:aws:acm:us-east-1:012345678901:certificate/xxx

Resources:
  CognitoUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: !Ref UserPoolName
      Policies:
        PasswordPolicy:
          MinimumLength: 8
          RequireLowercase: true
          RequireNumbers: true
          RequireSymbols: true
          RequireUppercase: true
          TemporaryPasswordValidityDays: 7
      AdminCreateUserConfig:
        AllowAdminCreateUserOnly: true
      AccountRecoverySetting:
        RecoveryMechanisms:
          - Name: verified_email
            Priority: 1
      UsernameConfiguration:
        CaseSensitive: false
      VerificationMessageTemplate:
        DefaultEmailOption: CONFIRM_WITH_CODE
      MfaConfiguration: 'ON'
      EnabledMfas:
        - SOFTWARE_TOKEN_MFA
      Schema:
        - Name: email
          AttributeDataType: String
          Mutable: true
          Required: true
      EmailConfiguration:
        EmailSendingAccount: COGNITO_DEFAULT

  CognitoUserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      UserPoolId: !Ref CognitoUserPool
      ClientName: !Ref UserPoolName
      GenerateSecret: true
      ExplicitAuthFlows:
        - ALLOW_USER_SRP_AUTH
        - ALLOW_REFRESH_TOKEN_AUTH
      PreventUserExistenceErrors: ENABLED
      AllowedOAuthFlows:
        - code
      AllowedOAuthScopes:
        - email
        - openid
        - phone
      AllowedOAuthFlowsUserPoolClient: true
      SupportedIdentityProviders:
        - COGNITO
      CallbackURLs:
        - !Sub https://${DomainName}/oauth2/idpresponse
      LogoutURLs: []

  CognitoUserPoolDomain:
    Type: AWS::Cognito::UserPoolDomain
    Properties:
-      Domain: !Ref UserPoolName
+      Domain: !Sub auth.${DomainName}
      UserPoolId: !Ref CognitoUserPool
+      CustomDomainConfig:
+        CertificateArn: !Ref CertificateArn

  UserPoolUser:
    Type: AWS::Cognito::UserPoolUser
    Properties:
      UserPoolId: !Ref CognitoUserPool
      Username: !Ref CognitoUserName
      DesiredDeliveryMediums:
        - EMAIL
      UserAttributes:
        - Name: email
          Value: !Ref CognitoUserEmail
        - Name: email_verified
          Value: 'true'

  ALBListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - Type: authenticate-cognito
          Order: 1
          AuthenticateCognitoConfig:
            UserPoolArn: !GetAtt CognitoUserPool.Arn
            UserPoolClientId: !Ref CognitoUserPoolClient
            UserPoolDomain: !Ref CognitoUserPoolDomain
        - Type: forward
          Order: 2
          TargetGroupArn: !Ref ExistingTargetGroupArn
      Conditions:
        - Field: host-header
          Values: 
            - !Ref DomainName
      ListenerArn: !Ref ExistingALBListenerArn
      Priority: 1

Outputs:
  UserPoolDomain:
    Description: Domain of the Cognito User Pool
-    Value: !Sub ${CognitoUserPoolDomain}.auth.${AWS::Region}.amazoncognito.com
+    Value: !Ref CognitoUserPoolDomain
  CallbackURL:
    Description: Callback URL for the Cognito User Pool Client
    Value: !Sub https://${DomainName}/oauth2/idpresponse

テンプレートのパラメータに、前提条件で述べたバージニアリージョンのACMのARNを指定してスタックを更新します。

cm-hirai-screenshot 2024-09-25 9.27.38

cm-hirai-screenshot 2024-09-25 9.57.02

カスタムドメインを作成すると、自動でCloudFrontのDNS名が発行されます。CloudFrontのエイリアスターゲットをコピーしておきます。

cm-hirai-screenshot 2024-08-22 17.18.12

Route 53で新しいレコードを作成します。レコード名をauth.example.com、レコードタイプをCNAMEとし、値には先ほどコピーしたCloudFrontのDNS名を入力します。

cm-hirai-screenshot 2024-08-22 17.19.50

正しく設定されていれば、カスタムドメインであるhttps://auth.example.com/login?client_id=xxxx&redirect_uri=xxxxのログイン画面に自動的にリダイレクトされます。

cm-hirai-screenshot 2024-09-25 9.40.18

カスタムドメインの設定により、ブランディングを維持しつつ、ユーザーエクスペリエンスを向上させることができます。
ユーザーは組織の公式ドメインでログイン画面にアクセスすることになり、信頼性と一貫性のあるユーザー体験を提供できます。

CloudFormationではなく、マネジメントコンソールから対応する場合は以下の記事を参考ください。

https://dev.classmethod.jp/articles/amazon-cognito-hosted-ui-customize-domain/

メールドメインをSESに変更

最後に、メールドメインをCognitoドメインから作成済みのSESに変更します。以下のテンプレートを使用してスタックを更新します。

AWSTemplateFormatVersion: 2010-09-09
Description: Cognito User Pool

Parameters:
  DomainName:
    Type: String
    Description: Domain name for the callback URL (e.g., example.com)
    Default: example.com
  UserPoolName:
    Type: String
    Description: User Pool name
    Default: admin-managed-user-pool
  CognitoUserEmail:
    Type: String
  CognitoUserName:
    Type: String
  ExistingALBListenerArn:
    Type: String
    Description: ARN of the existing ALB Listener (usually the HTTPS:443 listener)
    Default: arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:listener/app/alb-name/xxxx/xxxx
  ExistingTargetGroupArn:
    Type: String
    Description: ARN of the existing Target Group
    Default: arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:targetgroup/tg-name/xxxx
  CertificateArn:
    Type: String
    Description: >-
      ARN of the ACM certificate for the custom domain. 
      This certificate MUST be in the us-east-1 (N. Virginia) region, 
      regardless of the region where this stack is deployed.
    Default: arn:aws:acm:us-east-1:012345678901:certificate/xxx
+  EmailDomain:
+    Type: String
+    Description: Email address to use as the source for Cognito emails
+    Default: example.com
+  EmailSenderName:
+    Type: String
+    Description: Name to use as the sender for Cognito emails
+    Default: classmethod

Resources:
  CognitoUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: !Ref UserPoolName
      Policies:
        PasswordPolicy:
          MinimumLength: 8
          RequireLowercase: true
          RequireNumbers: true
          RequireSymbols: true
          RequireUppercase: true
          TemporaryPasswordValidityDays: 7
      AdminCreateUserConfig:
        AllowAdminCreateUserOnly: true
      AccountRecoverySetting:
        RecoveryMechanisms:
          - Name: verified_email
            Priority: 1
      UsernameConfiguration:
        CaseSensitive: false
      VerificationMessageTemplate:
        DefaultEmailOption: CONFIRM_WITH_CODE
      MfaConfiguration: 'ON'
      EnabledMfas:
        - SOFTWARE_TOKEN_MFA
      Schema:
        - Name: email
          AttributeDataType: String
          Mutable: true
          Required: true
-     EmailConfiguration:
-        EmailSendingAccount: COGNITO_DEFAULT
+      EmailConfiguration:
+        EmailSendingAccount: DEVELOPER
+        From: !Sub ${EmailSenderName} <no-reply@${EmailDomain}>
+        SourceArn: !Sub arn:aws:ses:${AWS::Region}:${AWS::AccountId}:identity/${EmailDomain}

  CognitoUserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      UserPoolId: !Ref CognitoUserPool
      ClientName: !Ref UserPoolName
      GenerateSecret: true
      ExplicitAuthFlows:
        - ALLOW_USER_SRP_AUTH
        - ALLOW_REFRESH_TOKEN_AUTH
      PreventUserExistenceErrors: ENABLED
      AllowedOAuthFlows:
        - code
      AllowedOAuthScopes:
        - email
        - openid
        - phone
      AllowedOAuthFlowsUserPoolClient: true
      SupportedIdentityProviders:
        - COGNITO
      CallbackURLs:
        - !Sub https://${DomainName}/oauth2/idpresponse
      LogoutURLs: []

  CognitoUserPoolDomain:
    Type: AWS::Cognito::UserPoolDomain
    Properties:
      Domain: !Sub auth.${DomainName}
      UserPoolId: !Ref CognitoUserPool
      CustomDomainConfig:
        CertificateArn: !Ref CertificateArn

  UserPoolUser:
    Type: AWS::Cognito::UserPoolUser
    Properties:
      UserPoolId: !Ref CognitoUserPool
      Username: !Ref CognitoUserName
      DesiredDeliveryMediums:
        - EMAIL
      UserAttributes:
        - Name: email
          Value: !Ref CognitoUserEmail
        - Name: email_verified
          Value: 'true'

  ALBListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - Type: authenticate-cognito
          Order: 1
          AuthenticateCognitoConfig:
            UserPoolArn: !GetAtt CognitoUserPool.Arn
            UserPoolClientId: !Ref CognitoUserPoolClient
            UserPoolDomain: !Ref CognitoUserPoolDomain
        - Type: forward
          Order: 2
          TargetGroupArn: !Ref ExistingTargetGroupArn
      Conditions:
        - Field: host-header
          Values: 
            - !Ref DomainName
      ListenerArn: !Ref ExistingALBListenerArn
      Priority: 1

Outputs:
  UserPoolDomain:
    Description: Domain of the Cognito User Pool
    Value: !Ref CognitoUserPoolDomain
  CallbackURL:
    Description: Callback URL for the Cognito User Pool Client
    Value: !Sub https://${DomainName}/oauth2/idpresponse

パラメータにメールドメイン名と送信者の名前を指定し、スタックを更新します。
cm-hirai-screenshot 2024-09-25 9.46.09

設定後、テストメールを送信すると、指定したSESのメールドメインから正常に送信されることが確認できました。
cm-hirai-screenshot 2024-09-25 10.05.31

SES との統合により、組織のドメインからカスタマイズされたメールを送信できるようになり、ユーザーの信頼を得やすくなるとともに、Cognitoのデフォルトのメール送信数制限を超えて、より大量のメール配信が可能になります。

CloudFormationではなく、マネジメントコンソールから対応する場合は以下の記事を参考ください。

https://dev.classmethod.jp/articles/cognito-ses-domain-email-2023/

最後に

本記事では、Amazon Cognito ユーザープールを CloudFormation を使用して構築し、さらに ALB との統合、カスタムドメインの設定、SES を用いたメール送信の設定まで、一連の流れを解説しました。
以下が今回のポイントです。

  1. CloudFormation を使用することで、Cognito ユーザープールの作成から各種設定まで、インフラストラクチャをコードとして管理できます。

  2. 管理者主導のユーザー登録プロセスを実現し、セキュアなユーザー管理を可能にしました。

  3. ALB との統合により、アプリケーションへのアクセス制御を簡単に実装できます。

  4. カスタムドメインの設定により、ブランディングを維持しつつ、ユーザーエクスペリエンスを向上させることができます。

  5. SES との統合により、組織のドメインからカスタマイズされたメールを送信できるようになり、ユーザーの信頼を得やすくなるとともに、Cognitoのデフォルトのメール送信数制限を超えて、より大量のメール配信が可能になります。

CloudFormation を使用することで、環境の再現性が高まり、開発からテスト、本番環境への展開がスムーズになります。

参考

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpool.html

https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/user-pool-email.html

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.