You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hetzner-ansible/roles/postgres/tasks/master-requirements.yml

221 lines
7.5 KiB
YAML

---
- 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