Vallée de Munster, le 25 avril 2025

pglift, le composant central de notre solution d’industrialisation pour PostgreSQL, est à présent disponible en version 2.0.

Cette nouvelle version apporte son lot de correctifs, nouvelles fonctionnalités et améliorations. Nous vous proposons, aujourd’hui, un aperçu de quelques-unes des nouveautés majeures depuis pglift 1.0.

Nettoyage de fonctionnalités obsolètes et amélioration des tests

Avec cette nouvelle version majeure, les développeurs de pglift ont entrepris un important travail de nettoyage en supprimant les fonctionnalités déclarées obsolètes, ainsi que le code associé. Cette démarche a notamment conduit à la suppression de certains paramètres de configuration (par exemple : prometheus.queriespath, cli.logpath…) et d’options dans les interfaces Ansible ou en ligne de commande (comme --jobs pour la commande pglift instance upgrade). Tous les changements susceptibles d’impacter les utilisateurices sont répertoriés dans la note de version détaillée du projet.

Parallèlement, un effort continu est mené pour faire évoluer la couverture de tests (unitaires, fonctionnels ou end-to-end). Cette version s’inscrit dans cette démarche, en intégrant notamment la réécriture d’éléments essentiels de la base de code. Ce travail de fond contribue à maintenir un haut niveau de qualité pour le projet pglift.

Enfin, la version de Python et les dépendances utilisées par pglift ont évolué tout au long du cycle de vie de la version 1. La version 2.0 de pglift requiert désormais Python 3.10 au minimum. Les développeurs veillent à maintenir à jour les principales librairies utilisées (pydantic, pydantic-settings, httpx…), afin de garantir la stabilité, la maintenabilité et la qualité du projet.

Support pour PostgreSQL 12 et 17

pglift s’aligne sur les versions de PostgreSQL supportées par la communauté. Il est donc maintenant possible de déployer, gérer et utiliser des instances avec PostgreSQL 17. A contrario, la version 12 (hors maintenance depuis le 14 novembre 2024) n’est plus supportée.

Sans configuration spécifique, installer le paquet pour PostgreSQL server 17 (postgresql-17 sous Debian, postgresql17-server pour la famille RedHat) permet d’activer et utiliser cette version avec pglift :

$ pglift site-settings --output-format=json | jq -r '.postgresql.versions[].version'
13
14
15
16

$ sudo apt install postgresql-17
…

$ pglift site-settings --output-format=json | jq -r '.postgresql.versions[].version'
13
14
15
16
17

$ pglift instance create prod --version 17 --port 5445
INFO     initializing PostgreSQL
INFO     configuring PostgreSQL authentication
INFO     configuring PostgreSQL
INFO     starting PostgreSQL 17/prod
INFO     creating instance dumps directory: /srv/dumps/17-prod

$ pglift instance list
┏━━━━━━━┳━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ name  ┃ version ┃ port ┃ datadir                  ┃ status  ┃
┡━━━━━━━╇━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ prod  │ 17      │ 5445 │ /srv/pgsql/17/prod/data  │ running │
└───────┴─────────┴──────┴──────────────────────────┴─────────┘

Création d’une instance depuis un backup pgBackRest

Depuis la version 1.7, il est possible de créer une instance depuis une sauvegarde disponible dans une stanza pgBackrest précédemment configurée. Cette fonctionnalité permet de récupérer ou recréer une instance depuis une sauvegarde.

Dans l’exemple qui suit, nous allons :

  • initier une instance ;
  • supprimer les données de l’instance (pour simuler une perte accidentelle) ;
  • et pour finir, la récupérer depuis la stanza pgBackRest.
$ pglift instance create prod --version 17 --port 5775 --pgbackrest-stanza prod-stz
INFO     initializing PostgreSQL
INFO     configuring PostgreSQL authentication
INFO     configuring PostgreSQL
INFO     starting PostgreSQL 17/prod
INFO     creating role 'backup'
INFO     configuring pgBackRest stanza 'prod-stz' for
         pg1-path=/srv/pgsql/17/prod/data
INFO     creating pgBackRest stanza 'prod-stz'
INFO     checking pgBackRest configuration for stanza 'prod-stz'
INFO     creating instance dumps directory: /srv/dumps/17-prod
$ pglift instance exec prod psql
[17/prod] postgres@~=# CREATE DATABASE myapp;
CREATE DATABASE
$ pglift instance stop prod
$ INFO     stopping PostgreSQL 17/prod
$ rm -rf /srv/pgsql/17/prod/{data,wal} # on supprime les données de notre instance

La commande pglift instance list, retourne maintenant une liste vide. Nos données sont potentiellement perdues, heureusement il est possible de les récupérer depuis la stanza pgBackRest (on utilise à nouveau prod-stz).

On peut reconstruire notre instance en utilisant un backup depuis la stanza prod-stz :

$ pglift instance create prod --version 17 --port 5775 --pgbackrest-stanza prod-stz
INFO     initializing PostgreSQL
> Confirm creation of instance from pgBackRest backup [y/n] (y): y
INFO     restoring from a pgBackRest backup
…
INFO     configuring pgBackRest stanza 'prod-stz' for
         pg1-path=/srv/pgsql/17/prod/data
INFO     creating pgBackRest stanza 'prod-stz'
INFO     checking pgBackRest configuration for stanza 'prod-stz'

Nos données sont à nouveau disponibles :

[17/prod] postgres@~=# \l+ myapp
List of databases
-[ RECORD 1 ]-----+-----------
Name              | myapp
Owner             | postgres
…

Édition du pg_hba

Depuis la sortie de pglift 1.0, un travail de fond a été mené afin de permettre l’édition des entrées HBA des instances. La version 2.0, en plus de bénéficier de ce travail, permet aussi de modifier les entrées HBA pour les instances configurées via Patroni :

$ pglift instance create demopatroni1 --patroni-cluster=demo-patroni \
  --patroni-node=demo-patroni-1 --port 5444

$ cat /srv/pglift/etc/patroni/17-demopatroni1.yaml | yq .postgresql.pg_hba
[
  "local   all             postgres                                trust",
  "local   all             all                                     trust",
  "host    all             all             127.0.0.1/32            trust",
  "host    all             all             ::1/128                 trust"
]

L’ajout et la suppression des entrées HBA peut donc être réalisée avec la commande pglift pghba. Comme le montre l’exemple suivant, cette commande valide et modifie la configuration Patroni de l’instance :

# Pour ajouter une entrée
$ pglift pghba -i demopatroni1 add --connection-type host \
  --connection-address 10.8.0.1 \
  --connection-netmask 24 \
  --database postgres \
  --user isidore \
  --method scram-sha-256

$ cat /srv/pglift/etc/patroni/17-demopatroni1.yaml | yq .postgresql.pg_hba
[
  "local   all             postgres                                trust",
  "local   all             all                                     trust",
  "host    all             all             127.0.0.1/32            trust",
  "host    all             all             ::1/128                 trust",
  "host    postgres        isidore         10.8.0.1        24      scram-sha-256"
]

# Pour retirer une entrée
$ pglift pghba -i demopatroni1 remove --connection-type host \
  --connection-address 10.8.0.1 \
  --connection-netmask 24 \
  --database postgres \
  --user isidore \
  --method scram-sha-256
$ cat /srv/pglift/etc/patroni/17-demopatroni1.yaml | yq .postgresql.pg_hba
[
  "local   all             postgres                                trust",
  "local   all             all                                     trust",
  "host    all             all             127.0.0.1/32            trust",
  "host    all             all             ::1/128                 trust"
]

Pour une instance « classique » (sans Patroni), depuis la version 1.8, l’utilisation de ces commandes entraîne la modification du fichier pg_hba.conf de l’instance.

Conversion d’une instance standalone en instance gérée par Patroni

Depuis pglift 1.8, il est possible de convertir une instance PostgreSQL standalone en membre d’une grappe gérée par Patroni.

L’instance standalone prod initiée de la sorte :

$ pglift instance create prod
INFO     initializing PostgreSQL
INFO     configuring PostgreSQL authentication
INFO     configuring PostgreSQL
INFO     starting PostgreSQL 17/prod
INFO     creating instance dumps directory: /srv/dumps/17-prod

$ pglift instance status prod
PostgreSQL: running

peut être convertie en membre d’une grappe Patroni (adoption). Cette opération est réalisable en utilisant la commande pglift instance alter ou en ajoutant les options pour Patroni lors de l’utilisation du module Ansible dalibo.pglift.instance :

$ pglift instance alter prod --patroni-cluster=demo-patroni \
  --patroni-node=demo-patroni-1
INFO     configuring PostgreSQL
INFO     stopping PostgreSQL 17/prod
INFO     setting up Patroni service
INFO     starting Patroni 17-prod

$ pglift instance status prod
PostgreSQL: running
Patroni API: running

Nouvelles options pour manipuler les schémas et extensions d’une base

Pour la version 1.7 de pglift, un travail de fond a été réalisé pour permettre de manipuler certains champs complexes, comme les extensions, qui peuvent inclure un nom, une version, et un état (présent ou absent)

Ce travail a notamment été réalisé pour introduire de nouvelles options permettant d’ajouter ou de supprimer des schémas et extensions à une base existante :

$ pglift database create mydb
INFO     creating 'mydb' database in 17/prod
$ pglift database alter mydb --add-schema myschema
INFO     altering 'mydb' database on instance 17/prod
INFO     creating schema 'myschema' in database mydb with owner 'postgres'
pglift database alter mydb --remove-schema myschema
INFO     altering 'mydb' database on instance 17/prod
INFO     dropping schema myschema from database mydb
$ pglift database alter mydb --add-extension pgcrypto
INFO     altering 'mydb' database on instance 17/prod
INFO     creating extension 'pgcrypto' in database mydb
$ pglift database alter mydb --remove-extension pgcrypto
INFO     altering 'mydb' database on instance 17/prod
INFO     dropping extension 'pgcrypto'

Au passage, l’interface ligne de commande a été améliorée pour afficher ces champs complexes. Depuis cette version de pglift, les informations concernant les schemas et extensions d’une base sont plus facilement visibles :

$ pglift database get mydb --output-format=json
{
  "name": "mydb",
  "owner": "postgres",
  "settings": null,
  "schemas": [
    {
      "name": "myschema",
      "owner": "postgres"
    },
    {
      "name": "public",
      "owner": "pg_database_owner"
    }
  ],
  "extensions": [
    {
      "name": "pgcrypto",
      "schema": "public",
      "version": "1.3"
    }
  ],
  …
}

Ces nouveautés ont aussi permis d’améliorer l’utilisation des options schemas et extensions via Ansible. Il est maintenant possible de déclarer l’ajout ou la suppression de ces objets via un Playbook Ansible (clé state, valeur present ou absent, pour les schemas et extensions) :

- name: my postgresql instances
  hosts: localhost
  vars:
    port: 5432
    - name: Add mydb database with schema
      dalibo.pglift.database:
        name: mydb
        instance: prod
        schemas:
          - name: myschema
            state: present
          - name: my_other_schema
            state: present
        extensions:
          - name: pgcrypto
            state: present
            version: 1.3

Ces travaux pour les schemas et extensions ont servi de base pour ajouter le support des slots de réplication d’une instance. Depuis pglift 1.8, ce mécanisme peut être utilisé pour créer et supprimer des slots avec les options --create-slot et --drop-slot ou via le module Ansible dalibo.pglift.instance.

Nouveautés de pglift 2.0

Numéro de version facultatif dans les chemins

pglift est à présent paramétrable sans numéro de version pour les chemins dédiés au PGDATA (datadir), aux WAL (waldir) et pour les sauvegardes logiques (dumps_directory).

Par exemple, la configuration suivante est maintenant valide et permet de gérer des instances sans le numéro de version dans ces chemins :

---
postgresql:
  waldir: /srv/pgsql/{name}/waldir
  datadir: /srv/pgsql/{name}/data
  dumps_directory: /srv/pgsql/{name}/dumps
$ pglift instance create prod
INFO     initializing PostgreSQL
INFO     configuring PostgreSQL authentication
INFO     configuring PostgreSQL
INFO     starting PostgreSQL 17/prod
INFO     creating instance dumps directory: /srv/pgsql/prod/dumps
$ pglift instance get prod --output-format=json | jq -r '.wal_directory, .data_directory'
/srv/pgsql/prod/wal
/srv/pgsql/prod/data

Ce changement permet, au contraire de la version 1 de pglift, une plus grande souplesse pour configurer les chemins relatifs aux instances.

Modèle de configuration pour Patroni

Avec cette nouvelle version, il est désormais possible de personnaliser la configuration des instances Patroni. Les utilisateurices peuvent utiliser, pour Patroni, le mécanisme de template déjà disponible pour certains autres composants configurables via pglift.

Par exemple, un·e utilisateurice peut garnir le fichier ${XDG_CONFIG_HOME}/pglift/patroni/patroni.yaml avec le template suivant :

---
bootstrap:
  dcs:
    loop_wait: 10
    retry_timeout: 3
watchdog:
  mode: 'off'
tags:
  demo1: mytag

Ce modèle de configuration sera ensuite utilisé lors de la création des instances Patroni :

$ pglift instance create demo1 --patroni-cluster=pgdemo1 --patroni-node=demo1
$ cat /home/pglift/.local/share/pglift/etc/patroni/17-demo1.yaml | yq .tags
{
  "demo1": "mytag"
}
$ cat /home/pglift/.local/share/pglift/etc/patroni/17-demo1.yaml | yq .bootstrap.dcs
{
  "loop_wait": 10,
  "retry_timeout": 3
}
$ patronictl show-config
loop_wait: 10
retry_timeout: 3

Cette fonctionnalité offre plus de liberté pour configurer Patroni.

Création d’instance sans pgBackRest

pglift 2.0 permet la création d’instance sans pgBackRest et ce même si ce dernier est configuré.

Avec les versions précédentes de pglift, lorsque pgBackRest était configuré, il était obligatoire de spécifier les options dédiées (Ex : --pgbackrest-stanza) lors de la création d’une instance. Par exemple, avec pglift 1.9 et pgBackRest configuré, l’utilisateurice devait à minima déclarer la stanza :

$ pglift instance create prod_without_backup
Usage: pglift instance create [OPTIONS] NAME
Try 'pglift instance create --help' for help.

Error: Missing option '--pgbackrest-stanza'.

Il n’est plus obligatoire de spécifier ces options, avec la version 2.0 la commande ci-dessus fonctionne et ce même si pgBackRest est configuré. Dans un tel cas, l’instance sera créée et configurée sans le composant pgBackRest et donc sans sauvegarde au fil de l’eau.

Nouvelles options diff et dry-run

Option diff

Certaines sous commandes de pglift permettent de visualiser les modifications réalisées en utilisant l’option --diff. Cette option est utilisable directement avec la ligne de commande ou via la collection Ansible dédiée à pglift.

Par exemple, la modification du port d’écoute avec l’option --diff (commande : pglift instance alter pg1 --diff --port 9981), va afficher la sortie suivante :

--- /srv/pgsql/17/pg1/data/postgresql.conf
+++ /srv/pgsql/17/pg1/data/postgresql.conf
@@ -61,7 +61,7 @@
                                        # comma-separated list of addresses;
                                        # defaults to 'localhost'; use '*' for all
                                        # (change requires restart)
-port = 5432  # (change requires restart)
+port = 9981  # (change requires restart)
 #max_connections = 100  # (change requires restart)
 #reserved_connections = 0              # (change requires restart)
 #superuser_reserved_connections = 3    # (change requires restart)

Pour utiliser cette fonctionnalité avec Ansible, il est possible d’appeler ansible-playbook avec l’option --diff ou positionner la clé diff dans les Playbooks. Le Playbook suivant active cette fonctionnalité par défaut, les différences seront systématiquement affichées lors de l’exécution de la tâche :

- name: My postgresql instances
  hosts: localhost
  tasks:
    - name: Create production instance
      diff: true
      dalibo.pglift.instance:
        name: prod
        state: started
        port: 5432
        settings:
          max_connections: 200
        surole_password: changeme
$ ansible-playbook --diff instance-production.yaml

TASK [Create production instance] **************************************
--- before: /srv/pgsql/17/prod/data/pg_hba.conf
+++ after: /srv/pgsql/17/prod/data/pg_hba.conf
@@ -112,15 +112,7 @@


 # TYPE  DATABASE        USER            ADDRESS                 METHOD
-
-# "local" is for Unix domain socket connections only
+local   all             postgres                                trust
 local   all             all                                     trust
-# IPv4 local connections:
 host    all             all             127.0.0.1/32            trust
-# IPv6 local connections:
 host    all             all             ::1/128                 trust
-# Allow replication connections from localhost, by a user with the
-# replication privilege.
-local   replication     all                                     trust
-host    replication     all             127.0.0.1/32            trust
-host    replication     all             ::1/128                 trust

--- before: /srv/pgsql/17/prod/data/postgresql.conf
+++ after: /srv/pgsql/17/prod/data/postgresql.conf
@@ -61,11 +61,11 @@
                    # comma-separated list of addresses;
                    # defaults to 'localhost'; use '*' for all
                    # (change requires restart)
-#port = 5432               # (change requires restart)
-max_connections = 100          # (change requires restart)
+port = 5432  # (change requires restart)
+max_connections = 200  # (change requires restart)
 #reserved_connections = 0      # (change requires restart)
 #superuser_reserved_connections = 3    # (change requires restart)
-#unix_socket_directories = '/var/run/postgresql' # comma-separated list of directories
+unix_socket_directories = '/tmp'  # comma-separated list of directories

Option dry-run

L’option --dry-run est maintenant disponible pour certaines sous commandes de pglift. Elle permet de simuler les actions sans effectuer les modifications réellement.

Par exemple, la sous commande pgconf, avec l’option --dry-run, permet de simuler et visualiser les modifications :

$ pglift --non-interactive pgconf -i prod set --dry-run max_connections=32
INFO     configuring PostgreSQL
WARNING  instance 17/prod needs restart due to parameter changes: max_connections
max_connections: 16 -> 32
DRY RUN: no changes made

Conclusion

pglift est maintenant utilisé par l’intégralité de nos clients https://www.dalibo.com/socle. La sortie de la version 2.0 est un indicateur important concernant la maturité du projet. C’est le résultat de plusieurs mois de travail, d’échanges et de collaboration avec nos clients.

Afin de rester concis, nous n’avons présenté que quelques fonctionnalités majeures parues depuis pglift 1.0. Cet article aurait pu aussi aborder les améliorations suivantes :

Pour plus d’information concernant les nouveauté et correctifs de cette nouvelle version ou pglift en général, nous vous invitons à :


DALIBO

DALIBO est le spécialiste français de PostgreSQL®. Nous proposons du support, de la formation et du conseil depuis 2005.