Use Ansible to Setup Google MX Records
We've all done it. After purchasing that shiny new domain name from our favorite registrar (one of mine happens to be namecheap), we go to set it up. Part of that setup likely includes changing the domain's MX records to point to "your own" mail servers, of which there is a good chance that "your own" actually means Google owned:
- ASPMX.L.GOOGLE.COM. 1
- ALT1.ASPMX.L.GOOGLE.COM. 5
- ALT2.ASPMX.L.GOOGLE.COM. 5
- ASPMX2.GOOGLEMAIL.COM. 10
- ASPMX3.GOOGLEMAIL.COM. 10
Ah, a list familiar to most of us. So up to this point, it's been a manual process for me (I know... shame on me). But, today, I decided setting up domain MX records manually would end. Ansible to the rescue! Everything is built into the current version:
ansible --version
ansible 2.7.9
Thus no external modules are required. The only required module https://docs.ansible.com/ansible/latest/modules/cloudflare_dns_module.html is built in. I'll show how to do this both from a plain playbook standpoint (since I did it that way first), and then using a role.
Playbook Method
The Ansible play is a simple one and consists of only 2 files, cloudflare_google_mx.yml and cloudflare.yml. The main playbook is as simple as this:
$ more playbook/cloudflare_google_mx.yml
---
- hosts: localhost
vars_files:
- "{{ playbook_dir }}/../vars/cloudflare.yml"
tasks:
- name: Create Google MX Records
cloudflare_dns:
zone: "{{ zone }}"
name: "{{ zone }}"
record: "{{ item.server }}"
value: "{{ item.server }}"
type: MX
priority: "{{ item.priority }}"
account_email: "{{ email }}"
account_api_token: "{{ cloudflare.apikey | replace('\n', '') }}"
state: present
loop:
- { server: ASPMX.L.GOOGLE.COM., priority: 1 }
- { server: ALT1.ASPMX.L.GOOGLE.COM., priority: 5 }
- { server: ALT2.ASPMX.L.GOOGLE.COM., priority: 5 }
- { server: ASPMX2.GOOGLEMAIL.COM., priority: 10 }
- { server: ASPMX3.GOOGLEMAIL.COM., priority: 10 }
And the cloudflare.yml file under var_files
holds an encrypted version of my cloudflare api key.
$ more vars/cloudflare.yml
---
cloudflare:
apikey: !vault |
$ANSIBLE_VAULT;1.1;AES256
65633238643730616136353238616464313063336131396338633066653231653464333733396330
3166613930386639653332333162383963333164303665380a373539616361633362653363636637
66343331666132356562333262626333396137363739313436343134666235363136336536333263
3035373738623963630a346330386630313530643162303263303738633961303066316539373533
31316632306438323334653332386662643962396637316237306536613766663164326336333861
3264366265333866393830326363383937383830383564386466
Role Method
If you instead want to install a role, I've made one available on Ansible Galaxy (Ansible's role repository):
https://galaxy.ansible.com/june07/ansible_cloudflare_google_mx
After installing the role via:
ansible-galaxy install june07.ansible_cloudflare_google_mx
You could then simply replace the tasks:
section in your playbook/cloudflare_google_mx.yml
playbook file with roles:
instead, like this:
---
- hosts: localhost
vars_files:
- "{{ playbook_dir }}/../vars/cloudflare.yml"
roles:
- june07.cloudflare-google-mx
What's Going On
Because of the number (COUNT THEM... FIVE) of MX records that Google recommends in it's G Suite Admin documentation, I decided a loop would be useful in providing the neccessary server/priority values to the task I named "Create Google MX Records", which in turn is simply calling the cloudflare_dns module that Michael Gruener (@mgruener) contributed.
The Ansible command that brings it all together is:
ansible-playbook -e "zone=mydomain.com [email protected]" playbook/cloudflare_google_mx.yml --vault-password-file ./.vault.json
Per the documentation for the module, there are 3 required parameters. The Cloudflare API Key, the zone (mydomain.com
), and the account_email ([email protected]
). Everything else found under the loop variables will remain the same regardless of which new domain is setup. In the future when I decide to grab that newer, shinier domain name, with grandious plans of what it will serve as a beginning to, setting up Google MX Records will now be that simple.
ansible-playbook -e "zone=newershinierdomain.com [email protected]" playbook/cloudflare_google_mx.yml --vault-password-file ./.vault.json
No more time waste with manually setting these DNS records up manually. Done!