Skip to content

Commit 1f6bedb

Browse files
authored
Merge pull request #5 from futurice/add-aws-ses-forwarder
Add AWS SES forwarder module
2 parents dea0328 + ff7d9e4 commit 1f6bedb

File tree

11 files changed

+764
-0
lines changed

11 files changed

+764
-0
lines changed

aws_ses_forwarder/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/lambda.zip

aws_ses_forwarder/README.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# aws_ses_forwarder
2+
3+
This module implements a simple, serverless email forwarding service for your custom domain.
4+
5+
Main features:
6+
7+
- MX records for email routing are created automatically
8+
- DKIM records are set up to improve deliverability
9+
- Automatic verification of recipient emails
10+
11+
Optional features:
12+
13+
- Custom "From" address for forwarded emails
14+
- Custom prefix added to "Subject" fields of forwarded emails
15+
- Skipping recipient verification when [out of the SES Sandbox](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/request-production-access.html)
16+
17+
Resources used:
18+
19+
- Route53 for DNS entries
20+
- S3 for temporary email storage
21+
- Lambda for performing email routing
22+
- SES for email ingress and egress
23+
- IAM for permissions
24+
25+
The JavaScript code used on the Lambda is based on the excellent [`aws-lambda-ses-forwarder`](https://github.com/arithmetric/aws-lambda-ses-forwarder) library.
26+
27+
## SES Sandbox limits
28+
29+
By default, to discourage spammers, SES will limit you to forwarding **at most 200 emails per a 24 hour period** (or 1 email per second).
30+
31+
To go beyond these limits, you need to [request a service limit increase from AWS](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/request-production-access.html).
32+
33+
## Example 1: Simple forwarding
34+
35+
Assuming you have the [AWS provider](https://www.terraform.io/docs/providers/aws/index.html) set up, and a DNS zone for `example.com` configured on Route 53:
36+
37+
```tf
38+
module "my_email_forwarder" {
39+
# Available inputs: https://github.com/futurice/terraform-utils/tree/master/aws_ses_forwarder#inputs
40+
# Check for updates: https://github.com/futurice/terraform-utils/compare/v12.1...master
41+
source = "git::ssh://[email protected]/futurice/terraform-utils.git//aws_ses_forwarder?ref=v12.1"
42+
43+
email_domain = "example.com"
44+
forward_all_to = ["[email protected]"]
45+
}
46+
```
47+
48+
After `terraform apply`, SES will send a verification email to all recipient emails you included. Each recipient must click on the verification link in that email before they start receiving forwarded emails. This is a feature of [the SES Sandbox](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/request-production-access.html), and you can get rid of it by contacting AWS support (and then setting `skip_recipient_verification` to `true`).
49+
50+
Once the emails are verified, drop an email to `[email protected]`, and it should pop into the inbox of `[email protected]`.
51+
52+
## Example 2: Forwarding specific mailboxes
53+
54+
You can also have specific mailboxes forward email to specific addresses:
55+
56+
```tf
57+
module "my_email_forwarder" {
58+
# Available inputs: https://github.com/futurice/terraform-utils/tree/master/aws_ses_forwarder#inputs
59+
# Check for updates: https://github.com/futurice/terraform-utils/compare/v12.1...master
60+
source = "git::ssh://[email protected]/futurice/terraform-utils.git//aws_ses_forwarder?ref=v12.1"
61+
62+
email_domain = "example.com"
63+
64+
forward_mapping = {
65+
sales = ["[email protected]"]
66+
admin = ["[email protected]"]
67+
}
68+
}
69+
```
70+
71+
Once applied, and recipients verified:
72+
73+
- Emails sent to `[email protected]` are forwarded to `[email protected]`
74+
- Emails sent to `[email protected]` are forwarded to `[email protected]`
75+
76+
This can be combined with `forward_all_to`, so that instead of getting a bounce for sending email to a non-existent mailbox, those emails also get forwarded somewhere.
77+
78+
## Example 3: Multiple instances
79+
80+
Due to the way AWS SES works, [there can be only one active receipt rule set at a time](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-managing-receipt-rule-sets.html#receiving-email-managing-receipt-rule-sets-enable-disable). Normally this module manages the rule set for you, and you don't need to care. But if you need to use the module multiple times (say, for several domains), they can't both have their rule sets be the active one, and you need to manage the rule set yourself:
81+
82+
```tf
83+
resource "aws_ses_receipt_rule_set" "forwarding" {
84+
rule_set_name = "my-forwarding-rules"
85+
}
86+
87+
resource "aws_ses_active_receipt_rule_set" "forwarding" {
88+
rule_set_name = aws_ses_receipt_rule_set.forwarding.rule_set_name
89+
}
90+
91+
module "my_email_forwarder" {
92+
# Available inputs: https://github.com/futurice/terraform-utils/tree/master/aws_ses_forwarder#inputs
93+
# Check for updates: https://github.com/futurice/terraform-utils/compare/v12.1...master
94+
source = "git::ssh://[email protected]/futurice/terraform-utils.git//aws_ses_forwarder?ref=v12.1"
95+
96+
rule_set_name = aws_ses_receipt_rule_set.forwarding.rule_set_name
97+
email_domain = "example.com"
98+
forward_all_to = ["[email protected]"]
99+
}
100+
101+
module "other_email_forwarder" {
102+
# Available inputs: https://github.com/futurice/terraform-utils/tree/master/aws_ses_forwarder#inputs
103+
# Check for updates: https://github.com/futurice/terraform-utils/compare/v12.1...master
104+
source = "git::ssh://[email protected]/futurice/terraform-utils.git//aws_ses_forwarder?ref=v12.1"
105+
106+
rule_set_name = aws_ses_receipt_rule_set.forwarding.rule_set_name
107+
email_domain = "example.org"
108+
forward_all_to = ["[email protected]"]
109+
}
110+
```
111+
112+
<!-- terraform-docs:begin -->
113+
114+
<!-- terraform-docs:end -->

aws_ses_forwarder/data.tf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
resource "random_string" "name_suffix" {
2+
length = 8
3+
special = false
4+
upper = false
5+
}
6+
7+
locals {
8+
# If an external name_prefix wasn't provided, use the default one with a random suffix (to prevent clashes on resources that require globally unique names)
9+
name_prefix = var.name_prefix == "" ? "aws-ses-forwarder-${random_string.name_suffix.result}" : var.name_prefix
10+
}
11+
12+
# Provides details about the current AWS region
13+
data "aws_region" "this" {}
14+
15+
# Use this data source to get the access to the effective Account ID, User ID, and ARN in which Terraform is authorized
16+
data "aws_caller_identity" "this" {}
17+
18+
data "aws_route53_zone" "this" {
19+
name = replace(var.email_domain, "/.*?\\b([\\w-]+\\.[\\w-]+)\\.?$/", "$1") # e.g. "foo.example.com" => "example.com"
20+
}

0 commit comments

Comments
 (0)