AWS Let’s Encrypt Certificate Auto-renewal w/SNS Notification

My original blog lacked SSL/TLS, and I wanted ensure jessepakin.com was fully fortified and Google friendly. Fortunately, it was not difficult to find and follow instructions for enabling SSL on a Lightsail (Bitnami) WordPress instance using a combination of Let’s Encrypt and Really Simple SSL.

After following the proper procedure, I examined the certificate and noticed the it was only valid for 90 days. Although I am more accustomed to certificates from other CA’s expiring annually, this is apparently normal (and in retrospect, sensible).

I tossed the notion of marking the renewal date on my calendar, assuming there must be an automated way to renew, and easily found a straightforward method using a cron job tied to the certbot-auto script. That methodology attempts to renew on a weekly basis. I felt the only aspect it was lacking was a means of notification, since I want to be relatively hands-off in the admin department (and generally feel important cron jobs should have notifications tied to them).

I briefly considered using the wp-cron system to send an email via WP-Mail-SMTP (remember, Lightsail instances don’t have native SMTP capabilities). However, this seemed like a co-mingling of responsibilities (using a WP hook to invoke certbot via exec() ), when the cert is a web server level concern. You could argue I’m guilty of the same thing by using Really Simple SSL rather than managing Apache directly, and you’d be correct, but you would also be pest/let-down at parties, etc.

Allegiance to SRP aside, I wanted to take full advantage of AWS for this feature and not take a hand-hold from WordPress plugins like WP SES. I decided SES was probably overkill and a bit too rigid; SNS does a fine job with basic emails and is delivery agnostic, in case I decide to switch my means of notification to SMS/other. Since the proper procedure for allowing Lightsail to speak to other AWS services is VPC peering, my thinking was once things were properly configured, I would have a solid basis for hitting other AWS resources from my Lightsail instance.

Rather than rewrite the several articles I used to guide my configuration, here is a quick list of links (with notes), followed by my own method for incorporating SNS into the process:

  1. Make sure your default VPC is enabled and then enable VPC peering on Lightsail.
  2. Make sure you have the AWS CLI installed and configured on your Lightsail instance (it should be by default). The instructions deviated slightly from the article and I had to run:
    sudo apt install awscli
  3. Create an access key so you can use the CLI
    Note: when configuring, make sure the default region matches the region where you enabled vpc peering/where you intend to implement SNS (e.g. us-east-2). For ‘Default output format’, I selected JSON, simply because it’s easy for me to read, although other options are available.

Now you’re ready to create an SNS topic/subscription. This is easy to do from the SNS dashboard within the AWS console.

First create a topic for the certificate renewal and copy the ARN when you’re finished (you’ll need this for the subscription and the CLI command).

Next create a subscription to the topic tied to the email address where you wish to receive the notification. Make sure you select ‘Email’ as the protocol. After you save the new subscription, you will need to check your mail at that that address and confirm the subscription.

When this is complete, you’re ready to test the topic/subscription via the CLI from your Lightsail instance. Run the following command, using the topic ARN you copied from above:

aws sns publish --topic-arn "<INSERT TOPIC ARN HERE>" --subject "testing" --message "test message"

After you verify you have received the test email message, you are ready for the final step. Refer once again to the instructions for setting an auto renewal cron job, but now with a slight modification to the command. Instead of:

cd /etc/letsencrypt/ && ./certbot-auto renew && /opt/bitnami/ctlscript.sh restart 

wrap the output using bash command substitution and set that to the value of our message, like so (now with a more sensible subject):

aws sns publish --topic-arn "<INSERT TOPIC ARN HERE>" --subject "website certificate renewal" --message " 
 $(cd /etc/letsencrypt/ && ./certbot-auto renew && /opt/bitnami/ctlscript.sh restart)"

Now the entire output of the cron job can be captured and emailed to you for review.

The simplicity is appealing, but be careful not to start sending every aspect of server maintenance through SNS. AWS provides myriad ways of aggregating log files, via Elastic Beanstalk retrieval, writeouts to CloudWatch, and more. This is just a basic way to get vital data into your inbox, and keep apprised as to the success/failure of your certificate renewal.

Leave a Reply

Your email address will not be published. Required fields are marked *