PolarDB for PostgreSQL 17.11.1.0 on AWS User Guide
Overview
This guide covers launching and verifying PolarDB for PostgreSQL 17.11.1.0 on Ubuntu 24.04 from cloudimg on Amazon EC2. It is one version of the cloudimg Hardened PostgreSQL 18, PostGIS & Postgres Extension AMIs listing on AWS Marketplace; you pick it as the software version when you subscribe and launch. The other PostgreSQL builds and extensions in the listing are described on the listing's guide hub.
PolarDB for PostgreSQL is Alibaba Cloud's open source PostgreSQL distribution, released under the Apache License 2.0 over PostgreSQL 17.11 (The PostgreSQL License). It is not an extension added to stock PostgreSQL: it is a distribution with its own storage manager (PolarVFS), its own replay machinery (LogIndex), its own monitoring functions and its own release train. Because it is PostgreSQL 17 underneath, everything you know about PostgreSQL applies: ACID transactions, roles and permissions, indexes, pg_dump, and every PostgreSQL driver (psycopg, JDBC, pgx, Npgsql and the rest).
The image is built from the upstream tag v17.11.1.0 (commit ff510dfcb411dcb504efb32d23a33865ac34b348, released 2026-08-18), which carries the PostgreSQL 17.11 security fixes. The running server reports exactly that build: PostgreSQL 17.11 (PolarDB 17.11.1.0 build ff510dfc).
A single node on local storage
PolarDB's headline architecture is shared storage, with several compute nodes reading one copy of the data. That needs more than one machine and a shared block device. This image is the single-node, local-storage shape that upstream ships and documents: upstream's own polardb.conf.sample sets polar_vfs.localfs_mode = true and its initialiser polar-initdb.sh takes a localfs mode for it. The storage layout is PolarDB's real one (base/, global/, pg_wal/, pg_logindex/ and pg_xact/ live in the PolarDB data directory and are read through PolarVFS with direct I/O); it simply sits on the instance's EBS volume.
What this image is not:
- Not a cluster. There are no read-only replicas sharing one copy of the data, no failover between nodes and no shared-storage parallel execution. All of these need more than one compute node.
- No web interface. There is no dashboard or HTTP surface. You use
psqlor any PostgreSQL client.
What is on the image:
- PolarDB for PostgreSQL 17.11.1.0 (
polardb.service), compiled from the pinned upstream source into/opt/polardb, with the client tools (psql,pg_dump,pg_restore,pg_basebackup,pg_isready,pg_ctl) on the defaultPATH - 93 extensions, including the PolarDB extensions (
polar_vfs,polar_monitor,polar_io_stat,polar_worker,polar_advisor,polar_feature_utilsand more) and upstream's bundled set:pg_cron,pgaudit,pg_partman,pg_repack,pg_hint_plan,pg_squeeze,pg_bigm,hll,roaringbitmap,pase,ip4rand others - A
polarappdatabase owned by the non-superuser application rolepolarapp, and thepolardbsuperuser; both passwords are generated on your instance's first boot - TLS with a certificate generated on your instance's first boot (TLS 1.2 minimum)
- A credential guard that runs on every boot and refuses to serve if a published or example password ever authenticates
- The build provenance, the upstream licences and a dependency licence inventory under
/usr/share/polardb-postgresql/
Default user: ubuntu · Architecture: x86_64 · Root volume: 16 GiB gp3
Security posture
- No database ships in the image. The image contains no PolarDB cluster at all, so it carries no role, password, data or key from the build. First boot creates a fresh cluster, the
polarappdatabase and two different passwords, one forpolardband one forpolarapp, and writes them to/root/polardb-credentials.txt, readable by root only. Locally, thepolardbsuperuser is also reachable as thepolardbsystem user (peer authentication on the local socket). - Nothing is served before first boot finishes. PolarDB will not start until first boot has created the cluster, the certificate and the passwords. While it sets them, the server listens on its local socket only, with no TCP port.
- Per-instance TLS certificate. First boot creates this instance's own private key and self-signed certificate (
/var/lib/polardb/primary/server.crt) and turns TLS on, so no two instances share a key. - Localhost only. PolarDB listens on
127.0.0.1:5432, and the listing's security group opens SSH (22) only. Reach the database through an SSH tunnel, or open it to your VPC as described in Step 7. - Remote connections require TLS.
pg_hba.confaccepts non-loopback clients only overhostsslwithscram-sha-256and rejects plain-text remote connections; there is notrustormd5rule. A start-time guard refuses to start PolarDB if the configuration is weakened (atrustrule, a non-TLS remote rule,md5password hashing, or a remote listener with TLS off). - Upstream's insecure defaults are not used. Upstream's build script initialises clusters with
trustauthentication, adds ahost all all 0.0.0.0/0 md5rule and offers a fixed encryption key; the image is built with./configureandmakeinstead, and the cloudimg settings override the sample'slisten_addresses = '*'andpassword_encryption = md5. - No metadata access for the database. A database superuser can make PolarDB open outbound connections (for example
COPY ... FROM PROGRAM,dblinkorpostgres_fdw), so the PolarDB service and both first-boot services are blocked from reaching the instance metadata service (169.254.169.254 and fd00:ec2::254). Amazon Time Sync (169.254.169.123) still works. If you add backups to S3 from inside the database, give them explicit credentials; they cannot use the instance role. - No core dumps. The database and first-boot services may not write core files, so process memory holding a password never lands on disk.
- IMDSv2 required. The AMI is registered with
ImdsSupport v2.0, so instances launched from it refuse token-less (IMDSv1) metadata requests. - Fails closed. If first boot cannot finish, PolarDB stays stopped and first boot tries again on the next boot.
- Per-instance identity. SSH host keys and the machine ID are generated fresh on every instance. SSH allows key login only, root cannot log in over SSH, and root has no password.
- No build tools. The compiler, linker and every development package used to build PolarDB were removed from the image after the build, along with the source tree.
- What we changed in Ubuntu: the
fwupd-refreshtimer is masked (EC2 has no firmware that fwupd can update), the C header packages the base image carried are removed, and only the running kernel is kept.
Prerequisites
- An AWS account and permission to launch EC2 instances and create security groups
- An EC2 key pair in the Region you launch in
- A VPC subnet, with a public IP on the instance if you connect over the internet
Recommended instance type: m5.large. The shipped settings (shared_buffers 256 MB, max_connections 200) suit development, testing and small production databases; for larger workloads choose a bigger instance, raise shared_buffers towards a quarter of the memory and give the root volume more space.
Connecting to your instance
| Version | Operating system | SSH user |
|---|---|---|
| PolarDB for PostgreSQL 17.11.1.0 on Ubuntu 24.04 | Ubuntu 24.04 LTS | ubuntu |
Step 1: Launch the instance
Option A: AWS Marketplace console
- Open the cloudimg Hardened PostgreSQL 18, PostGIS & Postgres Extension AMIs listing on AWS Marketplace and choose View purchase options, then Subscribe. One subscription covers every version in the listing.
- Once the subscription is active, choose Launch your software.
- Choose One-click launch from AWS Marketplace (or Launch from EC2 Console for the full launch wizard). In Version, choose PolarDB for PostgreSQL 17.11.1.0 on Ubuntu 24.04, then choose your Region.
- Pick an instance type (
m5.largerecommended; the software charge is $0.04 per vCPU per hour) and your key pair. - Security group: the listing's default group allows SSH (22) only. Restrict it to your own IP address. Do not open 5432 to the internet.
- Choose your VPC and subnet, leave the metadata defaults (the image already requires IMDSv2), then choose Launch.
Option B: AWS CLI
Run this on your own workstation. Replace the AMI ID with the one shown for your Region on the Marketplace launch page, and the VPC, subnet, key pair and CIDR with your own:
SG=$(aws ec2 create-security-group --group-name polardb \
--description "PolarDB for PostgreSQL" --vpc-id vpc-0123456789abcdef0 \
--query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 22 --cidr <your-mgmt-cidr>
aws ec2 run-instances \
--image-id ami-0123456789abcdef0 \
--instance-type m5.large \
--key-name my-key-pair \
--security-group-ids "$SG" \
--subnet-id subnet-0123456789abcdef0 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=polardb}]'
You do not need --metadata-options: the AMI already makes IMDSv2 required. To give the database more room, add a --block-device-mappings entry for /dev/sda1 with a bigger VolumeSize.
Step 2: Connect and read your credentials
Connect as ubuntu with the key pair you chose:
ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip>
First boot finishes within a minute of launch. Show the connection details (the two password lines are left out here; read them with sudo cat /root/polardb-credentials.txt and keep them in your secrets manager):
sudo grep -v -e '^POLARDB_SUPERUSER_PASSWORD=' -e '^POLARDB_APP_PASSWORD=' /root/polardb-credentials.txt | head -16
# PolarDB for PostgreSQL 17.11.1.0 (PostgreSQL 17.11) on Ubuntu 24.04 (cloudimg AWS Marketplace image)
# Generated on THIS instance's first boot by polardb-firstboot.service; these passwords exist nowhere else.
# Rotate a password (never on a command line): sudo -u polardb psql -h /run/polardb -d postgres
# then \password polarapp and update this file to match (polardb-credguard reads it at every boot).
POLARDB_HOST=127.0.0.1
POLARDB_PORT=5432
POLARDB_SUPERUSER=polardb
POLARDB_APP_ROLE=polarapp
POLARDB_APP_DATABASE=polarapp
POLARDB_SSLMODE=require
POLARDB_TLS_CERT=/var/lib/polardb/primary/server.crt
POLARDB_TLS_CERT_SHA256=B7:10:CC:87:DB:91:5E:3A:46:68:6B:87:55:D7:35:C9:43:AB:1A:55:0C:5E:9C:EF:0E:26:C6:A2:65:4B:E4:94
# Application database 'polarapp' (owner polarapp, a non-superuser) on 127.0.0.1:5432. Connect with TLS:
# psql "host=127.0.0.1 dbname=polarapp user=polarapp sslmode=require"
The certificate fingerprint is different on every instance. The commands below read the polarapp password from that file at run time, so it never appears on screen. In your own sessions you can instead put it in ~/.pgpass (mode 0600) as 127.0.0.1:5432:polarapp:polarapp:<polardb-app-password>.
Step 3: Confirm PolarDB is running
psql --version
systemctl is-active polardb.service polardb-firstboot.service polardb-credguard.service
sudo ss -Hltn
psql (PostgreSQL) 17.11
active
active
active
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 4096 127.0.0.54:53 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:22 0.0.0.0:*
LISTEN 0 400 127.0.0.1:5432 0.0.0.0:*
LISTEN 0 4096 [::]:22 [::]:*
PolarDB listens on 127.0.0.1:5432 only; port 53 on 127.0.0.53/127.0.0.54 is the operating system's local DNS stub. Now connect as polarapp over TLS and ask the server what it is:
export PGPASSWORD="$(sudo sed -n 's/^POLARDB_APP_PASSWORD=//p' /root/polardb-credentials.txt)"
psql "host=127.0.0.1 dbname=polarapp user=polarapp sslmode=require" \
-c "SELECT version();" \
-c "SELECT ssl, version AS tls_version FROM pg_stat_ssl WHERE pid = pg_backend_pid();" \
-c "\dx"
version
-------------------------------------------------------------------------
PostgreSQL 17.11 (PolarDB 17.11.1.0 build ff510dfc) on x86_64-linux-gnu
(1 row)
ssl | tls_version
-----+-------------
t | TLSv1.3
(1 row)
List of installed extensions
Name | Version | Schema | Description
---------------------+---------+-----------------+-------------------------------
pg_cron_preload | 1.0 | pg_cron_preload | polardb pg extend catalog
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
polar_feature_utils | 1.0 | pg_catalog | PolarDB feature utilization
polar_monitor | 1.3 | public | monitor functions for PolarDB
(4 rows)
ff510dfc is the upstream commit the binaries were compiled from.
Step 4: See PolarDB's storage layer
As the polardb superuser (peer authentication over the local socket, no password needed), check that PolarVFS is loaded and the data is served from PolarDB's data directory:
sudo -u polardb psql -h /run/polardb -d postgres \
-c "SHOW shared_preload_libraries" -c "SHOW polar_enable_shared_storage_mode" \
-c "SHOW polar_vfs.localfs_mode" -c "SHOW polar_datadir"
sudo ls /var/lib/polardb/shared
shared_preload_libraries
--------------------------------------------------------------------------------------------
$libdir/polar_vfs,$libdir/polar_io_stat,$libdir/polar_monitor_preload,$libdir/polar_worker
(1 row)
polar_enable_shared_storage_mode
----------------------------------
on
(1 row)
polar_vfs.localfs_mode
------------------------
on
(1 row)
polar_datadir
------------------------------------
file-dio:///var/lib/polardb/shared
(1 row)
base
global
pg_commit_ts
pg_logindex
pg_multixact
pg_replslot
pg_tblspc
pg_twophase
pg_wal
pg_xact
polar_fullpage
pg_wal/ and pg_logindex/ live in the PolarDB data directory, not in /var/lib/polardb/primary. The polar_monitor extension (already enabled in polarapp) adds PolarDB's own monitoring functions, and the full extension catalogue is available:
sudo -u polardb psql -h /run/polardb -d polarapp \
-c "SELECT polar_node_type() AS node_type, polar_is_available() AS available;" \
-c "SELECT count(*) AS available_extensions FROM pg_available_extensions;" \
-c "SELECT name FROM pg_available_extensions WHERE name IN ('pg_cron','pg_hint_plan','pgaudit','pg_partman','hll','roaringbitmap','pase','ip4r','pg_bigm','pg_squeeze','pg_repack','sequential_uuids') ORDER BY name;"
node_type | available
-----------+-----------
primary | t
(1 row)
available_extensions
----------------------
93
(1 row)
name
------------------
hll
ip4r
pase
pg_bigm
pg_cron
pg_hint_plan
pg_partman
pg_repack
pg_squeeze
pgaudit
roaringbitmap
sequential_uuids
(12 rows)
To enable one in your database, connect as polardb and run CREATE EXTENSION <name>; (some, such as pg_cron and pgaudit, also need an entry in shared_preload_libraries and a restart; see each extension's documentation).
Step 5: Work with data
PolarDB is PostgreSQL to your application. As polarapp, create a table, load 10,000 rows, index it and query it:
export PGPASSWORD="$(sudo sed -n 's/^POLARDB_APP_PASSWORD=//p' /root/polardb-credentials.txt)"
psql "host=127.0.0.1 dbname=polarapp user=polarapp sslmode=require" -v ON_ERROR_STOP=1 <<'SQL'
CREATE TABLE orders (id bigserial PRIMARY KEY, region text NOT NULL, amount numeric(12,2) NOT NULL, placed_at timestamptz NOT NULL DEFAULT now());
INSERT INTO orders (region, amount) SELECT 'region-' || (g % 4), (g * 1.5)::numeric(12,2) FROM generate_series(1, 10000) g;
CREATE INDEX orders_region_idx ON orders (region);
ANALYZE orders;
SELECT region, count(*) AS orders, sum(amount) AS total FROM orders GROUP BY region ORDER BY region;
EXPLAIN (COSTS OFF) SELECT count(*) FROM orders WHERE region = 'region-1';
DROP TABLE orders;
SQL
CREATE TABLE
INSERT 0 10000
CREATE INDEX
ANALYZE
region | orders | total
----------+--------+-------------
region-0 | 2500 | 18757500.00
region-1 | 2500 | 18746250.00
region-2 | 2500 | 18750000.00
region-3 | 2500 | 18753750.00
(4 rows)
QUERY PLAN
-------------------------------------------------------
Aggregate
-> Bitmap Heap Scan on orders
Recheck Cond: (region = 'region-1'::text)
-> Bitmap Index Scan on orders_region_idx
Index Cond: (region = 'region-1'::text)
(5 rows)
DROP TABLE
The image also carries a self-test that proves the appliance end to end with this instance's own credentials (a wrong password is refused, a TLS session works, 5,000 rows survive a full restart of PolarDB, PolarVFS is in use). It restarts PolarDB once, so run it when nothing else is connected:
sudo /usr/local/sbin/polardb-roundtrip-check.sh 2>/dev/null
PASS a wrong password is refused over TCP with an authentication error
PASS the per-VM credential connects as polarapp over TLSv1.3
PASS SQL round trip: 5000 rows written, indexed, analysed and aggregated back
PASS all 5000 rows survived a full engine restart
PASS running engine: PostgreSQL 17.11 (PolarDB 17.11.1.0 build ff510dfc) on x86_64-linux-gnu
PASS PolarVFS active, shared-storage mode on, data served from file-dio:///var/lib/polardb/shared
PASS polar_monitor registered; 93 extensions available
POLARDB_ROUNDTRIP_SUCCESS
Step 6: Check the security controls
The PolarDB unit carries the metadata block, polarapp is not a superuser, PolarDB listens on loopback with this instance's own certificate and scram-sha-256 hashing, and the fwupd refresh timer is masked:
systemctl show -p IPAddressDeny polardb.service
sudo -u polardb psql -h /run/polardb -d postgres -Atc "SELECT rolname, rolsuper FROM pg_roles WHERE rolname IN ('polarapp', 'polardb') ORDER BY 1;" \
-c "SHOW listen_addresses;" -c "SHOW ssl_cert_file;" -c "SHOW password_encryption;"
systemctl is-enabled fwupd-refresh.timer 2>/dev/null || true
IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32
polarapp|f
polardb|t
127.0.0.1
/var/lib/polardb/primary/server.crt
scram-sha-256
masked
A wrong password is refused by scram-sha-256:
OUT="$(PGPASSWORD=wrong-password psql "host=127.0.0.1 dbname=polarapp user=polarapp sslmode=require" -c "SELECT 1" 2>&1 || true)"
echo "${OUT#*failed: }"
FATAL: password authentication failed for user "polarapp"
Step 7: Connect from your application
PolarDB accepts connections on localhost only. Two ways to reach it:
- SSH tunnel (no change to the instance). On your workstation run
ssh -N -L 15432:127.0.0.1:5432 ubuntu@<public-ip>, then connect your client to127.0.0.1:15432aspolarappwithsslmode=require. - Open it to your VPC. In
/var/lib/polardb/primary/postgresql.conf, change the cloudimg linelisten_addresses = '127.0.0.1'(near the end of the file) tolisten_addresses = '*', restart PolarDB, then add an inbound rule for 5432 to the instance's security group from your application subnet or VPC CIDR only (never 0.0.0.0/0). Remote clients must use TLS (sslmode=require, orverify-fullwith this instance's certificate/var/lib/polardb/primary/server.crt) and the role's password. A plain-text (non-TLS) connection from another host is refused bypg_hba.conf.
sudo sed -i "s/^listen_addresses = '127.0.0.1'/listen_addresses = '*'/" /var/lib/polardb/primary/postgresql.conf
sudo systemctl restart polardb.service
Maintenance
- Change a password. Run
sudo -u polardb psql -h /run/polardb -d postgresand type\password polarapp(or\password polardb) at the prompt; it asks for the new password twice and never puts it on a command line. Then update/root/polardb-credentials.txt(the credential guard reads it on every boot) and your secrets manager. - Configuration. The cloudimg settings are the block at the end of
/var/lib/polardb/primary/postgresql.conf(listener, port, password hashing, TLS, logging);pg_hba.confis in the same directory. Apply changes withsudo systemctl restart polardb.service. The start-time guard refuses to start PolarDB if a change would weaken authentication or expose it without TLS;journalctl -u polardb.serviceshows why. - Updates. Ubuntu security updates are applied automatically by unattended upgrades. PolarDB itself is compiled from source, so it is not updated through
apt: new PolarDB releases arrive as new versions of this AMI in the listing. Back up (below), launch the new version and restore. - Backups. Take EBS snapshots of the root volume, or logical backups with
pg_dump:sudo -u polardb pg_dump -h /run/polardb -Fc polarapp > polarapp.dump. - Logs.
/var/log/polardb/andjournalctl -u polardb.service; first boot and the credential guard log tojournalctl -u polardb-firstboot.serviceandjournalctl -u polardb-credguard.service. - Licences and provenance. PolarDB for PostgreSQL is under the Apache License 2.0 and PostgreSQL under The PostgreSQL License.
/usr/share/polardb-postgresql/holds the upstreamLICENSE,NOTICEandCOPYRIGHT, every licence file of the bundled extensions (source-licences/), the build provenance (tag, commit, configure flags) and the licence inventory of the system libraries PolarDB uses.
sed -n '1,14p' /usr/share/polardb-postgresql/BUILD-PROVENANCE.txt
PolarDB for PostgreSQL - cloudimg image build provenance
=======================================================
upstream repository : https://github.com/polardb/PolarDB-for-PostgreSQL.git
pinned tag : v17.11.1.0
pinned commit : ff510dfcb411dcb504efb32d23a33865ac34b348
built version string: PostgreSQL 17.11 (PolarDB 17.11.1.0 build ff510dfc)
install prefix : /opt/polardb
built on : 2026-10-26 (UTC)
base OS : Ubuntu 24.04.5 LTS
licence : Apache License 2.0 (root LICENSE + NOTICE at the pinned commit),
over PostgreSQL 17.11 under the PostgreSQL Licence.
extensions installed: 93 (extensions.txt)
configure flags : configure-flags.txt
dependency licences : dependency-licences.txt
Support
cloudimg supports this image by email at support@cloudimg.co.uk. Include the instance ID, the version (PolarDB for PostgreSQL 17.11.1.0 on Ubuntu 24.04) and what you were doing.
PolarDB is a trademark of Alibaba Group. PostgreSQL is a trademark of the PostgreSQL Community Association of Canada. Ubuntu is a trademark of Canonical Ltd. cloudimg is not affiliated with or endorsed by these organisations.