Make Ansible "postgresql_ping" fail if the database does not exist

Posted by ads' corner on Wednesday, 2021-03-31
Posted in [Ansible][Postgresql][Postgresql-News]

Ansible has a very useful module “postgresql_ping” which checks connectivity to the database server. I’m using it in quite a few Playbooks as first step just to ensure that the database server is present - this fails early if there is a problem which otherwise just prevents the rest of the Playbook to work properly.

TASK [Check if database is available]
[WARNING]: PostgreSQL server is unavailable: could not connect to server: No such file or directory         Is the server running locally and accepting         connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
fatal: [127.0.0.1]: FAILED! => {"changed": false, "failed_when_result": true, "is_available": false, "server_version": {}}

However this module does not check if the database exists, just if the server is reachable. Example Playbook:

1
2
3
4
5
- name: Check if database is available
  postgresql_ping:
    db: "testdb"
  become: yes
  become_user: postgres

When I run the Playbook:

TASK [Check if database is available]
[WARNING]: PostgreSQL server is unavailable: FATAL:  database "testdb" does not exist
ok: [127.0.0.1]

As you can see, the database testdb does not exist. Which for the module is a reason to raise a warning, but not  a reason to fail.

One possible solution is to let this module do it’s work, and add a “postgresql_db” call next, which ensures that the database is created. But not every Playbook is supposed to create and populate a database, and has all the required parameters (owner, encoding, template ect) available. Therefore it would be nice if postgresql_ping fails early if the database in question doesn’t exist. That’s possible, with two more lines of code:

1
2
3
4
5
6
7
- name: Check if database is available
  postgresql_ping:
    db: "testdb"
  become: yes
  become_user: postgres
  register: ping_database
  failed_when: ping_database.warnings is defined

And the Playbook run:

TASK [Check if database is available]
[WARNING]: PostgreSQL server is unavailable: FATAL:  database "testdb" does not exist
fatal: [127.0.0.1]: FAILED! => {"changed": false, "failed_when_result": true, "is_available": false, "server_version": {}}

Together with “any_errors_fatal: True” this ends the entire Playbook early enough before I have to debug the problem later on.