DEBOPS.POSTGRESQL(5)

NAME
debops.postgresql - Manage PostgreSQL client using Ansible

SYNOPSIS

debops service/postgresql [--limit group,host,...] [--diff] [--check] [--tags tag1,tag2,...] [--skip-tags tag1,tag2,...] [<ansible-playbook options>] ...

DESCRIPTION

PostgreSQL <https://www.postgresql.org/> is a popular relational open source database. The debops.postgresql role can be used to create and manage PostgreSQL roles and databases on local or remote PostgreSQL servers.

To manage the PostgreSQL server itself, you will need to use debops.postgresql_server role.

GETTING STARTED

debops.postgresql role is only the client part. For a working PostgreSQL installation, debops.postgresql_server also needs to run somewhere. It can be either on the same host, or on a separate one.

See the debops.postgresql_server documentation to learn how to install the database server itself.

The PostgreSQL version installed by the role will be a default version offered by the distribution. If you want PostgreSQL 9.4 on Debian Wheezy, or an upstream version of the server, you can enable the upstream APT repository by adding in inventory:

postgresql__upstream: True

Check postgresql__preferred_version to learn more about selecting custom PostgreSQL versions.

  Server configuration

The role supports different modes of operation, depending on the presence of a PostgreSQL server installed locally or not.

  Local database server

If the database server is installed locally, it will be automatically detected and used by the debops.postgresql role without any additional configuration.

If a remote server was used previously, and then a local one was installed, it will automatically override the remote configuration. You might need to recreate the databases and user accounts in that case.

  Remote database server

If your PostgreSQL server is configured on a remote host and debops.postgresql does not detect a local installation, it won't manage databases or user accounts without a server specified.

To point it to a server, you need to set a variable in the inventory: postgresql__server: 'db.example.org'

This needs to be a FQDN address or an IP address of a host with the PostgreSQL server installed. This host will be accessed by Ansible using task delegation, so it needs to be accessible and managed by Ansible. Currently the role only supports one server at a time.

If you use debops.pki to manage SSL certificates and you configured PostgreSQL server with them, remote connections to the database will be automatically encrypted. The default server configuration requires remote connections to be done over SSL, otherwise the connection is dropped.

  Example inventory

To enable PostgreSQL client support on a host, you need to add that host to [debops_service_postgresql] Ansible group: [debops_service_postgresql] hostname

When PostgreSQL server is properly configured, or installed locally, you can create user accounts and databases using inventory variables:

postgresql__roles:
  - name: 'application'
  - name: 'application_production'
    flags: [ 'NOLOGIN' ]
postgresql__databases:
  - database: 'application_production'
    owner:    'application_production'
postgresql__groups:
  - roles:  [ 'application' ]
    groups: [ 'application_production' ]
    database: 'application_production'
postgresql__pgpass:
  - owner: 'application'

The above set of variables will create the PostgreSQL roles application and application_production, which is meant to manage the database and cannot directly be logged into.

The application_production PostgreSQL database will be created on the server and the application_production role will be its owner.

The application role will be granted access to the application_production role and all of its objects.

Next, Ansible will ensure that the local system group and user account application exists, and will create ~/.pgpass with PostgreSQL user and password stored for easier access.

  Example playbook

Here's an example Ansible playbook that uses the debops.postgresql role:

---
- name: Manage PostgreSQL client
  collections: [ 'debops.debops', 'debops.roles01',
                 'debops.roles02', 'debops.roles03' ]
  hosts: [ 'debops_service_postgresql' ]
  become: True
  environment: '{{ inventory__environment | d({})
                   | combine(inventory__group_environment | d({}))
                   | combine(inventory__host_environment  | d({})) }}'
  roles:
    - role: keyring
      tags: [ 'role::keyring', 'skip::keyring', 'role::postgresql' ]
      keyring__dependent_apt_keys:
        - '{{ postgresql__keyring__dependent_apt_keys }}'
    - role: apt_preferences
      tags: [ 'role::apt_preferences', 'skip::apt_preferences' ]
      apt_preferences__dependent_list:
        - '{{ postgresql__apt_preferences__dependent_list }}'
    - role: python
      tags: [ 'role::python', 'skip::python', 'role::postgresql' ]
      python__dependent_packages3:
        - '{{ postgresql__python__dependent_packages3 }}'
      python__dependent_packages2:
        - '{{ postgresql__python__dependent_packages2 }}'
    - role: postgresql
      tags: [ 'role::postgresql', 'skip::postgresql' ]

  Local Ansible facts, custom tasks

Role creates a set of local Ansible facts which can be used by other roles to create database management tasks that work both with local and remote PostgreSQL servers. These facts are:

•   ansible_local.postgresql.delegate_to

•   ansible_local.postgresql.server

•   ansible_local.postgresql.port

•   ansible_local.postgresql.user

•   ansible_local.postgresql.version

    These variables can be used in Ansible tasks to provide correct values pointing to the correct PostgreSQL server. An example set of tasks to create a role and database:

    - name: Create database role
      postgresql_user:
        name: '{{ application_database_user }}'
        password: '{{ application_database_password }}'
        state: 'present'
      delegate_to: '{{ ansible_local.postgresql.delegate_to }}'
    - name: Create application database
      postgresql_db:
        name: '{{ application_database_name }}'
        owner: '{{ application_database_user }}'
        state: 'present'
      delegate_to: '{{ ansible_local.postgresql.delegate_to }}'
      register: application_register_database

DEFAULT VARIABLE DETAILS

Some of debops.postgresql default variables have more extensive configuration than simple strings or lists, here you can find documentation and examples for them.

  postgresql__preferred_version

By default the role installs the PostgreSQL version preferred by the APT package manager. This behavior is influenced by how the PostgreSQL is packaged in Debian - each version has its own set of packages with the version as a suffix, and there's a set of metapackages which depend on the version available in the distribution (by default only 1 version is available).

Multiple PostgreSQL versions become available after enabling the upstream APT repository. To choose a different version than the default one, you need to set two variables in the inventory:

postgresql__preferred_version
    The value of this variable should be set as the version of the PostgreSQL you wish the role to manage (it does not influence the APT packages the role installs, but what version is used in different file/directory paths managed by the role, what features are enabled/disabled in the configuration, etc.).

postgresql__base_packages
    This is a list of APT packages which will be used by the role to install PostgreSQL. By default, it contains the metapackages which install the highest available version of PostgreSQL packages. To select a different version, you need to change the list of packages.

    For example, to install PostgreSQL 9.3 instead of the default available version, in inventory you need to define:

    postgresql__upstream: True
    postgresql__preferred_version: '9.3'
    postgresql__base_packages: [ 'postgresql-client-9.3' ]

    Remember that role does not support management of multiple PostgreSQL versions at the same time. The above variables should be defined in the inventory at all times, otherwise role might revert to the default PostgreSQL packages and version, and break your installation. This also is true for server upgrades. The preferred way to make an upgrade is to configure a new database server with desired PostgreSQL version and move the database to it.

    You might also need to set similar set of variables for the debops.postgresql_server role to keep both of the roles in sync. Refer to its documentation for details.

  postgresql__user_clusters

This list defines what entries will be set in /etc/postgresql-common/user_clusters configuration file. It is used by pg_wrapper in Debian to direct PostgreSQL-related commands to correct clusters. DebOps uses the default entry to redirect PostgreSQL-related commands like psql to either local or remote PostgreSQL server.

Each entry is defined by a YAML dict. Supported parameters:

user
    Required. String or list with UNIX account usernames to include in a given entry. You can specify * to use any user account.

group
    Required. String or list with UNIX group names to include in a given entry. You can specify * to use any group.

version
    Optional. Specify PostgreSQL version to use for a given entry. If not defined, default PostgreSQL detected by the role will be used.

cluster
    Optional. Specify name of the cluster to direct the commands to. If not specified, main cluster will be used.

host
    Optional. IP address or hostname of the server the PostgreSQL database is stored as. Requires port to be specified as well. Replaces cluster.

port
    Optional. TCP port to connect to as the PostgreSQL server. Requires host to be specified as well. Replaces cluster.

database
    Required. Name of the database to connect to by default. If * is specified, users will connect to the database with the same name as their UNIX account.

  postgresql__roles

PostgreSQL uses Roles <https://www.postgresql.org/docs/current/user-manag.html> as database accounts as well as groups.

Roles can have certain permissions granted to them by the server which allow access to database objects. This list can be used to create roles on a PostgreSQL server. Each role is defined as a YAML dictionary.

role or name
    Required. The name of a given role.

port
    Optional. By default roles are created on the local or remote PostgreSQL server's default cluster (5432). You can specify a different port to change the cluster which will be used.

password
    Optional. Specify the password for a given PostgreSQL role. If not set, a random password will be generated and stored in secret/ directory. See debops.secret role for more details.

encrypted
    Optional, bool. Specify if a given password is already encrypted or not.

expires
    Optional. Specify password expiration date as a PostgreSQL timestamp value.

flags
    Optional. YAML list of role attribute flags which should be applied to a given PostgreSQL role. Choices: [NO]SUPERUSER, [NO]CREATEROLE, [NO]CREATEUSER, [NO]CREATEDB, [NO]INHERIT, [NO]LOGIN, [NO]REPLICATION.

    If a given role should manage a particular database, you can specify additional parameters:

db  Name of the database to manage. Only one database can be configured in a role entry at a time.

priv
    YAML list of privileges to grant for a given role to specified database. List will be joined using / character into one privilege string.

  Examples

Create a PostgreSQL role:

postgresql__roles:
  - name: 'alpha'

Create a role and grant specific attribute flags:

postgresql__roles:
  - name: 'beta'
    flags: [ 'NOLOGIN' ]

Create a role and grant privileges to a particular database:

postgresql__roles:
  - name: 'gamma'
    db: 'gamma'
    priv: [ 'CONNECT', 'table1:ALL' ]

  postgresql__groups

Access to one or more PostgreSQL roles can be granted to other roles; that way an application role and database role can have different set of privileges. This list can be used to define these "groups" automatically. Recognized parameters:

roles
    Required. List of roles which will be granted access to specified "groups".

groups
    Required. List of role "groups" to grant access to.

database
    Required. Name of the database on which to grant privileges.

port
    Optional. By default roles are managed on the local or remote PostgreSQL server's default cluster (5432). You can specify a different port to change the cluster which will be used.

  Examples

Grant membership to other roles:

postgresql__groups:
  - roles:  [ 'alpha', 'beta' ]
    groups: [ 'gamma' ]
    database: 'gamma'

  postgresql__databases

List of PostgreSQL databases to create or manage on a PostgreSQL server. Known parameters:

database or name
    Required. Database name.

owner
    Optional. Specifies the PostgreSQL role which will be an owner of a particular database. If not specified, database will be owned by PostgreSQL superuser role, usually postgres.

    If owner is specified, given role will be granted all privileges to the database and will have grant option enabled for a given database.

template
    Optional. Specify name of the database which will be used as the template for new database.

encoding
    Optional. Default encoding used by a given database. If not supplied it falls back to the server default, derived from postgresql_server__locale on the postgresql_server role.

create_db
    Optional. Set this to False when granting a role specific privileges on an existing database.

type
    Optional. Type of database object to set privileges on. Default: schema.

objs
    Optional. Comma separated list of database objects to set privileges on. Default: public.

privs
    Optional. Comma separated list of privileges to grant. Default: ALL.

grant_option
    Optional. Whether role (owner) may grant/revoke the specified privileges to others. Default: yes.

  Examples

Create database owned by a specified role:

postgresql__databases:
  - name: 'gamma'
    owner: 'gamma'

Create database owned by a specified role and grant select privilege on all tables in schema public to another role:

postgresql__databases:
  - name: 'gamma'
    owner: 'gamma'
  - name: 'gamma'
    owner: 'alpha'
    create_db: False
    type: 'table'
    objs: 'ALL_IN_SCHEMA'
    public_privs: [ 'SELECT' ]
    grant_option: 'no'

  postgresql__extensions

List of YAML dictionaries that specify what extensions to enable or disable in a PostgreSQL database. Each dictionary can configure one extension at a time. Known parameters:

database
    Required. Name of the database to configure, it needs to be an existing database.

extension
    Required. Name of the PostgreSQL extension to configure.

port
    Optional. The PostgreSQL cluster port number. If not specified, the default postgresql__port will be used automatically.

state
    Optional. Either present or absent. If not specified or present, the extension will be enabled for a given database; if absent, the extension will be disabled.

  Examples

Add a custom extension to a database:

postgresql__extensions:
  - database: 'gamma'
    extension: 'pg_trgm'

  postgresql__pgpass

The ~/.pgpass configuration file is used to store usernames and passwords used to login to local or remote PostgreSQL databases. Using this list you can configure entries for different servers on UNIX accounts. If an account or group is not present, it will be created automatically.

Each entry is defined by a YAML dictionary. Recognized parameters:

owner
    Required. Specify name of the UNIX account that should be configured to access PostgreSQL databases. If that account doesn't exist, it will be created automatically as a local account.

group
    Optional. Specify default group to use for a UNIX account. If it doesn't exist, it will be created as a local group. If it's not specified, a group with the same name as owner will be created automatically.

system
    Optional. If True (default), created local accounts will be "system" accounts with UID < 1000. If False, created accounts and groups will be "normal" accounts and groups.

home
    Specify home directory of created UNIX account. If not specified, parameter will be omitted (not changed if account is already present).

server
    Optional. Specify IP address or FQDN hostname of the server that you want to configure. If not specified, default server will be guessed automatically from postgresql__server variable.

port
    Optional. Specify default TCP port to use for PostgreSQL server entry. If not specified, postgresql__port value will be used instead.

database
    Optional. Specify name of the database that should be covered by a given entry. If not specified, * will be used which means any database.

role
    Optional. Specify PostgreSQL role covered by a given entry. If not specified, owner will be used by default.

password
    Optional. Specify cleartext password which should be used with a given entry. If not specified, password will be pulled from secret/ directory managed by debops.secret Ansible role.

  Examples

Create ~/.pgpass entry for a role with any database:

postgresql__pgpass:
  - owner: 'alpha'

Create ~/.pgpass entry for a specific database:

postgresql__pgpass:
  - owner: 'gamma'
    database: 'gamma'

AUTHOR
Maciej Delmanowski

COPYRIGHT
2014-2022, Maciej Delmanowski, Nick Janetakis, Robin Schneider and others