DEV-1020 Initial commit new feature branch

qa
Görz, Friedrich 3 years ago committed by Michael Hähnel
parent 1b42d0118c
commit 8318792f1f

@ -145,12 +145,15 @@ docker_compose_path: "/usr/bin/docker-compose"
service_base_path: "/etc/smardigo"
devops_email_address: "nso.devops@netgo.de"
gitea_admin_email: "{{ devops_email_address }}"
lets_encrypt_email: "{{ devops_email_address }}"
connect_admin_email: "{{ devops_email_address }}"
keycloak_admin_email: "{{ devops_email_address }}"
pgadmin4_admin_email: "{{ devops_email_address }}"
grafana_admin_email: "{{ devops_email_address }}"
grafana_smardigo_email: "{{ devops_email_address }}"
harbor_oidc_admin_email: "{{ devops_email_address }}"
argocd_admin_email: "{{ devops_email_address }}"
http_port: "80"
https_port: "443"
@ -206,6 +209,12 @@ upstream_dns_servers:
- 185.12.64.1
- 185.12.64.2
harbor_username: "{{ docker_registry_username_vault }}"
harbor_token: "{{ docker_registry_token_vault }}"
keycloak_admin_username: "keycloak-admin"
keycloak_admin_password: "{{ keycloak_admin_password_vault }}"
# Note: all dollar signs in the hash need to be doubled for escaping.
# To create user:password pair, it's possible to use this command:
# echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
@ -214,3 +223,4 @@ traefik_admin_password_htpasswd: "{{ traefik_admin_password_htpasswd_vault }}"
mysql_root_username: "{{ mysql_root_username_vault }}"
mysql_root_password: "{{ mysql_root_password_vault }}"
lvm_volume_encryption: false

@ -1,5 +1,4 @@
---
hetzner_server_type: cpx11
hetzner_server_labels: "stage={{ stage }} service=postgres role={{ server_type }}"
@ -10,4 +9,10 @@ traefik_enabled: false
filebeat_postgres_enabled: true
custom_plattform_users:
- '{{ backupuser_user_name }}'
- "{{ backupuser_user_name }}"
postgres_homedir: "/var/lib/postgresql"
postgres_pgdatadir_lvm_hcloudvol_size: 10
postgres_pgdatadir_lvm_hcloudvol_count: 1
postgres_pgdatadir_lvm_hcloudvol_mountpath: "{{ postgres_homedir }}"

@ -0,0 +1,16 @@
---
shared_service_pg_master_ip: "{{ stage_server_infos
| selectattr('name', 'match', stage + '-postgres-01' )
| map(attribute='private_ip')
| list
| first
| default('-') }}"
shared_service_pg_slave_ip: "{{ stage_server_infos
| selectattr('name', 'match', stage + '-postgres-02' )
| map(attribute='private_ip')
| list
| first
| default('-') }}"
shared_service_postgres_01_hostname: "{{ stage }}-postgres-01"
shared_service_postgres_02_hostname: "{{ stage }}-postgres-02"

@ -0,0 +1,18 @@
---
shared_service_pg_master_ip: "{{ stage_server_infos
| selectattr('name', 'match', stage + '-postgres02-01' )
| map(attribute='private_ip')
| list
| first
| default('-') }}"
shared_service_pg_slave_ip: "{{ stage_server_infos
| selectattr('name', 'match', stage + '-postgres02-02' )
| map(attribute='private_ip')
| list
| first
| default('-') }}"
shared_service_postgres_01_hostname: "{{ stage }}-postgres02-01"
shared_service_postgres_02_hostname: "{{ stage }}-postgres02-02"
lvm_volume_encryption: true

@ -1,5 +1,4 @@
---
hetzner_server_type: "{{ hetzner_server_type_restore_database | default('cpx21') }}"
hetzner_server_labels: "stage={{ stage }} service=restore database_engine={{ database_engine | default('') }}"
@ -9,8 +8,8 @@ filebeat_enabled: false
node_exporter_enabled: false
custom_plattform_users:
- '{{ backupuser_user_name }}'
- "{{ backupuser_user_name }}"
# postgresql related
# defining type of server (naster|slave|restore)
# defining type of server (master|slave|restore)
server_type: restore

@ -52,6 +52,13 @@ alertmanager_admin_password_htpasswd: "{{ alertmanager_admin_password_htpasswd_v
netgo_msteams_hook_cd: "{{ netgo_msteams_hook_cd_vault }}"
netgo_msteams_hook_alerting: "{{ netgo_msteams_hook_alerting_vault }}"
management_oidc_client_secret: "{{ management_oidc_client_secret_vault }}"
# smardigo automation {{ stage }} gpg key
# https://git.dev-at.de/smardigo-hetzner/communication-keys/
# push mirror: https://{{ stage }}-gitea-01.smardigo.digital/gitea-admin/communication-keys/
gpg_key_smardigo_automation__private: "{{ gpg_key_smardigo_automation__private__vault }}"
custom_stage_plattform_users:
- hp.wissenbach

File diff suppressed because it is too large Load Diff

@ -0,0 +1,3 @@
---
server_type: "master"
lvm_volume_encryption: true

@ -0,0 +1,3 @@
---
server_type: "slave"
lvm_volume_encryption: true

@ -125,7 +125,7 @@
- hosts: postgres
serial: 1
become: yes
become: true
tasks:
- name: "Smardigo Patchday: stop service(s)"
ansible.builtin.systemd:
@ -134,10 +134,10 @@
- name: "Smardigo Patchday: update pkgs"
ansible.builtin.apt:
upgrade: yes
update_cache: yes
autoremove: yes
autoclean: yes
upgrade: true
update_cache: true
autoremove: true
autoclean: true
- name: "Smardigo Patchday: rebooting <{{ inventory_hostname }}>"
ansible.builtin.reboot:
@ -145,7 +145,7 @@
reboot_timeout: 300
- name: "Smardigo Patchday: wait_for host after reboot"
become: no
become: false
delegate_to: localhost
ansible.builtin.wait_for:
delay: 15
@ -154,22 +154,46 @@
host: '{{ stage_server_ip }}'
search_regex: OpenSSH
- name: "Smardigo Patchday: start services"
- name: "Open and mount LUKS encrypted LVM for datadir"
ansible.builtin.include_role:
name: lvm_with_hetzner_volumes
when: lvm_volume_encryption | bool
vars:
lvm_with_hetzner_volumes__volprefix: "postgres_datadir"
lvm_with_hetzner_volumes__volsize: "{{ postgres_pgdatadir_lvm_hcloudvol_size }}"
lvm_with_hetzner_volumes__volcount: "{{ postgres_pgdatadir_lvm_hcloudvol_count }}"
lvm_with_hetzner_volumes__mountpath: "{{ postgres_pgdatadir_lvm_hcloudvol_mountpath }}"
lvm_with_hetzner_volumes__passphrase: "{{ postgres_volume_encryption_passphrase }}"
- name: "Open and mount LUKS encrypted LVM for backupdir"
ansible.builtin.include_role:
name: lvm_with_hetzner_volumes
when: lvm_volume_encryption | bool and server_type == "slave"
vars:
lvm_with_hetzner_volumes__volprefix: "postgres-backup"
lvm_with_hetzner_volumes__volsize: "{{ postgres_backup_volume_size }}"
lvm_with_hetzner_volumes__volcount: "{{ postgres_backup_volume_count }}"
lvm_with_hetzner_volumes__mountpath: "{{ backup_directory }}"
lvm_with_hetzner_volumes__passphrase: "{{ postgres_volume_encryption_passphrase }}"
- name: "Smardigo Patchday: restart services"
ansible.builtin.systemd:
name: postgresql
state: started
state: restarted
# wait_for cannot be used anymore due to enabled SSL encryption for postgres connections in DEV-382
- name: "Smardigo Patchday: check if postgres is listing on net internal ip address"
become: no
become: false
community.postgresql.postgresql_ping:
port: 5432
ssl_mode: require
login_host: '{{ stage_private_server_ip }}'
register: check_postgres
ignore_errors: yes
ignore_errors: true
- name: "Smardigo Patchday: error-handling - ensure postgres started and check listing on net internal ip address"
when:
- not check_postgres.is_available
block:
- name: "Smardigo Patchday: error-handling - ensure service(s) started"
@ -178,7 +202,7 @@
state: started
- name: "Smardigo Patchday: error-handling - check if postgres is listing on net internal ip address"
become: no
become: false
community.postgresql.postgresql_ping:
port: 5432
ssl_mode: require
@ -206,27 +230,24 @@
your automation-bofh
when:
- not check_postgres.is_available
# due to bloody dependencies in SMA application startup, iam must be available during startup
# => patching IAM service outsourced in separate part to make sure that is up and running
- hosts: iam,keycloak
serial: 10
become: yes
become: true
tasks:
- name: "Smardigo Patchday: update pkgs"
ansible.builtin.apt:
upgrade: yes
update_cache: yes
autoremove: yes
autoclean: yes
upgrade: true
update_cache: true
autoremove: true
autoclean: true
- name: "Smardigo Patchday: find docker_compose.yml files"
ansible.builtin.find:
paths: '{{ service_base_path }}'
pattern: 'docker*.yml'
recurse: yes
recurse: true
register: docker_compose_services
- name: "Smardigo Patchday: shutdown services"
@ -241,7 +262,7 @@
reboot_timeout: 300
- name: "Smardigo Patchday: wait_for host after reboot"
become: no
become: false
delegate_to: localhost
ansible.builtin.wait_for:
delay: 15

@ -1,7 +1,6 @@
---
- name: "Getting all hcloud volumes for {{ inventory_hostname }}"
hcloud_volume_info:
hetzner.hcloud.hcloud_volume_info:
api_token: "{{ hetzner_authentication_ansible }}"
label_selector: "stage={{ stage }},bound_on={{ inventory_hostname }}"
register: hcloud_volumes_found
@ -9,31 +8,27 @@
become: false
- name: "Getting all hcloud volumes for {{ inventory_hostname }}"
debug:
ansible.builtin.debug:
msg: "{{ hcloud_volumes_found }}"
- name: "Setting all hcloud volumes for {{ inventory_hostname }}"
set_fact:
ansible.builtin.set_fact:
hcloud_volumes: "{{ hcloud_volumes_found.hcloud_volume_info | json_query(jmesquery) }}"
vars:
jmesquery: "[*].name"
- name: "remove delete protection for all hcloud volumes for {{ inventory_hostname }}"
hcloud_volume:
- name: "Remove delete protection for all hcloud volumes for {{ inventory_hostname }}"
hetzner.hcloud.hcloud_volume:
api_token: "{{ hetzner_authentication_ansible }}"
name: "{{ item }}"
delete_protection: no
delete_protection: false
delegate_to: 127.0.0.1
loop: "{{ hcloud_volumes }}"
- name: "Delete all hcloud volumes for {{ inventory_hostname }}"
hcloud_volume:
hetzner.hcloud.hcloud_volume:
api_token: "{{ hetzner_authentication_ansible }}"
name: "{{ item }}"
state: absent
delegate_to: 127.0.0.1
loop: "{{ hcloud_volumes }}"

@ -1,6 +1,6 @@
---
- name: "Creating some hcloud volumes for LVM purpose"
hcloud_volume:
hetzner.hcloud.hcloud_volume:
api_token: "{{ hetzner_authentication_ansible }}"
name: "{{ lvm_with_hetzner_volumes__volprefix }}-{{ inventory_hostname }}--vol{{ item }}"
server: "{{ inventory_hostname }}"
@ -11,69 +11,85 @@
vol_no: "{{ item | string }}"
size: "{{ lvm_with_hetzner_volumes__volsize }}"
state: present
delete_protection: yes
delete_protection: true
loop: "{{ range(1, lvm_with_hetzner_volumes__volcount + 1) | list }}"
register: created_volume
delegate_to: localhost
become: false
- name: "Getting all hcloud volumes for {{ inventory_hostname }}"
hcloud_volume_info:
hetzner.hcloud.hcloud_volume_info:
api_token: "{{ hetzner_authentication_ansible }}"
label_selector: "stage={{ stage }},used_for={{ lvm_with_hetzner_volumes__volprefix }},bound_on={{ inventory_hostname }}"
register: hcloud_volumes_found
delegate_to: localhost
become: false
- name: "Getting all hcloud volumes for {{ inventory_hostname }}"
debug:
msg: "{{ hcloud_volumes_found }}"
- name: "Setting LVM related VARs"
set_fact:
pvs: "{{ hcloud_volumes_found.hcloud_volume_info | json_query(jmesquery) }}"
ansible.builtin.set_fact:
pv_paths: "{{ hcloud_volumes_found.hcloud_volume_info | map(attribute='linux_device') | list }}"
pv_names: "{{ hcloud_volumes_found.hcloud_volume_info | map(attribute='name') | list }}"
vg_name: "vg.{{ lvm_with_hetzner_volumes__volprefix }}"
lv_name: "lv.{{ lvm_with_hetzner_volumes__volprefix }}"
vars:
jmesquery: "[*].linux_device"
encrypt_volumes: "{{ lvm_volume_encryption | bool }}"
when: hcloud_volumes_found.hcloud_volume_info | length > 0
- name: Manage LUKS container(s)
when: encrypt_volumes
block:
- name: Create LUKS container(s)
community.crypto.luks_device:
device: "{{ item.0 }}"
state: "present"
name: "{{ item.1 }}"
passphrase: "{{ lvm_with_hetzner_volumes__passphrase }}"
loop: "{{ pv_paths | zip(pv_names) | list }}"
- name: "Creating a volume group on top of all found hcloud volumes"
- name: Open LUKS container(s)
community.crypto.luks_device:
device: "{{ item.0 }}"
state: "opened"
name: "{{ item.1 }}"
passphrase: "{{ lvm_with_hetzner_volumes__passphrase }}"
loop: "{{ pv_paths | zip(pv_names) | list }}"
- name: "Creating a volume group on top of all found volumes"
community.general.lvg:
vg: "{{ vg_name }}"
pvs: "{{ pvs }}"
pvresize: yes
pvs: "{{ pv_names | map('regex_replace', '^(.*)$', '/dev/mapper/\\1') if encrypt_volumes else pv_paths }}"
pvresize: true
register: create_vg
when: hcloud_volumes_found.hcloud_volume_info | length > 0
- name: "Create logical volume" # noqa no-handler
community.general.lvol:
vg: "{{ vg_name }}"
lv: "{{ lv_name }}"
size: '100%PVS'
when:
- create_vg.changed
size: "100%PVS"
when: create_vg.changed
- name: "Format volume"
filesystem:
community.general.system.filesystem:
fstype: ext4
dev: "/dev/{{ vg_name }}/{{ lv_name }}"
- name: "Resize volume" # noqa no-handler
filesystem:
community.general.system.filesystem:
fstype: ext4
dev: "/dev/{{ vg_name }}/{{ lv_name }}"
resizefs: yes
resizefs: true
when:
- create_vg.changed
# set noqa linter 'tag' due to unknown file permissions/ownership for mount path ;
# must be set in role etc in which this role will be called!!!
- name: "Ensure mountpath exists without setting permission/ownership" # noqa risky-file-permissions
file:
ansible.builtin.file:
path: "{{ lvm_with_hetzner_volumes__mountpath }}"
state: directory
- name: "Mount created LVM volume"
mount:
ansible.posix.mount:
path: "{{ lvm_with_hetzner_volumes__mountpath }}"
src: "/dev/{{ vg_name }}/{{ lv_name }}"
fstype: ext4

@ -8,7 +8,7 @@
name: postgres
uid: 2000
group: postgres
home: '{{ postgres_homedir }}'
home: "{{ postgres_homedir }}"
system: true
shell: /bin/bash
@ -45,14 +45,14 @@
cache_valid_time: 900
state: present
loop:
- 'postgresql-{{ default_postgres_version }}'
- "postgresql-{{ default_postgres_version }}"
- python3-psycopg2
- name: "Set vars"
set_fact:
cert_private_key: '{{ postgres_homedir }}/{{ inventory_hostname }}.{{ domain }}-key.pem'
cert_public_key: '{{ postgres_homedir }}/{{ inventory_hostname }}.{{ domain }}-crt.pem'
ca_cert: '{{ postgres_homedir }}/ca-certificate.pem'
cert_private_key: "{{ postgres_homedir }}/{{ inventory_hostname }}.{{ domain }}-key.pem"
cert_public_key: "{{ postgres_homedir }}/{{ inventory_hostname }}.{{ domain }}-crt.pem"
ca_cert: "{{ postgres_homedir }}/ca-certificate.pem"
- name: "Include role for self-signed CA"
include_role:
@ -63,15 +63,15 @@
name: selfsigned_ca
tasks_from: _create_cert
vars:
selfsigned_ca_cert_private_key: '{{ cert_private_key }}'
selfsigned_ca_cert_private_key: "{{ cert_private_key }}"
selfsigned_ca_cert_private_key_group: postgres
selfsigned_ca_cert_public_key: '{{ cert_public_key }}'
selfsigned_ca_cacert: '{{ ca_cert }}'
selfsigned_ca_cert_public_key: "{{ cert_public_key }}"
selfsigned_ca_cacert: "{{ ca_cert }}"
selfsigned_ca_cert_subject:
CN: '{{ inventory_hostname }}.{{ domain }}'
CN: "{{ inventory_hostname }}.{{ domain }}"
selfsigned_ca_cert_altnames:
- 'DNS:{{ inventory_hostname }}.{{ domain }}'
- 'DNS:{{ inventory_hostname }}'
- "DNS:{{ inventory_hostname }}.{{ domain }}"
- "DNS:{{ inventory_hostname }}"
# selfsigned_ca_trigger_handler: restart postgres
- name: "ASSERT: stage_private_server_ip"
@ -86,9 +86,16 @@
regex: "{{ item.regex }}"
line: "{{ item.line }}"
path: /etc/postgresql/{{ default_postgres_version }}/main/postgresql.conf
loop: '{{ postgres_config }}'
loop: "{{ postgres_config }}"
notify: restart postgres
- name: "Updating pg_hba.conf entry for trusted admin user 'postgres'"
lineinfile:
state: "{{ database_state }}"
regex: "^hostssl[ ]+postgres[ ]+postgres"
line: "hostssl postgres postgres {{ stage_private_server_ip }}/32 trust"
path: /etc/postgresql/{{ default_postgres_version }}/main/pg_hba.conf
- name: "Creating archive directory if necessary"
file:
state: directory

@ -1,5 +1,4 @@
---
### tags:
- name: "Create/Resize LVM for datadir"
@ -10,6 +9,7 @@
lvm_with_hetzner_volumes__volsize: "{{ postgres_pgdatadir_lvm_hcloudvol_size }}"
lvm_with_hetzner_volumes__volcount: "{{ postgres_pgdatadir_lvm_hcloudvol_count }}"
lvm_with_hetzner_volumes__mountpath: "{{ postgres_pgdatadir_lvm_hcloudvol_mountpath }}"
lvm_with_hetzner_volumes__passphrase: "{{ postgres_volume_encryption_passphrase }}"
# Minimal requirements for postgres
- name: Include Base Requirements
@ -36,6 +36,7 @@
lvm_with_hetzner_volumes__volsize: "{{ postgres_backup_volume_size }}"
lvm_with_hetzner_volumes__volcount: "{{ postgres_backup_volume_count }}"
lvm_with_hetzner_volumes__mountpath: "{{ backup_directory }}"
lvm_with_hetzner_volumes__passphrase: "{{ postgres_volume_encryption_passphrase }}"
when: server_type == "slave"
args:
apply:
@ -43,5 +44,3 @@
- backup-requirements
tags:
- backup-requirements

@ -1,24 +1,31 @@
---
- name: Check role exists # noqa no-changed-when
become: yes
- name: Check role exists
become: true
become_user: postgres
shell: "/usr/bin/psql -Atc \"SELECT count(rolname) FROM pg_roles where rolname='replicator'\"" # noqa command-instead-of-shell
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: yes
become: true
become_user: postgres
shell: "/usr/bin/psql -c 'CREATE ROLE replicator WITH REPLICATION LOGIN;'"
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 # noqa no-changed-when
become: yes
- name: Change password with scram-sha-256! for replicator and set password
become: true
become_user: postgres
shell: "/usr/bin/psql -c \"set password_encryption = 'scram-sha-256';ALTER ROLE replicator WITH PASSWORD '{{ postgres_replicator_user_password }}';\""
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
lineinfile:
ansible.builtin.lineinfile:
state: present
regex: "^host[ ]+replication[ ]+replicator"
line: "host replication replicator {{ shared_service_pg_slave_ip }}/32 trust"
@ -26,7 +33,7 @@
register: pg_hba_conf_replicator
- name: Set 'wal_level = replica' for master postgresql instance
lineinfile:
ansible.builtin.lineinfile:
state: present
regex: "^wal_level"
line: "wal_level = replica"
@ -34,7 +41,7 @@
register: wal_level
- name: Set 'max_wal_senders = 10' for master postgresql instance
lineinfile:
ansible.builtin.lineinfile:
state: present
regex: "^max_wal_senders"
line: "max_wal_senders = 10"
@ -42,7 +49,7 @@
register: max_wal_senders
- name: Set 'archive_mode = on' for master postgresql instance
lineinfile:
ansible.builtin.lineinfile:
state: present
regex: "^archive_mode"
line: "archive_mode = on"
@ -50,7 +57,7 @@
register: archive_mode
- name: Set 'archive_command = cp -f %p /postgresql/replication/%f' for master postgresql instance
lineinfile:
ansible.builtin.lineinfile:
state: present
regex: "^archive_command"
line: "archive_command = 'cp -f %p /postgresql/replication/%f'"
@ -58,76 +65,109 @@
register: archive_command
- name: Set 'wal_keep_size = 16' for master postgresql instance
lineinfile:
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-server
apt: name=nfs-kernel-server state=present update_cache=yes cache_valid_time=900
- name: Install nfs-common
apt: name=nfs-common state=present update_cache=yes cache_valid_time=900
- 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
lineinfile:
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
service:
ansible.builtin.service:
name: nfs-kernel-server
state: restarted
when: nfsshare_archive_check.changed
when: nfsshare_archive_check.changed or
ansible_facts.services["nfs-kernel-server.service"].state != "active"
- name: Restart postgres if necessary # noqa no-handler
service:
ansible.builtin.service:
name: postgresql
state: restarted
when:
pg_hba_conf_replicator.changed or
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
wal_keep_size.changed or
ansible_facts.services["postgresql.service"].state != "active"
- name: Create extension pgcrypto for template1 # noqa no-changed-when
become: yes
- name: Create extension pgcrypto for template1
become: true
become_user: postgres
shell: "/usr/bin/psql template1 -c \"create extension if not exists pgcrypto;\""
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 # noqa no-changed-when
become: yes
- name: Check database replication_cron exists
become: true
become_user: postgres
shell: "/usr/bin/psql -Atc \"SELECT count(*) FROM pg_database WHERE datname = 'replication_cron'\""
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: yes
become: true
become_user: postgres
shell: "/usr/bin/psql -c \"CREATE DATABASE replication_cron;\""
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 # noqa no-changed-when
become: yes
- name: Create replication update schema
become: true
become_user: postgres
shell: "/usr/bin/psql replication_cron -c \"CREATE SCHEMA IF NOT EXISTS replication_cron;\""
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 # noqa no-changed-when
become: yes
- name: Create replication update table
become: true
become_user: postgres
shell: "/usr/bin/psql replication_cron -c \"CREATE TABLE IF NOT EXISTS replication_cron.replication_cron (dt timestamp);\""
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 # noqa no-changed-when
become: yes
- name: Create dummy update data
become: true
become_user: postgres
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);\""
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:
@ -135,42 +175,46 @@
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 # noqa no-changed-when
become: yes
- name: Check replication slot exists
become: true
become_user: postgres
shell: "/usr/bin/psql -Atc \"select count(*) from pg_replication_slots where slot_name='pgstandby1'\""
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: yes
become: true
become_user: postgres
shell: "/usr/bin/psql -Atc \"SELECT pg_create_physical_replication_slot('pgstandby1');\""
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"
copy:
src: '{{ item }}'
dest: '/tmp/{{ item }}'
mode: '0444'
ansible.builtin.copy:
src: "{{ item }}"
dest: "/tmp/{{ item }}"
mode: "0444"
owner: postgres
group: postgres
loop:
- testdb.sql
- name: "Ensure test DB"
become: yes
become: true
become_user: postgres
community.postgresql.postgresql_db:
name: dummytestdb
- name: "Ensure content for test DB"
become: yes
become: true
become_user: postgres
community.postgresql.postgresql_db:
name: dummytestdb
state: restore
target: /tmp/testdb.sql
when: postgres_ensure_testdb | default(False)

@ -1,5 +1,4 @@
---
- name: Install nfs-common
apt: name=nfs-common state=present update_cache=yes cache_valid_time=900
@ -29,6 +28,11 @@
line: "{{ shared_service_pg_master_ip }} db-backups"
state: present
- name: Wait for nfsd is up and running
wait_for:
host: "{{ shared_service_pg_master_ip }}"
port: 2049
- name: Mount replication NFS volume
ansible.posix.mount:
src: db-master:/postgresql/replication
@ -47,6 +51,11 @@
state: absent
path: /var/lib/postgresql/{{ default_postgres_version }}/main/
- name: Wait for db-master is up and running
wait_for:
host: "{{ shared_service_pg_master_ip }}"
port: 5432
- name: Sync data from db-master # noqa command-instead-of-shell no-changed-when
become: yes
become_user: postgres

@ -43,10 +43,18 @@ dev-pgadmin4-01
[postfix]
dev-mail-01
[postgres]
[postgres01]
dev-postgres-01
dev-postgres-02
#[postgres02]
#dev-postgres02-01
#dev-postgres02-02
[postgres:children]
postgres01
#postgres02
[prometheus]
dev-prometheus-01

Loading…
Cancel
Save