This content originally appeared on DEV Community and was authored by Athreya aka Maneshwar
Making Ansible Snappy, Quiet, and Friendly: A Dev’s Guide to ansible.cfg
Hi there! I’m Maneshwar. Right now, I’m building LiveAPI, a first-of-its-kind tool that helps you automatically index API endpoints across all your repositories. LiveAPI makes it easier to discover, understand, and interact with APIs in large infrastructures.
Setting up PostgreSQL isn’t hard. Forgetting to set it up the same way across servers? That’s where it gets messy. We wanted to automate it all—install, configure, create roles, set cron, restore dumps, and even back them up with alerts—using a single Ansible playbook and a couple of shell scripts.
Here’s how we automated our entire PostgreSQL lifecycle, from install to restore.
Step 1: Install PostgreSQL and Required Extensions
We start with installing PostgreSQL 16, plpython3u
, and pg_cron
. We also drop in the official APT repo and GPG key so we’re not stuck with the system default version.
- name: Install required dependencies for PostgreSQL
ansible.builtin.apt:
name:
- curl
- ca-certificates
- gnupg
- lsb-release
state: present
update_cache: yes
We then fetch the PostgreSQL signing key and register the repo:
- name: Add PostgreSQL APT repository
ansible.builtin.apt_repository:
repo: "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt {{ ansible_lsb.codename }}-pgdg main"
state: present
Post that, we install the actual packages we care about:
- name: Install PostgreSQL 16 and cron extension
ansible.builtin.apt:
name:
- postgresql-16
- postgresql-16-cron
- postgresql-plpython3-16
- python3-psycopg2 # needed for Ansible postgres modules
state: present
Step 2: Configure PostgreSQL Access and Superusers
We change the default user’s password, create our custom flyweight
superuser, and make sure PostgreSQL accepts external connections:
- name: Alter custom superuser role attributes
shell: |
PGPASSWORD="{{ pg_postgres_password }}" psql -U postgres -c "ALTER ROLE {{ pg_flyweight_user }} WITH SUPERUSER CREATEDB CREATEROLE REPLICATION BYPASSRLS;"
become: true
become_user: postgres
We also modify postgresql.conf
and pg_hba.conf
to:
- Allow external connections (
listen_addresses = '*'
) - Enable
pg_cron
viashared_preload_libraries
- Allow md5 authentication for all IPs (
0.0.0.0/0
)
Step 3: pg_cron Config
If you’re using pg_cron
, you need to point it to a database. We do that using:
- name: Ensure cron.database_name is set to 'liveapi'
lineinfile:
path: /etc/postgresql/16/main/postgresql.conf
line: "cron.database_name = 'liveapi'"
state: present
insertafter: EOF
Step 4: Restore Databases from Backup (Ansible + Shell Combo)
We restore a .tar
archive which includes:
roles.sql
- One or more
.dump
files (one per DB)
Here’s what the restore shell script does:
- Downloads and extracts the archive
- Restores roles (excluding
postgres
) - For each DB:
- Creates it
- Calls
pg_restore
- Restarts PostgreSQL with updated
cron.database_name
if needed
restore.sh.j2
looks like this:
curl -sSL "$ARCHIVE_URL" -o "$ARCHIVE_NAME"
tar -xf "$ARCHIVE_NAME" -C "$TMP_DIR"
for dumpfile in "$TMP_DIR"/*.dump; do
dbname=$(basename "$dumpfile" .dump)
createdb -h "$PG_HOST" -U "$PG_USER" "$dbname"
pg_restore -h "$PG_HOST" -U "$PG_USER" -d "$dbname" "$dumpfile"
done
This script is rendered and executed from Ansible:
- name: Run restore.sh as sudo
ansible.builtin.shell: /home/ubuntu/restore/restore.sh
become: true
Step 5: Backups to S3 + Discord Alerts
Our backup script does the opposite: dumps everything, compresses it, uploads to S3, and alerts us on Discord with the file size.
PGPASSWORD=$password pg_dumpall -U postgres > full_backup.sql
tar -zcvf "$f" ./dump/full_backup.sql
aws s3 cp "$f" s3://fw-pgbackup
If backup fails or the file size is too small (<20MB), we get a Discord ping.
Why This Setup Works
One command to setup PostgreSQL from scratch
Restore production-like data to dev in seconds
pg_cron ready out of the box
Role and permission management handled automatically
Cloud backup and alerting done without manual ops
If you’re building platforms with Postgres and want reproducibility with zero surprises, this combo of Ansible + shell + S3 + Discord is hard to beat.
LiveAPI helps you get all your backend APIs documented in a few minutes.
With LiveAPI, you can generate interactive API docs that allow users to search and execute endpoints directly from the browser.
If you’re tired of updating Swagger manually or syncing Postman collections, give it a shot.
This content originally appeared on DEV Community and was authored by Athreya aka Maneshwar