はじめに

AWS CDKにてCognitoのメール送信設定を行う方法について紹介します。

  • CognitoでEメールを送信する場合
  • Amazon SESでEメールを送信する場合(推奨)

前提

以下のような設定でCDKによるCognito UserPoolを作成することを前提としています。

import * as cdk from 'aws-cdk-lib';
import * as cognito from 'aws-cdk-lib/aws-cognito';
~~
    // Cognito UserPoolの作成
    const userPool = new cognito.UserPool(this, 'MyUserPool', {
      userPoolName: 'my-user-pool',
      passwordPolicy: {
        tempPasswordValidity: cdk.Duration.days(1),
      },
    });

CognitoでEメールを送信する場合

前提に記載した設定でCognito UserPoolを作成すると、Eメール設定は「CognitoでEメールを送信」する設定になります。
コンソール上で確認すると、このような設定になっています。

ただし、返信先を指定したい場合は、emailの設定を以下のように指定します。

    // Cognito UserPoolの作成
    const userPool = new cognito.UserPool(this, 'MyUserPool', {
      userPoolName: 'my-user-pool',
      passwordPolicy: {
        tempPasswordValidity: cdk.Duration.days(1),
      },
      email: cognito.UserPoolEmail.withCognito('reply@example.com'),
    });

注意点

「CognitoでEメールを送信」設定を利用する場合、追加でSESの設定が不要である代わりに、1日に最大50件までしか送信できないといった制約があるため、注意が必要です。
また、この件数は上限緩和不可の値となっているため、本番環境など実際に広く公開して利用する場合には「Amazon SESでEメールを送信」する設定を推奨します。

Amazon SESでEメールを送信する場合(推奨)

「Amazon SESでEメールを送信」する場合は、emailの設定を以下のように指定します。

    // Cognito UserPoolの作成
    const userPool = new cognito.UserPool(this, 'MyUserPool', {
      userPoolName: 'my-user-pool',
      passwordPolicy: {
        tempPasswordValidity: cdk.Duration.days(1),
      },
      email: cognito.UserPoolEmail.withSES({
        fromEmail: 'no-reply@example.com',
        fromName: '送信者テスト',
        sesVerifiedDomain: 'example.com',
      }),
    });

コンソール上で確認すると、このような設定になっています。


※実際にCDKで設定した項目はexample.comではないため、該当箇所はマスクしています

注意点

SESはサンドボックスを解除しておいてください。
送信元に指定するメールアドレスもしくはドメインはSESにて検証しておいてください。

ハマったポイント

この設定を入れる際に、fromEmailを適切に設定するまで少し悩みました。
送信元のEメールアドレスは必須設定となっており、SESで検証したEメールアドレスを指定する必要があります。
一方で、SESではドメインの検証のみ設定としており、no-reply@〜のメールアドレスの検証は実施していない状態でした。

そこで最初は以下のように、fromEmailとfromNameのみ指定してユーザプールを作成していました。

      email: cognito.UserPoolEmail.withSES({
        fromEmail: 'no-reply@example.com',
        fromName: '送信者テスト',
      }),

結果、デプロイは成功したものの、メールが全く送信されなくなってしまいました。

次に、fromEmailにSESで検証済みのドメインを指定してみました。

      email: cognito.UserPoolEmail.withSES({
        fromEmail: 'example.com',
        fromName: '送信者テスト<no-reply@example.com>',
      }),

結果、この設定ではデプロイエラーとなってしまいました。
CDKの裏の処理でCloudFormationがメール送信時のFrom情報を生成しており、その構成が「送信者テスト <no-reply@example.com> < example.com >」のような構成になってしまい、不正な送信元として認識されてしまっていました。(エラーメッセージは、Provided From email address is invalid)

いろいろ試行錯誤しているうちに、CDKのドキュメントにてsesVerifiedDomainなる項目があることを見つけ、上記の設定でうまく送信することができるようになりました。

まとめ

  • CDKでCognito UserPoolを作成するとDefaultではCognitoでEメールを送信する設定となる
    • CognitoでEメールを送信する設定は1日50件までしかメール送信ができないため、一般公開する用途には不向き
  • CDKでCognito UserPoolを作成する際にAmazon SESでEメールを送信する設定にしたい場合は、emailを設定する
    • withSESの指定はfromEmailが必須
    • SESにドメインのみ検証しており、任意のメールアドレスを送信元指定したい場合は、sesVerifiedDomainを指定する

参考リンク