• Stars
    star
    3,022
  • Rank 14,935 (Top 0.3 %)
  • Language
  • License
    MIT License
  • Created almost 6 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

📫 A serverless email server on AWS using S3 and SES

How to support the project

This solution is free for anyone to use and learn from. If you’d like to see more projects like this one, consider using some of our products from the AWS Marketplace or share them with someone you might think would be interested in using them.

📫 S3 Email

This stack was created out of frustration due to the fact that to this day there's no easy way to have a full email server without the overhead of installing and configuring all servers needed to handle incoming and outgoing messages. We wanted something simple, with no interface and no server management, so we came up with S3-Email. This included AWS SES as our email server (receive and send) and S3 as our database and interface. Then we tied everything together with a bit of code via AWS Lambda.

The result is an unmanaged email server with unlimited email addresses that also offers the benefit of easily organizing messages by adding the + character to the email names. The + is converted to a /, which correlates to an object path in S3.

Endless email addresses

Once you add and confirm your domain with SES, you can put any string you want in front of the @, as long as it conforms to the email address standard. This means that you'll have endless email addresses at your disposal, and you'll be able to organize your life in a way never possible before. For example, you can give each service you sign up for its own special email:

Organizing with a +

With that said, you can organize your emails with the + character in this way:

When dealing with clients we came up with this folder structure:

For all sorts of alerts we like to group them like this

This groups all emails in the corresponding folder by replacing the + with a / character which creates a folder structure in S3. The possibilities are endless.

Basically, receive and send email with some skills.

DISCLAIMER!

This stack is available to anyone at no cost, but on an as-is basis. 0x4447 LLC is not responsible for damages or costs of any kind that may occur when you use the stack. You take full responsibility when you use it.

How to deploy

All you need to do to deploy this stack is click the button to the left and follow the instructions that CloudFormation provides in your AWS Dashboard. Alternatively you can download the CF file from here.

What will deploy?

S3-Email Diagram

The stack takes advantage of AWS S3, AWS SES, AWS Lambda, and the AWS Trigger system to tie everything together. You'll get:

  • 1x SES Rule Sets
  • 2x S3 Bucket
    • 1x for CodePipeline to store artifacts
    • 1x for the emails
  • 3x CodePipelines
  • 3x CodeBuilds
  • 3x Lambdas
  • 1x IAM Group

All project resources can be found here.

Auto deploy

The stack is set up in a such a way that any time new code is pushed to a selected branch, the CodePipeline picks up the change and updates the Lambda for you. These are the available branches:

  • master: the latest stable code
  • development: unstable code that we test in our test environment - we don't recommend that you use this branch

Manual work

Keep in mind that when you deploy, everything may not work right out of the box.

Confirm to SES that you own the domain

You have to add your domain and confirm that you own it. Follow these steps to do so:

  1. Go to the SES Dashboard.
  2. Click Domains on the left side menu.
  3. Click the blue Verify a New Domain button.
  4. Type your domain in the modal and select Generate DKIM Settings.
  5. The next window displays all information needed to configure your domain.
  6. Once finisheds, you'll wait some time for the domain to switch from a pending verification status to a verified status.

Enable SES Rule Sets

Deployment creates SES rule sets. This should be enabled by default on fresh AWS accounts, but on accounts where you already had some rules, this won't work. This behavior is a known bug by AWS in CloudFormation. Taking the following steps will enable the rule:

  1. Go to the SES Dashboard.
  2. Click Rule Sets on the left side menu.
  3. Check 0x4447_S3_Email on the Inactive Rule Sets tab.
  4. Hit Set as Active Rule Set to activate the rule.

Attach user to the IAM Group

After the stack is deployed you'll get a IAM Group with a policy attached that will give a user using it the bare minimum to access to the S3-Bucket to read and create emails.

SES Limitations

There are two major limitations with SES:

  1. For security reasons, AWS defaults to 200 emails sent per 24 hour period at a rate of 1 email/second. If you need to send more than that, you'll need to ask AWS to increase your limit.
  2. By default, you can't send emails to unverified addresses. If you'd like to be able to send (as opposed to just receiving), you'll need to reach out to AWS to remove this limitation from your account.

How the stack works

Receiving email:

  1. An email comes to SES and and it gets stored in TMP S3 folder.
  2. S3 will trigger the Inbound Lambda Function which will organize the email based on the to, from and date fields. In addition to that, the Lambda will read the domain(s) added to SES, and will use that data to determine if the email should land in the Inbox or Sent folder. If the to fields contains the domain from SES, it goes to the Inbox, if not, it is assumed the email was sent out.
  3. The Inbox or Sent folder triggers another Lambda function that loads the raw email, converts it to a .html and .txt file, and stores it alongside the original message, while storing any attachments in the attachments.

In addition to this flow, when a new email comes in, a copy of it will be saved in the Today folder to show you which emails are new. The S3 bucket has a Life Cycle Policy and will delete any email older than one day from the Today folder. This way you always know what's new.

Sending email:

  1. Create a properly formatted JSON file (see the following section).
  2. Save the file to the path TMP/email_out/json. The file name and extension are irrelevant as long as the content is text and JSON formatted.
  3. This action triggers a Lambda that generates a raw email, sends it out using SES, and saves the raw message to the Sent folder.
  4. The Sent folder triggers another Lambda function that loads the raw email, converts it to a .html and .txt file, and stores it alongside the original message.

This flow was designed to take advantage of the S3 trigger system and break each action into a small Lambda.

How to create an email message

Create a custom JSON file, then upload it to the TMP/email_out/json folder (if you don't have the folder structure yet, set it up). The JSON structure should look like this:

{
	"from": "[email protected]",
	"to": "[email protected]",
	"subject": "From SES",
	"html": "Write a nice message to whoever you are sending this message to.",
	"text": "Write a nice message to whoever you are sending this message to."
}

Remember that the from field must contain the domain you added to SES. You won't be able to send emails from unverified domains.

Backup old emails

A bonus feature of this stack is the possibility to process manually uploaded emails. This is possible thanks to the event driven nature of the stack. Just upload the raw email in the TMP/email_in folder, and your emails will be processed automatically.

The only prerequisite is that the email file needs to be the raw representation of the email itself. For example: files ending in .eml are nothing more than a txt file with the raw content of the email.

Which means you can just upload those files straight up to the S3 bucket.

Pricing

All resources deployed via this stack will potentially cost you money. But you'd have to do the following for this to happen:

  • Invoke Lambdas over 1,000,000 times a month
  • Send and receive over 1000 emails a month
  • Perform over 10,000 Get and Put operations and over 2000 Delete operations in your S3 Bucket
  • Exceed 100 build minutes on CodeBuild
  • $1 per active CodePipeline (must run at least once a month to be considered active)

The only payment you'll encounter from Day One is an S3 storage fee for emails and CodePipeline artifacts.

How to work with this project

When you want to deploy the stack, the only file you should be interested in is the CloudFormation.json file. If you'd like to modify the stack, we recommend that you use the Grapes framework, which was designed to make it easier to work with the CloudFormation file. If you'd like to keep your sanity, never edit the main CF file 🤪.

The End

If you enjoyed this project, please consider giving it a 🌟. And check out our 0x4447 GitHub account, where you'll find additional resources you might find useful or interesting.

Sponsor 🎊

This project is brought to you by 0x4447 LLC, a software company specializing in building custom solutions on top of AWS. Follow this link to learn more: https://0x4447.com. Alternatively, send an email to [email protected].

More Repositories

1

0x4447-cli-node-grapes

🍇 This is a small framework to make it easier to work with AWS CloudFormation files.
JavaScript
46
star
2

0x4447_product_answering_machine

☎️ An automated answering machine build on top of Amazon Connect
40
star
3

0x4447_product_synology_backup

🛢 This stack will deploy all that is necessary to enable S3 Glacier backup for your Synology.
22
star
4

0x4447_product_secure301

🚧 A stack that will allow you to redirect one domain over HTTPS to another.
15
star
5

0x4447_product_s3_email_lambda_converter

📫 part of the S3-Email product.
JavaScript
8
star
6

0x4447_docker_static

Point to a folder with a static website, and you will get it delivered over HTTPS locally, for easy development.
Shell
7
star
7

0x4447_product_s3_email_lambda_inbound

📫 part of the S3-Email product.
JavaScript
6
star
8

0x4447_product_s3_drive_private

💾 A stack to create a basic network drive using S3, while enabling all the useful features to make the experience complete.
4
star
9

0x4447_product_s3_email_lambda_outbound

📫 part of the S3-Email product.
JavaScript
4
star
10

0x4447_product_s3_drive_self_destruct

💣 This stack will create a S3 bucket where every object by default is public, with a customizable expiration date for all the object.
3
star
11

0x4447_product_aws_artifacts

💠 A standard configuration for a S3 bucket for CodePipeline with auto deletion so the artifacts don't pile up.
3
star
12

0x4447_product_answering_machine_name_get

☎️ An automated answering machine build on top of Amazon Connect
JavaScript
2
star
13

0x4447_product_answering_machine_message

☎️ An automated answering machine build on top of Amazon Connect
JavaScript
2
star
14

0x4447_product_drive_efs

This stack deploys a EFS drive with backup setup automatically and with the right Security Group.
1
star
15

0x4447_product_vpc

🗳 A basic template that deploys a custom VPC with a default configuration
1
star
16

0x4447_product_ec2_hibernation_lambda

Periodically check the CPU load of a EC2 instance and hibernate it to preserve costs.
JavaScript
1
star
17

0x4447_product_answering_machine_notification

☎️ An automated answering machine build on top of Amazon Connect
JavaScript
1
star
18

0x4447_product_cloud_video_editing

🧮 This stacks deploys a video editing setup based on Nvidia CUDA.
1
star
19

0x4447_product_simple301_lambda_redirect

🚧 A stack that will allow you to redirect one domain over HTTPS to another.
JavaScript
1
star