Barman 3.20.1 on AWS User Guide
Overview
This guide covers launching and using the Barman 3.20.1 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg backup and recovery listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.
Barman (Backup and Recovery Manager) is EnterpriseDB's open source disaster recovery tool for PostgreSQL. It takes physical base backups of one or many PostgreSQL servers, archives their write ahead log (WAL) continuously, applies a retention policy and restores a server to any point in time.
The cloudimg image is working from the first minute:
- A protected PostgreSQL source out of the box. First boot creates a local PostgreSQL 16 cluster of its own (listening on loopback only), and Barman is already backing it up: WAL streams continuously through a replication slot, the first base backup is taken during first boot, and
barman-backup.timertakes a new one every day at 01:30 UTC with aREDUNDANCY 2retention policy. Use it to learn Barman, then add your own servers. - Least privilege, per-instance secrets. Barman connects with two roles:
barman, which is not a superuser and holds only the backup functions and monitoring roles Barman's documentation lists, andstreaming_barman, which only hasREPLICATION. Both passwords are generated on each instance's first boot and kept only in/var/lib/barman/.pgpass(mode 0600). No password, key or database is baked into the image. - TLS and a tight
pg_hba.conf. The local PostgreSQL uses a TLS certificate generated for the instance on first boot; the two Barman roles may only log in over TLS with SCRAM-SHA-256, and every other network login is refused. - A self test for backup and restore.
sudo barman-selftestwrites a marker row, takes a backup, writes a second marker, archives its WAL, restores the latest backup into a private temporary directory, starts a throwaway PostgreSQL on the restored copy and checks that both markers are there. - Locked down. The Barman and PostgreSQL services are denied the instance metadata service (IPv4 and IPv6) and reserved address ranges, and run with systemd sandboxing; the AMI requires IMDSv2. Nothing listens on the network except SSH.
- Upstream, unmodified. Barman 3.20.1 and PostgreSQL 16 come from the PostgreSQL project's own APT repository (apt.postgresql.org, signing key pinned), with upstream's systemd units, on fully patched Ubuntu 24.04 LTS with unattended security upgrades switched on.
What is on the image: Barman 3.20.1 (barman, barman-cli, python3-barman), PostgreSQL 16 server and client, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.
Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet.
- A security group that allows TCP 22 (SSH) from your own networks only. Barman needs no inbound port of its own.
- To protect your own databases: PostgreSQL servers this instance can reach on their PostgreSQL port (5432 by default), and enough disk on this instance for the backups and WAL you keep. Size the root volume for that at launch, or add a volume for
/var/lib/barman.
Step 1: Launch the instance
In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Barman 3.20.1 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large, your key pair, a security group as above, and a root volume large enough for the backups you plan to keep.
With the AWS CLI (replace the values in angle brackets):
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--block-device-mappings 'DeviceName=/dev/sda1,Ebs={VolumeSize=<size-in-GiB>,VolumeType=gp3}' \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=barman}]'
Step 2: Connect to your instance
| Version | SSH user |
|---|---|
| Barman 3.20.1 on Ubuntu 24.04 | ubuntu |
ssh -i <your-key.pem> ubuntu@<public-ip>
Step 3: Check that Barman is running
First boot takes about 20 seconds: it creates the PostgreSQL cluster, its certificate and the role passwords, starts WAL streaming and takes the first base backup. Then the WAL receiver, PostgreSQL and both timers are active:
systemctl is-active barman.timer barman-backup.timer barman-receive-wal@pg.service postgresql@16-main.service
sudo test -f /var/lib/cloudimg/barman-firstboot.done && echo FIRSTBOOT_DONE
active
active
active
active
FIRSTBOOT_DONE
barman.timer runs barman cron every minute (it keeps WAL streaming alive and archives incoming WAL); barman-backup.timer runs the daily base backup.
PostgreSQL listens on loopback only, and SSH is the only network listener:
sudo ss -lntp | awk 'NR>1 {print $4, $6}' | sed -E 's/pid=[0-9]+,fd=[0-9]+/.../g' | sort
0.0.0.0:22 users:(("sshd",...),("systemd",...))
127.0.0.1:5432 users:(("postgres",...))
127.0.0.53%lo:53 users:(("systemd-resolve",...))
127.0.0.54:53 users:(("systemd-resolve",...))
[::]:22 users:(("sshd",...),("systemd",...))
Step 4: Read the instance details
First boot writes a short root only note. It holds no secret itself: the role passwords live only in /var/lib/barman/.pgpass.
sudo cat /root/barman-credentials.txt
# Barman 3.20.1 on Ubuntu 24.04 - first-boot details, unique to this instance (root only).
barman.host=<private-ip>
barman.server=pg
barman.backup_method=postgres (pg_basebackup over streaming replication)
barman.wal_streaming=on (replication slot barman, barman-receive-wal@pg.service)
barman.schedule=barman-backup.timer, daily 01:30 UTC (barman backup all)
postgres.listen=127.0.0.1:5432 and [::1]:5432 only (no public database port)
postgres.tls.sha256=<POSTGRES_TLS_SHA256>
roles=barman (backup functions only, not superuser), streaming_barman (REPLICATION)
role.logins=passwords are generated on first boot and kept only in /var/lib/barman/.pgpass (mode 0600, owner barman)
#
# Everyday use:
# sudo -u barman barman check pg health of the source and WAL streaming
# sudo -u barman barman list-backups pg the backup catalogue
# sudo -u barman barman backup pg --wait take a base backup now
# sudo barman-selftest backup + restore proof on this instance
# Guide: https://www.cloudimg.co.uk/guides/barman-3-20-1-on-ubuntu-24-04-aws/
Your instance shows its own private address and certificate fingerprint.
Step 5: Check the server and its backups
Barman's own health check covers the connection, WAL streaming, the replication slot, the retention policy and the backups:
sudo -u barman barman check pg
Server pg:
PostgreSQL: OK
superuser or standard user with backup privileges: OK
PostgreSQL streaming: OK
wal_level: OK
replication slot: OK
directories: OK
retention policy settings: OK
backup maximum age: OK (no last_backup_maximum_age provided)
backup minimum size: OK (22.2 MiB)
wal maximum age: OK (no last_wal_maximum_age provided)
wal size: OK (0 B)
compression settings: OK
failed backups: OK (there are 0 failed backups)
minimum redundancy requirements: OK (have 1 non-incremental backups, expected at least 1)
pg_basebackup: OK
pg_basebackup compatible: OK
pg_basebackup supports tablespaces mapping: OK
systemid coherence: OK
pg_receivexlog: OK
pg_receivexlog compatible: OK
receive-wal running: OK
archiver errors: OK
The catalogue already holds the base backup taken on first boot:
sudo -u barman barman list-backups pg
pg 20261108T154819 - F - Sun Nov 8 15:48:20 2026 - Size: 38.2 MiB - WAL Size: 0 B
WAL is streamed by streaming_barman through the slot barman:
sudo -u barman barman replication-status --target wal-streamer pg | grep -E 'Application name|User name|Current state|Replication slot'
Application name: barman_receive_wal
User name : streaming_barman
Current state : streaming (async)
Replication slot: barman
Details of one backup (use an ID from list-backups, or latest):
sudo -u barman barman show-backup pg latest | grep -E 'Status|Backup Method|Backup Size|Begin WAL|Begin time|End time'
Status : DONE
Backup Method : postgres
Backup Size : 22.2 MiB (38.2 MiB with WALs)
Begin WAL : 000000010000000000000003
Begin time : 2026-11-08 15:48:19.829596+00:00
End time : 2026-11-08 15:48:20.248134+00:00
Step 6: Take a backup now
sudo -u barman barman backup pg --wait
sudo -u barman barman list-backups pg --minimal
--wait returns once the WAL the backup needs has been archived, so the new backup is immediately usable for a restore. With REDUNDANCY 2, Barman keeps the two newest base backups (and the WAL they need) and removes older ones during barman cron.
Step 7: Run the self test
barman-selftest proves the whole backup and restore path without touching your data: it writes a random marker row into a scratch table of the local source, takes a base backup, writes a second marker, switches and archives the WAL, restores the latest backup with barman recover into a private temporary directory, starts a throwaway PostgreSQL on the restored copy (no network listener) and checks that both markers are there. It then removes everything it made. It takes about 30 seconds:
sudo barman-selftest 2>&1 | tail -2
barman-selftest: backup 20261108T154848 restored; base-backup and WAL-replayed markers both present in the recovered copy
BARMAN_SELFTEST_OK 20261108T154848
The self test adds a base backup to the catalogue, which the retention policy treats like any other.
Step 8: Restore a backup
barman recover writes a complete PostgreSQL data directory from a backup and the archived WAL. Restore into an empty directory owned by barman (here on this instance), with your own directory and, for point in time recovery, a target time:
sudo install -d -o barman -g barman -m 0700 <restore-directory>
sudo -u barman barman recover pg latest <restore-directory>
sudo -u barman barman recover pg latest <restore-directory> --target-time "<YYYY-MM-DD HH:MM:SS+00>"
To restore straight onto another server over SSH, add --remote-ssh-command "ssh postgres@<pg-host>" (that host must trust this instance's barman user's SSH key). Start PostgreSQL on the restored directory with the same major version as the backup.
Step 9: Protect your own PostgreSQL servers
Each server Barman protects is one file in /etc/barman.d/. On the PostgreSQL server you want to back up (not on this instance), create the two roles with passwords of your own and allow this instance in its pg_hba.conf:
-- on the PostgreSQL server, as a superuser
CREATE ROLE barman LOGIN PASSWORD '<barman-password>';
GRANT EXECUTE ON FUNCTION pg_backup_start(text, boolean) TO barman;
GRANT EXECUTE ON FUNCTION pg_backup_stop(boolean) TO barman;
GRANT EXECUTE ON FUNCTION pg_switch_wal() TO barman;
GRANT EXECUTE ON FUNCTION pg_create_restore_point(text) TO barman;
GRANT pg_read_all_settings, pg_read_all_stats, pg_checkpoint TO barman;
CREATE ROLE streaming_barman LOGIN REPLICATION PASSWORD '<streaming-password>';
# pg_hba.conf on the PostgreSQL server: this instance's private address only
hostssl all barman <barman-instance-ip>/32 scram-sha-256
hostssl replication streaming_barman <barman-instance-ip>/32 scram-sha-256
The server also needs wal_level = replica (the default) and free max_wal_senders and max_replication_slots. Then, on this instance, add the passwords to /var/lib/barman/.pgpass and a server file (here <server> is a short name of your choice):
printf '%s\n' '<pg-host>:5432:*:barman:<barman-password>' '<pg-host>:5432:*:streaming_barman:<streaming-password>' | sudo -u barman tee -a /var/lib/barman/.pgpass >/dev/null
sudo tee /etc/barman.d/<server>.conf >/dev/null <<'EOF'
[<server>]
description = "Production PostgreSQL"
conninfo = host=<pg-host> port=5432 user=barman dbname=postgres sslmode=require
streaming_conninfo = host=<pg-host> port=5432 user=streaming_barman dbname=postgres sslmode=require
backup_method = postgres
streaming_archiver = on
slot_name = barman
create_slot = auto
retention_policy = RECOVERY WINDOW OF 7 DAYS
EOF
sudo -u barman barman cron
sudo -u barman barman check <server>
sudo -u barman barman backup <server> --wait
barman cron (every minute) creates the replication slot and starts barman-receive-wal@<server>.service for the new server, and the daily timer backs it up with the others (barman backup all). When you no longer need the demo source, remove /etc/barman.d/pg.conf and stop postgresql@16-main.service.
Step 10: Scheduling and retention
systemctl list-timers barman.timer barman-backup.timer
grep -vE '^[[:space:]]*(;|$)' /etc/barman.d/pg.conf
To change the backup time, override the timer (for example OnCalendar=*-*-* 03:00:00 UTC) with sudo systemctl edit barman-backup.timer. Change retention_policy and minimum_redundancy per server in its file in /etc/barman.d/.
Step 11: Check the security posture
The Barman services (and PostgreSQL) are denied the instance metadata service and reserved address ranges:
systemctl show barman.service -p IPAddressDeny --value | tr ' ' '\n' | sort
168.63.129.16/32
169.254.169.254/32
192.0.0.0/24
198.18.0.0/15
224.0.0.0/4
240.0.0.0/4
fd00:ec2::254/128
Barman still reaches your PostgreSQL servers in the VPC: connecting to them is its job, and only root can add a server to /etc/barman.d/. The services run as the unprivileged barman user with systemd sandboxing:
systemctl show barman.service -p User -p NoNewPrivileges -p ProtectSystem -p ProtectHome -p PrivateTmp
User=barman
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=full
NoNewPrivileges=yes
Neither Barman role is a superuser, and the secrets are readable by their owner only:
sudo -u postgres psql -X -tA -c "SELECT rolname, rolsuper, rolreplication FROM pg_roles WHERE rolname IN ('barman','streaming_barman') ORDER BY 1"
sudo stat -c '%a %U %n' /var/lib/barman/.pgpass /root/barman-credentials.txt /etc/postgresql/16/main/tls/server.key
sudo openssl x509 -in /etc/postgresql/16/main/tls/server.crt -noout -fingerprint -sha256 | cut -d= -f2
barman|f|f
streaming_barman|f|t
600 barman /var/lib/barman/.pgpass
600 root /root/barman-credentials.txt
600 postgres /etc/postgresql/16/main/tls/server.key
<POSTGRES_TLS_SHA256>
The local source's pg_hba.conf admits local OS users by peer authentication and the two Barman roles over TLS on loopback only:
sudo grep -vE '^[[:space:]]*(#|$)' /etc/postgresql/16/main/pg_hba.conf
local all all peer
hostssl all barman 127.0.0.1/32 scram-sha-256
hostssl all barman ::1/128 scram-sha-256
hostssl replication streaming_barman 127.0.0.1/32 scram-sha-256
hostssl replication streaming_barman ::1/128 scram-sha-256
Step 12: Server components
| Component | Path |
|---|---|
| Barman | /usr/bin/barman (packages barman, barman-cli, python3-barman 3.20.1) |
| Global configuration | /etc/barman.conf (as packaged) |
| Server definitions | /etc/barman.d/*.conf (pg.conf is the local demo source) |
| Backups, WAL and catalogue | /var/lib/barman/<server>/ |
| Logs | /var/log/barman/barman.log, journalctl -u barman -u 'barman-receive-wal@*' -u barman-backup |
| Service units | barman.timer, barman.service, barman-receive-wal@.service (upstream), barman-backup.timer, barman-backup.service, barman-firstboot.service, with cloudimg drop-ins in /etc/systemd/system/<unit>.d/ |
| Demo source | PostgreSQL 16 cluster 16/main, configuration in /etc/postgresql/16/main/ |
| Helpers | /usr/local/sbin/barman-selftest |
| Licence and provenance | /usr/share/doc/barman/ |
barman --version 2>&1 | head -1
dpkg-query -W -f '${Package} ${Version}\n' barman barman-cli python3-barman postgresql-16
3.20.1 Barman by EnterpriseDB (www.enterprisedb.com)
barman 3.20.1-1.pgdg24.04+1
barman-cli 3.20.1-1.pgdg24.04+1
postgresql-16 16.15-1.pgdg24.04+2
python3-barman 3.20.1-1.pgdg24.04+1
Step 13: Security recommendations
- Allow port 22 in the security group from your own networks only. Allow this instance into your database servers' security groups on 5432 by its private address or security group, never from the internet.
- Use
hostsslandscram-sha-256for the Barman roles on your servers, and keep/var/lib/barman/.pgpassat mode 0600. - Keep a copy of the backups off the instance: take EBS snapshots of the volume that holds
/var/lib/barman, or copy them to another region. - Monitor with
sudo -u barman barman check all --nagios, and runsudo barman-selftestafter configuration changes. - Keep the operating system patched; unattended security upgrades are on, and
sudo apt-get update && sudo apt-get upgradeapplies everything else (including new Barman and PostgreSQL releases from apt.postgresql.org).
Support and licensing
Barman is open source under the GPL-3.0 licence and PostgreSQL under the PostgreSQL licence; there is no per user or per CPU licence fee. The package copyright files and a build provenance note naming the source are in /usr/share/doc/barman/. cloudimg is not affiliated with or endorsed by EnterpriseDB or the PostgreSQL Global Development Group. The AMI price covers cloudimg's hardening, first boot setup and support.
- Email: support@cloudimg.co.uk
- Website: https://www.cloudimg.co.uk
- Support: 24/7, with a 24 hour response SLA