How to backup your Postgres DB into AWS S3 in Kubernetes

TL;DR: Use CronJob to schedule a DB daily backup

Image for post
Image for post
Based on the photo by Erda Estremera on Unsplash

One good friend of me told me time ago…

Image for post
Image for post
I know how to recognize good advice

Designing our backup solution

Our business requirements for the backup solution are:

  • Not in the same place. We use AWS S3 for store the backups. Out of our cluster network.
  • Secure and encrypted. Custody of data is essential. We will use secure transport up to S3 and the files will be encrypted with a symmetric key.
  • Kubernetes way. Backups should be done automatically using Kubernetes resources.

Create and configure an AWS S3 bucket

It’s very pretty straightforward create a AWS S3 bucket. We create it using our main AWS account with the “Create bucket wizard”.

Image for post
Image for post
AWS S3 New bucket wizard

What is not so easy is having a good access and security configuration.

In our case we need to create a specific user to use only the AWS API and with just write permissions (PutObject in essence).

There is no a default S3 policy for just write. So we create the custom policy first and we assign it when we create the new user later.

Image for post
Image for post
Just the permissions needed

We even specify the folders that you can access.

Now, the user creation and policy assignment.

Image for post
Image for post
Wizard to create a user with AWS API access only
Image for post
Image for post
Check “Attach existing policies directly”
Image for post
Image for post
Our policy ready to be assigned

Good! We are ready to enter in the Kubernetes part.

Write and apply CronJob

We create a bash script with the following steps:

  1. Database backup with pg_dump command.
  2. Compression with BZip2.
  3. Encrypt the file.
  4. Upload it to S3.
Our simple but powerful bash script

As you can observe, all the parameters are passed as environment variables.

Regard to the CronJob spec is the following:

Before apply it, we need to setup the secrets and configurations. Visit “Secrets” for more information and to see how secrets are created in Kubernetes.

We apply our manifest now:

kubectl apply -f backup-postgres-cronjob.yaml

If you have interest in the Dockerfile for this image, here it is:

Check it up!

For a rapid testing, we apply a each 5 minutes cron schedule (*/5 * * * *).

Image for post
Image for post
Backup done! AWS S3 console

When we check that the backup worked, we re-apply the manifest with the desired backup frequency (I.E: each day at 2 am, 0 2 * * *).


If you have a Kubernetes cluster, probably you need backups.

Thanks to Kubernetes CronJob it’s very simple create good backups.

A possible improvement to this solution is to use AWS SAS or Telegram API to notify us when the backup is done. Maybe I’ll update the post later with that notification.

Please, if you liked it, give it a round of applause. And if you want to know more about DevOps, Kubernetes, Docker, etc … follow me :)


Image for post
Image for post

Written by

CTO @ & Beyond-Full-stack developer #go #python #kubernetes

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store