Send and Receive Emails with Amazon Simple Email Service (SES), Without an Actual Mailbox

Roy Ben Yosef
CyberArk Engineering
6 min readJul 20, 2021
Photo by Tim Mossholder on Unsplash

I wanted to share how you can send and receive emails using Amazon Simple Email Service (SES) — without having an actual mailbox. You might be asking “why would I want to do that?” and one possible answer would be interacting with a user using email, for example, in some serverless workflow.

The actual use case is really up to you. I will stick to the technical capabilities: How to send and receive emails using SES without an actual mailbox.

The Problem with Email Verification

When using SES, you are required to verify email addresses (unless you “get your account out of sandbox”). This is all well when you are using an actual email account, but what if you don’t want to or can’t use one? This step-by-step guide will show you how to verify, and then receive emails, using SES without using an actual email account.

Prerequisites

  • Be able to create an S3 bucket, Lambda functions, and configure SES.
  • Be able to register a domain with Route 53, to send and receive emails, you will need a verified domain. While it is possible to accomplish this with a domain from another registrar, the easiest way is to register it with AWS Route 53, which I will show next.
Photo by Filip Urban on Unsplash

Let’s Get to Work

To send emails with any email address under our domain you will need:

  • A registered domain, verified in SES.

To receive emails to any email address under our domain you will need:

  • The same registered domain, verified in SES.
  • To create MX and TXT records in the Hosted Zone for your domain.
  • To create and configure receipt rules in SES.

Register a Domain with AWS Route 53

There is a fee for registering a domain. The cost varies (from as little as $10 per year), depending on which top-level domain you choose to register.

It’s best to follow this AWS guide for registering a new domain, but I’ve summarized the main points here:

  • In Route 53, under domain registration, verify your domain name availability. Note the different price for each top-level domain, and add it to the cart.
  • Fill in your contact details, and optionally enable “Privacy Protection” for extra WHOIS privacy.
  • Enable/disable auto-renewal for this domain according to your needs, accept the terms and conditions and complete the order.
  • Route 53 states that “Domain registration might take up to three days to complete.” You will receive an email when it’s registered or if there’s a problem. You can view the registration status under “Domains, Pending Requests”. All of my attempts went through within 15 minutes.
  • If you’re having problems, you might need to verify your payment.
  • IMPORTANT: Make sure that your domain is registered before proceeding.

Verify Your Domain with SES

To verify your domain with SES based on this guide, do the following:

  • In the SES console, under “Domains”, “Verify a new domain,” enter your domain name (e.g. domain.com and NOT www.domain.com,) click “Verify this domain.”
  • Note the MX and TXT records that are required. Since we are using Route 53, simply click on “Use Route 53,” and it will create them for you. Note the warning: it will replace all MX records for the domain. Otherwise, you can create records manually with the information on this page.
  • Assuming you have all records in place, after a short while your domain status under SES “Domains” will change to “Verified.”

Manually Create an MX/TXT Record for Your Domain

It’s best to have Route 53 create the MX records for you. But if you need to create them yourself, follow this guide, which is summarized below.

  • In the Route 53 console, under “Hosted Zones”, click on your domain.
  • Leave the “Record Name” field empty so that your record name is your domain name.
  • Set “Record Type” to MX.
  • Set the value to “10 inbound-smtp.us-east-1.amazonaws.com”, replace “us-east-1” if you are using this region to receive emails with SES. Otherwise, for a list of SES endpoints, see this and this. In case you are wondering, the “10” is a priority for email servers.
  • Create the record.
  • The process for creating TXT records is similar — just use the proper values from the domain verification page in SES.

Verify an External Email Address for Testing

Later in this guide, we will send test emails to an external email address that must be verified:

  • In the SES console, under “Email addresses,” “Verify a new email address”, enter your external email.
  • After you receive the email, click the “Verify” link, and you can see that the status changed to “Verified”.

Create an SES Rule Set

To receive emails, we will need to create an ACTIVE rule set in SES:

  • In the SES console, under “Rule Sets”, click on “Create a Rule set” and name your rule set.
  • Make sure that “Make Rule Set Active” is checked. If your rule set is not active, you will not be able to receive emails. Note that it is only possible to have one rule set active at a time.
  • In the “Putting everything to the test” section, we will add actions to handle the incoming email messages.
  • IMPORTANT: Make sure that your rule is showing under “Active Rule Set.” If not, select it and click “Set as Active Rule Set.”

You can now send receive emails. All domain addresses are verified.

Photo by Science in HD on Unsplash

Putting Everything to the Test

Sending Emails

Using AWS CLI:

Create the following file message.json file:

{
"Subject": {
"Data": "Test email sent using the AWS CLI",
"Charset": "UTF-8"
},
"Body": {
"Text": {
"Data": "This is the message body in text format.",
"Charset": "UTF-8"
},
"Html": {
"Data": "This message body contains HTML formatting. It can, for example, contain links like this one: <a class=\"ulink\" href=\"http://docs.aws.amazon.com/ses/latest/DeveloperGuide\" target=\"_blank\">Amazon SES Developer Guide</a>.",
"Charset": "UTF-8"
}
}
}

Run the following command, replacing the destination value with the external email address you verified before and the from value to any email address you want under your domain. Since we verified the domain, we have an umbrella verification to any address under it and any subdomain.

aws ses send-email --destination "ToAddresses=<your-external-verified-email-address>" --message file://message.json --from "<anything-you-want@yourdomain.com>"

You should receive this email at the external, verified address.

Of course, you can do it with your favorite SDK, like boto3 in a lambda or wherever makes sense.

Creating Rule Actions for Receiving Emails

To receive emails, do the following:

  • Create a Lambda that you will process incoming messages.
  • Click “View Active Rule Set” and specify any address under your domain (e.g. sendhere@mydomain.com) that you want to receive emails at (since we verified the domain we can receive at any address), find “Add Recipient” and click “Next Step”.
  • Under “Add Action” select S3 (Take a look at the other interesting options) and either pick an existing S3 bucket or create one in the S3 bucket drop-down menu.
  • Optionally add a prefix for the bucket objects
  • Again, under “Add Action,” select your Lambda. Keep the rest as default and click on “Next”.
  • Name your rule, and make sure it is assigned to the active rule set.

Receiving the Email

Send an email to the address you configured in the last step from the verified external address, and soon enough, you can see it in your S3 bucket as an object that includes all data and attachments encoded in base64.

Your Lambda was also invoked with the message metadata which you can use to fetch everything else from the S3 bucket.

A Few Words on Infrastructure as Code

To keep things simple and focused, I chose to set everything in the AWS console. In a real world scenario, we would always do things as code and not manually. My choice of weapon is the AWS CDK.

Summary

We learned how to use AWS SES to send and receive emails, even without having an actual mailbox which you can verify sending and receiving emails from. This might be useful for some serverless flows and I hope you will find it useful.

Please comment about any use cases you might find this useful for.

--

--

Roy Ben Yosef
CyberArk Engineering

Sr. Software architect at CyberArk’s Technology Office. Into code, architecture and problem solving. Like to build and fix stuff. Usually late at night.