Wednesday, July 12, 2017

Terraform G Suite DNS records

In the previous post I cited automation potential as one of the reasons to change registrars. While it’s a pretty strong reason for cloud admins, it might be a bit obscure for others…

Back in the day Google offered free edition of G Suite (Google Apps for Domain). As I acquired domains and corresponding free G Suite licenses, each required creation of various DNS records for integration. These days G Suite is not free, but plenty of organisations use it and must go through the same process. IaC is a passion of mine, so I decided to hone my Terraform skills and write a module for creation and management of G Suite DNS records. For now this module relies on Cloudflare and their free DNS hosting, in the future I might add support for other DNS hosting services like Route 53.


When building a tool that can do a variety of things, one of the challenging parts is deciding on its default behaviour. Everyone recommends “sane defaults”, but how to decide what's sane? To make life of your end users easier, you have to understand them and their most common uses for your tool. Some users might want only Gmail with their domain; some just want to point their domain to their blog; others want to run their entire company on G Suite with Gmail, Calendar, Contacts, Drive, Calendar, Hangouts, Sites, etc.

I decided not to make assumptions about the most common case and left all features off by default. The only required variable is domain_name of your Cloudflare site (which must be already added to your account). Run terraform apply on the following config and it will do absolutely nothing:
module "my_domain" {
  source      = "github.com/sshvetsov/tf-gsuite-cloudflare"
  domain_name = "yourdomain.com"
}

Want to create a set of MX records for Gmail? Add one more variable:
use_default_mx_records = true

Want to add recommended TXT record for SPF? Add another variable:
use_default_spf_record = true

Want to prevent spoofing by signing your emails with Google generated DKIM key? Easy:
dkim_value = "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."

If secure Gmail is all you’re using G Suites for, similar config should be more than enough:
module "my_domain" {
  source      = "github.com/sshvetsov/tf-gsuite-cloudflare"
  domain_name = "yourdomain.com"

  use_default_mx_records = true  
  use_default_spf_record = true
  dkim_value = "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
}

Want your root/apex/bare domain yourdomain.com redirecting to blog.yourdomain.com, your custom Blogger domain? Voila:
module "my_domain" {
  source      = "github.com/sshvetsov/tf-gsuite-cloudflare"
  domain_name = "yourdomain.com"

  redirect_apex       = true
  custom_cname_names  = ["blog", "jlryza01k1ls"]
  custom_cname_values = ["ghs.google.com", "gv-bgzglgxbgymvbz.dv.googlehosted.com"]
}

Want your Drive, Calendar and Mail to have matching subdomains? Just add this variable:
create_app_cname_records = true

Don’t like my name choices? Want to subdomain to more G Suite services? Sure, just pass the list:
app_cname_names = [
    "webmail",
    "cal",
    "docs",
    "site-a",
    "site-b",
]

Other options are available and almost everything could be customised. Take a look at the examples provided in the repo to get a sense of other possibilities.

Note: I started writing my module as an exercise and only bothered looking around for prior work after it was finished. Surprisingly, my search yielded only one similar project, so hopefully my module will be of benefit to larger community. Enjoy!