Here at RevSys we've been moving away from Chef and using SaltStack for all our new server setups. Salt is still pretty new and while I run into bugs every now and again, they're releasing new versions with fixes at an impressive rate.

Today I want to show you how to setup a new server with Postfix and Mailgun in a reusable way. This tutorial assumes that you already have a working Salt setup.

The steps are pretty easy, we need to:

Install postfix and sasl Configure postfix to use our Mailgun account for it's SMTP relay server

We'll make this salt state easily reusable by having the Mailgun credentials and optional email alias configurable with Salt Pillar data.

Setup Pillar Data

So first we'll setup the Pillar data. For the purposes of the tutorial we'll assume we are setting up the server 'example.revsys.com'.

We'll add:

mailgun_username: example@example.mailgun.org mailgun_password: MySillySecretPassword mailgun_alias_file: example/templates/example_mail_aliases `

To the pillar data. This could be a separate per server pillar file that /srv/pillar/example.sls or a more reusable /srv/pillar/mailgun.sls depending on how you want to do it.

Setup Salt State File

Then we create a mailgun state in /srv/salt/mailgun/init.sls:

postfix : pkg : - installed - names : - postfix - libsasl2 - modules service : - running - require : - pkg : postfix - watch : - file : /etc/postfix/ main . cf /etc/postfix/ main . cf : file . managed : - source : salt :// mailgun /templates/ main . cf - user : root - group : root - mode : 644 - require : - pkg : postfix /etc/postfix/s asl_passwd : file . managed : - source : salt :// mailgun /templates/s asl_passwd - user : root - group : root - mode : 600 - template : jinja - context : username : {{ pillar [ 'mailgun_username' ] }} password : {{ pillar [ 'mailgun_password' ] }} - require : - pkg : postfix cmd . wait : - name : postmap /etc/postfix/s asl_passwd - user : root - watch : - file : /etc/postfix/s asl_passwd - watch_in : - service : postfix {% if pillar . get ( 'mailgun_alias_file' , False ) %} /etc/ aliases : file . managed : - source : salt ://{{ pillar [ 'mailgun_alias_file' ] }} - user : root - group : root - mode : 600 - template : jinja - require : - pkg : postfix cmd . wait : - name : newaliases - user : root - watch : - file : /etc/ aliases {% endif %}

How this works

What it does is pretty simple. We install postfix and sasl. Then push out a main.cf template that adds the configuration necessary to have postfix use mailgun as an SMTP relay. Those configuration options are well documented by Rackspace in this post on Configuring Postfix for Mailgun and Sendgrid. You just need to add this to bottom of the default main.cf:

smtp_sasl_auth_enable = yes relayhost = smtp.mailgun.org smtp_sasl_security_options = noanonymous smtp_sasl_password_maps=hash:/etc/postfix/sasl_passwd

Our Salt State then creates the file /etc/postfix/sasl_password using a template that looks like:

smtp.mailgun.org {{ username }} : {{ password }}

Which is built using the Pillar data we created above and can customize on a per host/role basis if necessary. And then optionally we can define an aliases file which will replace /etc/aliases and run the standard newaliases command. We're using cmd.wait here to only rebuild the sasl_passwd map and optional aliases if those files have changed. The watch_in command then restarts postfix if we add or change the sasl_password.

Targeting

To actually deploy this again a server then all you need to do is adjust your /srv/salt/top.sls to include the state like so:

base: 'example.revsys.com': - mailgun

Obviously along with whatever other targeting configuration you have setup already.

Hope this helps you get SMTP relaying with Mailgun up and running a bit faster!