add first working version

Signed-off-by: Jakub Sokołowski <jakub@status.im>
This commit is contained in:
Jakub Sokołowski 2022-11-24 16:40:41 +01:00
parent bab9faf31c
commit 80e572044e
No known key found for this signature in database
GPG Key ID: FE65CD384D5BF7B4
9 changed files with 206 additions and 0 deletions

41
defaults/main.yml Normal file
View File

@ -0,0 +1,41 @@
---
postgres_ha_service_name: 'postgres-ha'
postgres_ha_service_path: '/docker/{{ postgres_ha_service_name }}'
postgres_ha_compose_file: '{{ postgres_ha_service_path }}/docker-compose.yml'
postgres_ha_cont_name: '{{ postgres_ha_service_name }}'
postgres_ha_cont_data_vol: '{{ postgres_ha_service_path }}/data'
postgres_ha_cont_image: 'postgres:15.1-alpine'
postgres_ha_cont_port: 5432
postgres_ha_cont_uid: 70
postgres_ha_host_uid: '{{ 100000 + hackmd_db_cont_uid | int }}'
postgres_ha_cont_run_size: '512K'
postgres_ha_cont_tmp_size: '256K'
# Admin Auth
postgres_ha_admin_user: 'postgres'
postgres_ha_admin_pass: 'changeMeIfYouCare'
# Replication Auth
postgres_ha_replica_user: 'replicator'
postgres_ha_replica_pass: 'changeMeIfYouCare'
postgres_ha_replica_slot: 'main'
#postgres_ha_replica_host: 'db-master.example.org'
#postgres_ha_replica_port: 5432
#postgres_ha_replica_allowed_addresses: ['10.0.0.0/8']
# Mandatory Configuration
#postgres_ha_is_master: true
# Optional Configuration
postgres_ha_db_name: 'postgres'
# Additional Databases
postgres_ha_databases: []
# - name: 'dbtest'
# user: 'dbuser'
# pass: 'dbpass'
# general container management
compose_recreate: 'smart'
compose_state: 'present'
compose_restart: false

19
tasks/config.yml Normal file
View File

@ -0,0 +1,19 @@
---
- name: 'Create service and container folders'
file:
dest: '{{ item }}'
state: 'directory'
owner: 'dockremap'
group: 'docker'
mode: 0775
with_items:
- '{{ postgres_ha_service_path }}'
- '{{ postgres_ha_cont_data_vol }}'
- name: 'Create compose file'
template:
src: 'docker-compose.yml.j2'
dest: '{{ postgres_ha_compose_file }}'
owner: 'dockremap'
group: 'docker'
mode: 0644

25
tasks/databases.yml Normal file
View File

@ -0,0 +1,25 @@
---
- name: 'Create user: {{ db.get("user", db.name) }}'
command: |
docker exec {{ postgres_ha_cont_name }}
psql
--username={{ postgres_ha_admin_user }}
--port={{ postgres_ha_cont_port }}
--command
"DO $$
BEGIN
CREATE USER \"{{ db.get("user", db.name) }}\" PASSWORD '{{ db.pass | mandatory }}';
EXCEPTION WHEN DUPLICATE_OBJECT THEN
RAISE NOTICE 'not creating role {{ db.get("user", db.name) }} -- it already exists';
END
$$;"
- name: 'Create database: {{ db.name | mandatory }}'
shell: |
echo "SELECT
'CREATE DATABASE \"{{ db.name }}\" WITH OWNER \"{{ db.get("user", db.name) }}\";'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '{{ db.name }}')\\\gexec" |
docker exec -i {{ postgres_ha_cont_name }} \
psql
--username={{ postgres_ha_admin_user }}
--port={{ postgres_ha_cont_port }}

17
tasks/hba.yml Normal file
View File

@ -0,0 +1,17 @@
---
- name: 'Allow VPN connections in HBA config'
register: postgres_ha_hba
blockinfile:
path: '{{ postgres_ha_cont_data_vol }}/pgdata/pg_hba.conf'
marker: '# {mark} ANSIBLE MANAGED REPLICATORS'
block: |
{% for addr in postgres_ha_replica_allowed_addresses %}
host replication replicator {{ addr }} md5
{% endfor %}
- name: 'Restart database container'
when: postgres_ha_hba.changed
args:
chdir: '{{ postgres_ha_service_path }}'
command: |
docker-compose restart db

22
tasks/main.yml Normal file
View File

@ -0,0 +1,22 @@
---
- import_tasks: config.yml
- import_tasks: start.yml
when: postgres_ha_is_master
- import_tasks: hba.yml
when: postgres_ha_is_master
- import_tasks: users.yml
when: postgres_ha_is_master
- import_tasks: replica.yml
when: not postgres_ha_is_master
- import_tasks: start.yml
when: not postgres_ha_is_master
- include_tasks: databases.yml
with_items: '{{ postgres_ha_databases }}'
loop_control:
loop_var: db

25
tasks/replica.yml Normal file
View File

@ -0,0 +1,25 @@
---
- name: 'Check if replica DB config exists'
stat:
path: '{{ postgres_ha_cont_data_vol }}/pgdata/postgresql.auto.conf'
register: postgres_ha_auto_conf
- name: 'Initialize DB with base backup'
when: not postgres_ha_auto_conf.stat.exists
args:
chdir: '{{ postgres_ha_service_path }}'
command: |
docker-compose run --rm
--env=PGPASSWORD={{ postgres_ha_replica_pass }}
--name {{ postgres_ha_service_name }}-backup
-- db
pg_basebackup
--host={{ postgres_ha_replica_host }}
--port={{ postgres_ha_replica_port }}
--username={{ postgres_ha_replica_user }}
--slot={{ postgres_ha_replica_slot }}
--verbose
--create-slot
--pgdata=/var/lib/postgresql/data/pgdata
--write-recovery-conf
--checkpoint=fast

8
tasks/start.yml Normal file
View File

@ -0,0 +1,8 @@
---
- name: 'Create database container'
docker_compose:
project_src: '{{ postgres_ha_service_path }}'
state: '{{ compose_state }}'
restarted: '{{ compose_restart }}'
recreate: '{{ compose_recreate }}'
pull: true

16
tasks/users.yml Normal file
View File

@ -0,0 +1,16 @@
---
- name: 'Create user replication user'
command: |
docker exec {{ postgres_ha_cont_name }}
psql
--username={{ postgres_ha_admin_user }}
--port={{ postgres_ha_cont_port }}
--command
"DO $$
BEGIN
CREATE ROLE {{ postgres_ha_replica_user }}
WITH REPLICATION LOGIN ENCRYPTED PASSWORD '{{ postgres_ha_replica_pass }}';
EXCEPTION WHEN DUPLICATE_OBJECT THEN
RAISE NOTICE 'not creating role {{ postgres_ha_replica_user }} -- it already exists';
END
$$;"

View File

@ -0,0 +1,33 @@
---
version: '3.7'
services:
db:
container_name: '{{ postgres_ha_cont_name }}'
image: '{{ postgres_ha_cont_image }}'
restart: always
environment:
POSTGRES_DB: '{{ postgres_ha_db_name | mandatory }}'
POSTGRES_USER: '{{ postgres_ha_admin_user }}'
POSTGRES_PASSWORD: '{{ postgres_ha_admin_pass }}'
{% if not postgres_ha_is_master %}
PGPASSWORD: '{{ postgres_ha_replica_pass }}'
{% endif %}
# This fixes chmod errors on DB startup due to volume + userns-remap
PGDATA: '/var/lib/postgresql/data/pgdata'
ports:
- '{{ postgres_ha_cont_port }}:{{ postgres_ha_cont_port }}'
tmpfs:
- '/run/postgresql:size={{ postgres_ha_cont_run_size }}'
- '/tmp:size={{ postgres_ha_cont_tmp_size }}'
volumes:
- '{{ postgres_ha_cont_data_vol }}:/var/lib/postgresql/data'
command: |
-p {{ postgres_ha_cont_port }}
healthcheck:
interval: 30s
retries: 5
test: [
'CMD', 'pg_isready',
'-p', '{{ postgres_ha_cont_port }}',
'-U', '{{ postgres_ha_admin_user }}'
]