Postfix relaying Amazon SES in a Beanstalk PHP application


I’ve been working alot with a customers setup with originally a local sendmail server on Amazon Linux server. This turned out to not work as intended. I have setup a Ubuntu machine with Exim4 relaying Amazon SES for another customer, but unfortunately Amazon Linux doesn’t provide any packages for Exim4, so I had to go with Postfix instead.

The installation was pretty straightforward and the initial setup just includes the smtp settings Amazon provide in their documentation.

[sourcecode language=”bash”]
relayhost = email-smtp.eu-west-1.amazonaws.com:25
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_use_tls = yes
smtp_tls_security_level = encrypt
smtp_tls_note_starttls_offer = yes
[/sourcecode]

Just change the relayhost to whatever Amazon SMTP server you have production access too.

Then the password file has to be created. Because I want to reuse the same Amazon AMI to more than one customer, I can’t make the password file onto the image, and it has to be inserted individually on each Beanstalk application deploy.
I created a small bash script to make that possible. Include that script into the .ebextension directory of the application zip.
Here’s the simple bash script.

[sourcecode language=”bash”]
files:
"/opt/aws/postfix-ses.sh" :
content: |
#!/bin/bash
#
# Configure postfix to relay Amazon SES SMTP servers in EU
PHPINI="/etc/php.d/environment.ini"
PASSWDFILE="/etc/postfix/sasl_passwd"
if [[ -a ${PHPINI} ]]; then
SES_USERNAME=`grep ‘SES_USERNAME’ /etc/php.d/environment.ini | cut -d "=" -f2 | sed -e ‘s/^"//’ -e ‘s/"$//’`
SES_PASSWORD=`grep ‘SES_PASSWORD’ /etc/php.d/environment.ini | cut -d "=" -f2 | sed -e ‘s/^"//’ -e ‘s/"$//’`
echo "email-smtp.eu-west-1.amazonaws.com:25 ${SES_USERNAME}:${SES_PASSWORD}" > ${PASSWDFILE}
if [[ -a ${PASSWDFILE} ]]; then
postmap hash:${PASSWDFILE}
rm -f ${PASSWDFILE}
if [[ -a "${PASSWDFILE}.db" ]]; then
chown root:root "${PASSWDFILE}.db"
chmod 0600 "${PASSWDFILE}.db"
postconf -e ‘smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt’
else
logger "Could NOT find ${PASSWDFILE}.db, postfix configuration failed."
exit 1
fi
else
logger "Could NOT find ${PASSWDFILE}, postfix configuration failed."
exit 1
fi
else
logger "Could NOT find ${PHPINI}, postfix configuration failed."
exit 1
fi
mode: "000755"
owner: root
group: root
[/sourcecode]

What is needed for this to work out as intended then?
First of all, this is a PHP application, so I’m not sure how this would be possible to transfer into a Java application.
As you can see in the script above, I grep for environment variables that is set in Beanstalk software configuration. You can use whatever variable name you want but change the grep lines accordingly. So, the variables are of course the username and password you were given when you signed up for Amazon SES production access. It’s not your normal IAM credentials. Other than that, you’re ready to go.