A Terraform module for creating a Mailgun domain, Route53 Zone, and corresponding DNS records
This project automates the following setup on AWS Route 53:
https://documentation.mailgun.com/quickstart-sending.html#verify-your-domain
Sending & Tracking DNS Records created by this module:
Type | Value | Purpose |
---|---|---|
TXT | “v=spf1 include:mailgun.org ~all” | SPF (Required) |
TXT | This value is dynamic | DKIM (Required) |
CNAME | “mailgun.org” | Tracking (Optional) |
Receiving MX Records Records created by this module (optional, see use of mailgun_set_mx_for_inbound
variable below) :
Type | Value | Purpose |
---|---|---|
MX | mxa.mailgun.org | Receiving (Optional) |
MX | mxb.mailgun.org | Receiving (Optional) |
From the mailgun docs:
Do not configure Receiving MX DNS records if you already have another provider handling inbound mail delivery for your domain (e.g. Gmail). Instead we recommend using a subdomain on Mailgun (e.g. mg.yourdomain.com)
To disable the creation of the MX records, set the terraform variable mailgun_set_mx_for_inbound
to false
.
You'll need your Mailgun API Key, found in your control panel homepage.
Sign up: https://mailgun.com/signup
Control Panel: https://mailgun.com/cp
Mailgun domains do not support terraform import
, so you need to let this module
create the mailgun domain for you, otherwise you end up manually editing your
state file which probably won't end well.
https://www.terraform.io/downloads.html
or mac users can brew install terraform
Utilize this module in one or more of your tf files:
aws_region = "us-east-1"
domain = "big-foo.com"
mailgun_api_key = "key-***********"
mailgun_smtp_password = "*********"
provider "aws" {
region = "${var.aws_region}"
}
provider "mailgun" {
api_key = "${var.mailgun_api_key}"
}
variable "aws_region" {}
variable "domain" {}
variable "mailgun_api_key" {}
variable "mailgun_smtp_password" {}
module "mailer" {
source = "github.com/samstav/terraform-mailgun-aws"
domain = "${var.domain}"
mailgun_smtp_password = "${var.mailgun_smtp_password}"
}
Before running your plan, fetch the module with terraform get -update
Once your definition(s) are complete:
# This downloads and installs modules needed for your configuration.
# See `terraform get --help` for more info
$ terraform get -update
# This generates an execution plan for terraform. To save this to a file you need to supply -out.
# To generate a plan *only* for this module, use -target=module.mailer
# See `terraform plan --help` for more info.
$ terraform plan -out=mailer.plan
# This builds or changes infrastructure according to the terraform execution plan.
# See `terraform apply --help` for more info.
$ terraform apply mailer.plan
To pin your configuration to a specific version of this module, use the ?ref
param and change your source
line to something like this:
source = "github.com/samstav/terraform-mailgun-aws?ref=v1.1.0"
See releases.
There are two different approaches when using an existing Route53 Zone with this module. The first, and simplest approach, is to set the zone_id
variable. This module detects the presence of this value and will presume the existence of your Route53 zone. It will use then use (and modify the records on that zone) rather than creating a new zone for you.
The second approach is to import your existing Route53 zone (by id) into the terraform-mailgun-aws
module using terraform import
. The fundamental difference with this approach is that your zone will now be tracked and managed as a resource component of this module. Every terraform run (plan/apply) will then check the existence and state (configuration) of the zone. This has some advantages, primarily in the case that you want terraform to destroy and/or re-create the zone without needing to hard-code the new Route53 Zone ID.
To import your existing zone into this module:
$ terraform import module.mailer.aws_route53_zone.this[0] <your_route53_zone_id>
(The [0]
is needed because it is a "conditional resource" and you must refer to the 'count' index when importing, which is always [0])
The mailer
portion is the name you choose for the module instance, e.g.:
module "mailer" {
source = "github.com/samstav/terraform-mailgun-aws"
}
To find the zone id for your existing Route53 Hosted Zone:
$ aws route53 list-hosted-zones-by-name --dns-name big-foo.com
This module outputs the Route53 Zone ID, as well as the NS record values (the nameservers):
To refer to these outputs, use "${module.mailer.zone_id}"
or "${module.mailer.name_servers}"
...
resource "aws_route53_record" "root" {
# refer to your zone id like so
zone_id = "${module.mailer.zone_id}"
name = "${var.domain}"
type = "A"
alias {
name = "s3-website-us-east-1.amazonaws.com."
zone_id = "********"
evaluate_target_health = true
}
}
Route resources are not available in the mailgun terraform provider, so we do it with the included script.
$ ./main.py create-route big-foo.com --forward bigfoo@gmail.com
{
"message": "Route has been created",
"route": {
"actions": [
"forward(\"bigfoo@gmail.com\")"
],
"created_at": "Sun, 01 Jan 2017 18:21:16 GMT",
"description": "Forward all mailgun domain email to my specified forwarding location(s).",
"expression": "match_recipient(\".*@big-foo.com\")",
"id": "84jfnnb3oepoj85jhbaae4f6",
"priority": 1
}
}
See ./main.py create-route --help
for more options on creating routes.
Make sure the nameservers (the values on your NS record in your zone) match the nameservers configured at your registrar.