--- - name: Check role exists become: true become_user: postgres ansible.builtin.shell: '/usr/bin/psql -Atc "SELECT count(rolname) FROM pg_roles where rolname=''replicator''"' # noqa command-instead-of-shell register: role_check ignore_errors: true # noqa ignore-errors no-changed-when - name: Create role if necessary become: true become_user: postgres ansible.builtin.shell: "/usr/bin/psql -c 'CREATE ROLE replicator WITH REPLICATION LOGIN;'" when: role_check.stdout == "0" register: cmd_ret changed_when: cmd_ret.rc != 0 - name: Change password with scram-sha-256! for replicator and set password become: true become_user: postgres ansible.builtin.shell: >- /usr/bin/psql -c "SET password_encryption = 'scram-sha-256'; ALTER ROLE replicator WITH PASSWORD '{{ postgres_replicator_user_password }}'" register: cmd_ret changed_when: cmd_ret.rc != 0 - name: Setup pg_hba.conf for replicator user ansible.builtin.lineinfile: state: present regex: "^host[ ]+replication[ ]+replicator" line: "host replication replicator {{ shared_service_pg_slave_ip }}/32 trust" path: /etc/postgresql/{{ default_postgres_version }}/main/pg_hba.conf register: pg_hba_conf_replicator - name: Set 'wal_level = replica' for master postgresql instance ansible.builtin.lineinfile: state: present regex: "^wal_level" line: "wal_level = replica" path: /etc/postgresql/{{ default_postgres_version }}/main/postgresql.conf register: wal_level - name: Set 'max_wal_senders = 10' for master postgresql instance ansible.builtin.lineinfile: state: present regex: "^max_wal_senders" line: "max_wal_senders = 10" path: /etc/postgresql/{{ default_postgres_version }}/main/postgresql.conf register: max_wal_senders - name: Set 'archive_mode = on' for master postgresql instance ansible.builtin.lineinfile: state: present regex: "^archive_mode" line: "archive_mode = on" path: /etc/postgresql/{{ default_postgres_version }}/main/postgresql.conf register: archive_mode - name: Set 'archive_command = cp -f %p /postgresql/replication/%f' for master postgresql instance ansible.builtin.lineinfile: state: present regex: "^archive_command" line: "archive_command = 'cp -f %p /postgresql/replication/%f'" path: /etc/postgresql/{{ default_postgres_version }}/main/postgresql.conf register: archive_command - name: Set 'wal_keep_size = 16' for master postgresql instance ansible.builtin.lineinfile: state: present regex: "^wal_keep_size" line: "wal_keep_size = 16" path: /etc/postgresql/{{ default_postgres_version }}/main/postgresql.conf register: wal_keep_size - name: Install nfs packages ansible.builtin.apt: name: - nfs-kernel-server - nfs-common state: present update_cache: true cache_valid_time: 900 - name: Create nfs share for archive ansible.builtin.lineinfile: path: /etc/exports regex: "^/postgresql/replication" line: "/postgresql/replication/ {{ shared_service_pg_slave_ip }}/32(rw,crossmnt,root_squash,no_subtree_check,sync)" state: present register: nfsshare_archive_check - name: Get service facts ansible.builtin.service_facts: - name: Check existence of necessary services vars: services: - name: postgresql.service - name: nfs-kernel-server.service block: - name: "Check state of {{ item.name }}" ansible.builtin.fail: msg: "{{ item.name }} is not present on this system, why? It should have been there!" when: ansible_facts.services[item.name] is not defined loop: "{{ services }}" - name: Restart nfs-server if necessary # noqa no-handler ansible.builtin.service: name: nfs-kernel-server state: restarted when: nfsshare_archive_check.changed or ansible_facts.services["nfs-kernel-server.service"].state != "active" - name: Restart postgres if necessary # noqa no-handler ansible.builtin.service: name: postgresql state: restarted when: pg_hba_conf_replicator.changed or wal_level.changed or archive_mode.changed or archive_command.changed or max_wal_senders.changed or wal_keep_size.changed or ansible_facts.services["postgresql.service"].state != "active" - name: Create extension pgcrypto for template1 become: true become_user: postgres ansible.builtin.shell: '/usr/bin/psql template1 -c "create extension if not exists pgcrypto;"' ignore_errors: true # noqa ignore-errors no-changed-when - name: Check database replication_cron exists become: true become_user: postgres ansible.builtin.shell: '/usr/bin/psql -Atc "SELECT count(*) FROM pg_database WHERE datname = ''replication_cron''"' register: database_replication_check ignore_errors: true # noqa ignore-errors no-changed-when - name: Create replication_cron update database become: true become_user: postgres ansible.builtin.shell: '/usr/bin/psql -c "CREATE DATABASE replication_cron;"' when: database_replication_check.stdout == "0" ignore_errors: true # noqa ignore-errors no-changed-when - name: Create replication update schema become: true become_user: postgres ansible.builtin.shell: '/usr/bin/psql replication_cron -c "CREATE SCHEMA IF NOT EXISTS replication_cron;"' ignore_errors: true # noqa ignore-errors no-changed-when - name: Create replication update table become: true become_user: postgres ansible.builtin.shell: '/usr/bin/psql replication_cron -c "CREATE TABLE IF NOT EXISTS replication_cron.replication_cron (dt timestamp);"' ignore_errors: true # noqa ignore-errors no-changed-when - name: Create dummy update data become: true become_user: postgres ansible.builtin.shell: >- /usr/bin/psql replication_cron -c "INSERT INTO replication_cron.replication_cron SELECT NOW() WHERE NOT EXISTS (SELECT 1 FROM replication_cron.replication_cron)" register: cmd_ret changed_when: cmd_ret.rc != 0 ignore_errors: true # noqa command-instead-of-shell - name: Ensure a cron runs every 5 minutes and update replication check table" ansible.builtin.cron: name: "update replication table" minute: "*/5" job: su - postgres -c "/usr/bin/psql replication_cron -c \"UPDATE replication_cron.replication_cron SET dt=now();\"" - name: Check replication slot exists become: true become_user: postgres ansible.builtin.shell: '/usr/bin/psql -Atc "select count(*) from pg_replication_slots where slot_name=''pgstandby1''"' register: replication_slot_check ignore_errors: true # noqa ignore-errors no-changed-when - name: Create replication-slot become: true become_user: postgres ansible.builtin.shell: '/usr/bin/psql -Atc "SELECT pg_create_physical_replication_slot(''pgstandby1'');"' when: replication_slot_check.stdout == "0" register: cmd_ret changed_when: cmd_ret.rc != 0 ignore_errors: true # noqa command-instead-of-shell # only needed in case of install from scratch - name: "Ensure test db stuff" when: postgres_ensure_testdb | default(False) block: - name: "Copy testdb.sql to ensure test DB" ansible.builtin.copy: src: "{{ item }}" dest: "/tmp/{{ item }}" mode: "0444" owner: postgres group: postgres loop: - testdb.sql - name: "Ensure test DB" become: true become_user: postgres community.postgresql.postgresql_db: name: dummytestdb - name: "Ensure content for test DB" become: true become_user: postgres community.postgresql.postgresql_db: name: dummytestdb state: restore target: /tmp/testdb.sql