Skip to content

aws-samples/aws-account-factory-email

aws-account-factory-email

This solution is designed as a way to allows AWS account owners to effectively register more than one AWS account to a single email address by means of a go-between email forwarder.

Background

This solution describes how you can decouple real email addresses from the email address that’s associated with an AWS account. AWS accounts require a unique email address be provided at the time of account creation. In some organizations, the team that manages AWS accounts must take on the burden of managing many unique email addresses with their messaging team. While some organizations do support email sub-addressing, also known as "plus" addressing (explained in RFC 5233), not every organization allows this or can implement this.

This solution provides a unique email address vending solution that enables AWS account owners to associate one email address with multiple AWS accounts. The real email addresses of AWS account owners are then associated with these generated email addresses in a table. The solution handles all incoming email for the unique email accounts, looks up the owner of each account, and then forwards any received messages to the owner.

For a detailed guide on how to implement this solution see Register multiple AWS accounts with a single email address by using Amazon SES.

Solution Diagram

Solution Diagram In this solution there are two flows:

  1. Vend an email address

In the diagram, the email address vending flow (lower section) begins typically with an account vending solution or outside automation, or is invoked manually. In the request, a Lambda function is called with a payload (examples in src/events) that contains the needed metadata. The function uses this information to generate a unique account name and email address, stores it in a DynamoDB database, and returns the values to the caller. These values can then be used to create a new AWS account (typically by using AWS Organizations).

  1. Forward email

This flow is illustrated in the upper section of the previous diagram. When an AWS account is created by using the account email generated from the email address vending flow, AWS sends various emails, such as account registration confirmation and periodic notifications, to that email address. By following the steps in this pattern, you configure your AWS account with Amazon SES to receive emails for the entire domain. This solution configures forwarding rules that allow Lambda to process all incoming emails, check to see if the TO address is in the DynamoDB table, and forward the message to the account owner's email address instead. Using this process gives account owners the ability to associate multiple accounts with one email address.

  1. Read / Update / Delete Email Configuration (not pictured)

Because this is an example of one way this functionality could be created, this solution does not yet implement a read, update, or delete flow that could be used to read the configuration, make modifications or remove mappings. However, an administrator could create more Lambda functions to do this or use the AWS console directly to interact with the Account Table. A recommended pattern is to implement Amazon API Gateway to provide an API for other applications to consume this functionality.

Prerequisites

  • Administrative access to an AWS account
  • Access to a development environment with the AWS CLI and IAM access to your AWS account.
  • Set up and verify a domain name for use in receiving email with Amazon SES
    • You can use sub-domains like mysubdomain.example.com but try to keep the name as short as possible because there is an overall limit to the length of email addresses (64 characters)
    • The domain must be externally resolvable in order for it to receive emails
    • Follow the instructions in Verifying a domain with Amazon SES. Once your domain is verified, it is ready to receive emails

Tools needed for deployment

Pre-Deployment Configuration

  • At minimum, edit SES_DOMAIN_NAME, ACCOUNT_FROM, and ACCOUNT_ADMIN in cdk.json. See the cdk.json section below for more information on each setting
  • Update aws-cdk-lib==xxxx in requirements.txt to match the version which you have installed on your computer. Use cdk --version to get the version number.

cdk.json Settings

The cdk.json file that is located in the root of the this repository tells the CDK Toolkit how to execute your app. There various settings inside this file that control the application's behavior. Most of these settings act like environment variables.

  • SES_DOMAIN_NAME: Set this to the domain in which you want to receive incoming email. You must own and verify this domain to receive email for this domain. This solution does not set up or verify the domain for you, see above.
  • ACCOUNT_TABLE_NAME: This will be the name of the DynamoDB table that is deployed as part of this solution.
  • ADDRESS_FROM: This is the email address that will be used as the FROM address for every email that is forwarded. The domain part (after the '@' sign) must match the SES_DOMAIN_NAME.
  • ADDRESS_ADMIN: This is the email address you wish to use if the solution is unable to find or forward an email to a valid account owner. Emails will be SENT to this email address. Typically customers set this to a shared mailbox that the IT team monitors.
  • MAIL_HEADER_VALUE: This is the value of the X-Processed-By header that is added to every email forwarded through this system
  • COUNTER_LENGTH: This is the length of the number appended to account names (including leading zeros). e.g. this-is-my-account-name-001
  • DISABLE_CATCH_ALL: This setting is not present in cdk.json by default. By adding this setting with any value, it will disable the catch-all behavior and the solution will no longer forward messages where the account owner email is not found. To help prevent a denial of service attack, the catch-all functionality should be disabled. To enable catch-all, ensure this setting is NOT present in cdk.json.

Deployment

This project was written to use the AWS CDK to define and provision the needed infrastructure for the solution. Follow the steps below to deploy the solution.

  1. Clone this repository to your development environment
$ git clone <clone url for this repository>
  1. To manually create a virtualenv (assumes you are in the root of this repository):
$ python -m venv .venv
  1. After the init process completes and the virtualenv is created, you can use the following step to activate your virtualenv.
$ source .venv/bin/activate

Or, if you are a Windows platform, you would activate the virtualenv like this:

% .venv\Scripts\activate.bat
  1. Once the virtualenv is activated, you can install the required dependencies.
$ pip install -r requirements.txt
  1. At this point you can now synthesize the CloudFormation template for this code. This allows you to view the CloudFormation template prior to deployment. If this command succeeds you will see many lines of YAML printed to your scree.
$ cdk synth
  1. To deploy the solution to your account / region, run the following replacing "ACCOUNT-NUMBER" and "REGION":
$ cdk bootstrap aws://ACCOUNT-NUMBER/REGION
$ cdk deploy

Testing Python Code

There are also some basic Python unit tests included that test the solution's core python functions (not the CDK code).

To run the tests, you'll need boto3 and schema python libraries which you can install using pip.

pip install -r tests/requirements.txt

You should now be able to run the tests:

$ pytest

or

$ python -m unittest

Cleanup Steps

Run the following CDK command to remove the deployed infrastructure:

cdk destroy

Alternatively, you can delete the CloudFormation stack "AwsMailFwdStack" through the AWS Console.

CDK Notes

Useful commands

  • cdk ls list all stacks in the app
  • cdk synth emits the synthesized CloudFormation template
  • cdk deploy deploy this stack to your default AWS account/region
  • cdk diff compare deployed stack with current state
  • cdk docs open CDK documentation

Improvement Ideas

  • Implement Read/Update/Delete flows for email address configurations
  • Implement a Dead Letter Queue (DLQ) where undeliverable messages can go for archive or reprocessing

Security

See CONTRIBUTING for more information.

License

This library is licensed under the MIT-0 License. See the LICENSE file.