How to install and configure PostgreSQL database using Ansible Playbook

How to install and configure PostgreSQL database using Ansible Playbook

ansible_postgresql_automation

Test Environment

Fedora 33 installed

Here in this article we will see how we can utilize the Ansible modules to automate the installation and configuration of the PostgreSQL database on a Fedora Linux OS. Also we will use the PostgreSQL database modules to create user role and create a database using the user role which was created initially.

If you are interested in watching the video. Here is the youtube video on the same step by step procedure below.

Procedure

Step1: Identify the OS Platform and update the upgrade the system

Here in this step we are fetching the OS platform of the remote managed node on which we are trying to install and configure the PostgreSQL database and upgrade the system by installing the latest packages available in the repositories.

  - name: Get the OS platform
    command: cat /etc/redhat-release
    register: redhatRelease

  - name: Print the redhat-release
    debug: msg={{ redhatRelease.stdout }}

  - name: Update packages
    yum: name=* state=latest

Step2: Configure the PostgreSQL RPM repository

Once we have our remote managed node in the updated state, we can configure the Postgre SQL RPM repository from which we will be installing the Postgre SQL database server packages.

  - name: Install the PostgreSQL RPM repository
    dnf:
      name: "https://download.postgresql.org/pub/repos/yum/reporpms/F-34-x86_64/pgdg-fedora-repo-latest.noarch.rpm"
      state: present

Step3: Install PostgreSQL server package

Here we are going to install the PostgreSQL database server from the repository that we configured in our previous step.

  - name: Install PostgreSQL server
    dnf:
      name: postgresql14-server
      state: present

Step4: Check if PostgreSQL database is initialized

As a pre-requisite we will check if the PostgreSQL database server has been initialised by running the setup script. We are incorporating this step before the initialisation step to make sure that the playbook does not through any errors if its executed multiple time and the database server has been already initialised.

  - name: Check if Database is initialized
    stat:
      path: /var/lib/pgsql/14/data/pg_hba.conf
    register: result

Step5: Initialize the PostgreSQL database if not already done

Once the pre-requisite step has been executed, we will initialize the database only if the pg_hba.conf file is not present in the required location.

  - name: Initialize the database
    shell: /usr/pgsql-14/bin/postgresql-14-setup initdb
    when: not result.stat.exists

Step6: Allow remote connection to PostgreSQL database

Once the installation and initialisation of the database is completed, we are updating the default configuration files to make sure remote connection is enabled with username and password for authentication. For this we are going to update pg_hba.conf as shown below and copy the updated configuration file to required location on the PostgreSQL database server.

Also note that for local connection there is no authentication required as we updated the method to trust.

Updated pg_hba.conf file

...
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            scram-sha-256
# IPv6 local connections:
host    all             all             ::1/128                 scram-sha-256
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            scram-sha-256
host    replication     all             ::1/128                 scram-sha-256
# Allow access from everywhere
host    all             all             0.0.0.0/0                md5

Here is the task to copy the updated pg_hba.conf file.

  - name: Allow remote connection to PostgreSQL database
    copy:
      src: /home/admin/middleware/stack/ansible/playbooks/postgresql-setup/pg_hba.conf
      dest: /var/lib/pgsql/14/data/

Step7: Allow PostgreSQL database server to listen on all network interfaces

For this we are going to update the default postgresql.conf to listen on all network interfaces on port 5432. The default postgresql.conf file can be obtained from the remote managed node at the following location ‘/var/lib/pgsql/14/data/postgresql.conf’.

...
#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------

# - Connection Settings -

listen_addresses = '*'
#listen_addresses = 'localhost'         # what IP address(es) to listen on;
                                        # 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)
...

Here is the task to copy the updated postgresql.conf file.

  - name: Allow PostgreSQL to listen on all interfaces
    copy:
      src: /home/admin/middleware/stack/ansible/playbooks/postgresql-setup/postgresql.conf
      dest: /var/lib/pgsql/14/data/

Step8: Start the PostgreSQL database service

Now that we have our PostgreSQL database server installed and configured, we can start the service as shown below.

  - name: Start the database service
    service:
      name: postgresql-14
      state: started

Step9: Allow traffic for PostgreSQL database service

By default, the firewall setting does not allow for the remote connection to the PostgreSQL database service. For enabling the remote connection we need to updated the firewall setting to allow traffic for PostgreSQL database service as shown below.

  - name: Allow PostgreSQL database service
    firewalld:
      service: postgresql
      permanent: yes
      state: enabled

Step10: Completed ansible-playbook for PostgreSQL database server installation and configuration

Here is the complete playbook for the installation and configuration of the database service on Fedora linux OS. Please note hosts section contains the IP address of my remote managed node on which i am configuring the database. Please update this with your respective IP address, FQDN or group name of the database server based on the ansible inventory file in your environment.

[admin@fedser32 postgresql-setup]$ pwd
/home/admin/middleware/stack/ansible/playbooks/postgresql-setup
[admin@fedser32 postgresql-setup]$ cat install-postgresql.yml 
---
- name: Postgre SQL Database installation and configuration
  hosts: 192.168.122.234
  become: true
  become_user: root
  tasks:
  - name: Get the OS platform
    command: cat /etc/redhat-release
    register: redhatRelease

  - name: Print the redhat-release
    debug: msg={{ redhatRelease.stdout }}

  - name: Update packages
    yum: name=* state=latest

  - name: Configure the PostgreSQL RPM repository
    dnf:
      name: "https://download.postgresql.org/pub/repos/yum/reporpms/F-34-x86_64/pgdg-fedora-repo-latest.noarch.rpm"
      state: present

  - name: Install PostgreSQL server
    dnf:
      name: postgresql14-server
      state: present

  - name: Check if Database is initialized
    stat:
      path: /var/lib/pgsql/14/data/pg_hba.conf
    register: result

  - name: Initialize the database
    shell: /usr/pgsql-14/bin/postgresql-14-setup initdb
    when: not result.stat.exists

  - name: Allow remote connection to PostgreSQL database
    copy:
      src: /home/admin/middleware/stack/ansible/playbooks/postgresql-setup/pg_hba.conf
      dest: /var/lib/pgsql/14/data/

  - name: Allow PostgreSQL to listen on all interfaces
    copy:
      src: /home/admin/middleware/stack/ansible/playbooks/postgresql-setup/postgresql.conf
      dest: /var/lib/pgsql/14/data/

  - name: Start the database service
    service:
      name: postgresql-14
      state: started

  - name: Allow PostgreSQL database service
    firewalld:
      service: postgresql
      permanent: yes
      state: enabled

Step11: Execute the Playbook to install and configure the PostgreSQL database service

Here is the complete execution of the playbook to install and configure the PostgreSQL database service.

[admin@fedser32 postgresql-setup]$ ansible-playbook install-postgresql.yml 

PLAY [Postgre SQL Database installation and configuration] ***************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************
[DEPRECATION WARNING]: Distribution fedora 33 on host 192.168.122.234 should use /usr/bin/python3, but is using /usr/bin/python for backward compatibility 
with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See 
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information. This feature will be removed in version 2.12. 
Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
ok: [192.168.122.234]

TASK [Get the OS platform] ***********************************************************************************************************************************
changed: [192.168.122.234]

TASK [Print the redhat-release] ******************************************************************************************************************************
ok: [192.168.122.234] => {
    "msg": "Fedora release 33 (Thirty Three)"
}

TASK [Update packages] ***************************************************************************************************************************************
ok: [192.168.122.234]

TASK [Configure the PostgreSQL RPM repository] ***************************************************************************************************************
ok: [192.168.122.234]

TASK [Install PostgreSQL server] *****************************************************************************************************************************
ok: [192.168.122.234]

TASK [Check if Database is initialized] **********************************************************************************************************************
ok: [192.168.122.234]

TASK [Initialize the database] *******************************************************************************************************************************
skipping: [192.168.122.234]

TASK [Allow remote connection to PostgreSQL database] ********************************************************************************************************
ok: [192.168.122.234]

TASK [Allow PostgreSQL to listen on all interfaces] **********************************************************************************************************
ok: [192.168.122.234]

TASK [Start the database service] ****************************************************************************************************************************
ok: [192.168.122.234]

TASK [Allow PostgreSQL database service] *********************************************************************************************************************
ok: [192.168.122.234]

PLAY RECAP ***************************************************************************************************************************************************
192.168.122.234            : ok=11   changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0  

Step12: Install the Ansible PostgreSQL module

We need to install the Ansible PostgreSQL module so that we can managed the PostgreSQL database remotely using the Ansible Playbook. Here is the Ansible module which needs to be installed on the Ansible controller system.

Ansible module – https://galaxy.ansible.com/community/postgresql

[admin@fedser32 postgresql-setup]$ ansible-galaxy collection install community.postgresql

Step13: Setup a user role and database using the PostgreSQL modules

Here is a very basic ansible playbook which used the postgresql modules names postgresql_user and postgresql_db to create a user role and create a database using the role which we created.

[admin@fedser32 postgresql-setup]$ cat configure-postgresql.yml 
---
- name: Creating user roles and database
  hosts: all
  tasks:
  - name: Connect to default database and create a user with super prvileges
    postgresql_user:
      name: dbadmin
      password: dbadmin1234
      role_attr_flags: CREATEDB,SUPERUSER,CREATEROLE,LOGIN
  - name: Create a new database with name "testdatabase"
    postgresql_db:
      login_host: 192.168.122.234
      login_user: dbadmin
      login_password: dbadmin1234
      port: 5432
      name: testdatabase

Step14: Execute the playbook to create user role and database

Now, let’s execute the playbook to create the required user role with the mentioned privileges and create a database thereafter.

[admin@fedser32 postgresql-setup]$ ansible-playbook configure-postgresql.yml 

PLAY [Creating user roles and database] **********************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************
[DEPRECATION WARNING]: Distribution fedora 33 on host 192.168.122.234 should use /usr/bin/python3, but is using /usr/bin/python for backward compatibility 
with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See 
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information. This feature will be removed in version 2.12. 
Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
ok: [192.168.122.234]

TASK [Connect to default database and create a user with super prvileges] ************************************************************************************
changed: [192.168.122.234]

TASK [Create a new database with name "testdatabase"] ********************************************************************************************************
ok: [192.168.122.234]

PLAY RECAP ***************************************************************************************************************************************************
192.168.122.234            : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Step15: Validate the user role and database creation on remote node

We can SSH to our remote managed node (ie. database server) and validate whether the user role and database got created as per the playbook as shown below.

List user roles

[root@fedmaster data]# sudo -u postgres psql
psql (14.0)
Type "help" for help.

postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 dbadmin   | Superuser, Create role, Create DB                          | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

List databases

postgres=# \l
                                   List of databases
     Name     |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
--------------+----------+----------+-------------+-------------+-----------------------
 postgres     | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0    | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
              |          |          |             |             | postgres=CTc/postgres
 template1    | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
              |          |          |             |             | postgres=CTc/postgres
 testdatabase | dbadmin  | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 

Hope you enjoyed reading this article. Thank you..