Cross-Account Usage of Amazon Simple Email Service (SES) — Route All Your Emails via a Single AWS Account in a Multi-Account Setup

It’s fairly common in enterprises to have multiple AWS accounts for different environments: dev/test, staging/QA, prod/preprod, etc. Often there’s a shared services account which hosts all services that other accounts need. One such service is sending emails. This article explains how to set up SES in the shared account & use it to send emails from a Lambda function running in the dev or prod account.

Step 1 — Identity Policy

After you have verified a domain or email address in SES in the shared account, create an identity policy for it, as shown below:

The finished policy looks like this:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "arn:aws:ses:ap-south-1:210987654321:identity/sample@example.com"
        }
    ]
}

Step 2 — Send Email

Use the following Python code to send email from a Lambda function. Ensure that the Lambda execution role has permissions to use SES.

import boto3
client = boto3.client('ses', region_name = "ap-south-1")
def lambda_handler(event, context):
    client.send_email(
        Source = 'sample@example.com',
        SourceArn = 'arn:aws:ses:ap-south-1:210987654321:identity/sample@example.com',
        Destination = { 'ToAddresses': [ 'someone@gmail.com' ] },
        Message = {
            'Subject': { 'Data': 'Test Email' },
            'Body': { 'Html': { 'Data': 'Test Email' } }
        }
    )