Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 4 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,21 @@ up: init
up-with-clean-etcd: init
ansible-playbook -i inventory.ini playbook.yml -e "clean_etcd=true"

.PHONY: haproxy
haproxy: init
ansible-playbook -i inventory.ini haproxy.yml

.PHONY: pg-observe
pg-observe: init
ansible-playbook -i inventory.ini pg_observe.yml

.PHONY: prometheus-grafana
prometheus-grafana: init
ansible-playbook -i inventory.ini prometheus_grafana.yml

.PHONY: haproxy.check.master
haproxy.check.master: init
@PGPASSWORD=`grep postgresql_superuser_password group_vars/promoters.yml | awk '{print $$2}'` && \
ANSIBLE_HOST=`grep haproxy1 inventory.ini | awk '{print $$2}' | sed 's/ansible_host=//'` && \
PGPASSWORD=$$PGPASSWORD psql -h $$ANSIBLE_HOST -p 5000 -U postgres -c "SELECT pg_is_in_recovery()" | grep -q 'f' && \
ANSIBLE_HOST='192.168.64.100' && \
PGPASSWORD=$$PGPASSWORD psql -h 192.168.64.100 -p 5000 -U postgres -c "SELECT pg_is_in_recovery()" | grep -q 'f' && \
echo "HAProxy master is OK" || echo "HAProxy master check failed"

.PHONY: haproxy.check.slave
haproxy.check.slave: init
@PGPASSWORD=`grep postgresql_superuser_password group_vars/promoters.yml | awk '{print $$2}'` && \
ANSIBLE_HOST=`grep haproxy1 inventory.ini | awk '{print $$2}' | sed 's/ansible_host=//'` && \
PGPASSWORD=$$PGPASSWORD psql -h $$ANSIBLE_HOST -p 5001 -U postgres -c "SELECT pg_is_in_recovery()" | grep -q 't' && \
PGPASSWORD=$$PGPASSWORD psql -h 192.168.64.100 -p 5001 -U postgres -c "SELECT pg_is_in_recovery()" | grep -q 't' && \
echo "HAProxy slave is OK" || echo "HAProxy slave check failed"

.PHONY: haproxy.check
Expand All @@ -59,7 +50,4 @@ check-metrics: check-metrics.node-exporter check-metrics.postgres-exporter

.PHONY: lint
lint:
ansible-lint playbook.yml
ansible-lint haproxy.yml
ansible-lint pg_observe.yml
ansible-lint prometheus_grafana.yml
find . -name "*.yml" -exec ansible-lint {} \;
76 changes: 44 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
# ansible-patroni
Ansible playbook for deploy PostgreSQL Patroni cluster
Ansible playbook for deploying PostgreSQL Patroni cluster

⚠️ **WARNING: This configuration is for testing/development purposes only. DO NOT use in production without proper security hardening!**

## Overview
This Ansible playbook automates the deployment of a PostgreSQL high-availability cluster using Patroni and etcd. The setup includes a 3-node cluster configuration with automatic failover capabilities and monitoring.
This Ansible playbook automates the deployment of a PostgreSQL high-availability cluster using Patroni and etcd. The setup includes the following components for connection management and high availability:
- `Keepalived` creates a Virtual IP (VIP) for failover.
- `HAProxy` acts as a proxy layer for distributing requests.
- `PgBouncer` operates as a connection pooler.

The connection path:
```
Keepalived VIP -> HAProxy -> PgBouncer -> PostgreSQL
```

## Prerequisites
- Ubuntu/Debian-based system
Expand All @@ -15,31 +23,28 @@ This Ansible playbook automates the deployment of a PostgreSQL high-availability
- PostgreSQL 16
- Patroni
- etcd (for distributed configuration)
- PgBouncer (for connection pooling)
- Keepalived (for VIP)
- HAProxy (for load balancing)
- Python 3 and pip
- Node Exporter (system metrics)
- Postgres Exporter (PostgreSQL metrics)

## Quick Start
1. Clone this repository:
2. Create config files by command `make init`
3. Update inventory.ini with your servers:
2. Create config files with the command `make init`
3. Update `inventory.ini` with your servers:
```ini
[promoters]
patroni1 ansible_host=192.168.64.2 node_id=1
patroni2 ansible_host=192.168.64.3 node_id=2
patroni3 ansible_host=192.168.64.4 node_id=3
```
4. Update ansible.cfg with your user (root by default)
4. Update `ansible.cfg` with your user (root by default).
5. Run the playbooks:
```shell
# Deploy Patroni cluster
make up

# Deploy HAProxy
make haproxy

# Deploy monitoring
make pg-observe
```

## Default Configuration
Expand All @@ -52,9 +57,20 @@ make pg-observe
- HAProxy PostgreSQL (master): 5000
- HAProxy PostgreSQL (replica): 5001
- HAProxy Statistics: 7000
- PgBouncer: 6432
- Node Exporter: 9100
- Postgres Exporter: 9187

### Keepalived Configuration
- VIP: Used for automatic failover between HAProxy instances.
- Configured to determine the `MASTER` node based on its `node_id` in the cluster.

### PgBouncer Configuration
- Connection pooling for PostgreSQL to reduce the overhead of establishing frequent connections.
- Default port: `6432`.
- Authentication method: Userlist file.
- Configurations stored in `/etc/pgbouncer/pgbouncer.ini`.

### PostgreSQL Settings
- Version: 16
- Encoding: UTF8
Expand Down Expand Up @@ -90,27 +106,6 @@ make pg-observe
- User: postgres
- Config Path: /etc/postgres_exporter/postgres_exporter.yaml

## File Structure
```
.
├── ansible.cfg # Ansible configuration
├── inventory.ini # Server inventory
├── playbook.yml # Main playbook
├── haproxy.yml # HAProxy playbook
├── pg_observe.yml # Monitoring playbook
└── group_vars/
│ └── promoters.yml # Variables and settings
└── templates/
│ ├── etcd.conf.yml.j2 # etcd configuration
│ ├── patroni.yml.j2 # Patroni configuration
│ ├── haproxy.cfg.j2 # HAProxy configuration
│ ├── postgres_exporter.yaml.j2 # Postgres exporter config
│ ├── etcd.service.j2 # etcd systemd service
│ ├── patroni.service.j2 # Patroni systemd service
│ ├── node_exporter.service.j2 # Node exporter systemd service
│ └── postgres_exporter.service.j2 # Postgres exporter systemd service
```

## Important Security Notes
This deployment includes several configurations that are NOT suitable for production:
- Basic default passwords
Expand All @@ -123,9 +118,11 @@ This deployment includes several configurations that are NOT suitable for produc
## Logging
- Patroni logs: /var/log/patroni/patroni.log
- etcd logs: /var/log/etcd.log
- PgBouncer logs: /var/log/pgbouncer/pgbouncer.log
- Log rotation is configured for Patroni logs (7 days retention)
- Node Exporter logs: journalctl -u node_exporter
- Postgres Exporter logs: journalctl -u postgres_exporter
- Keepalived logs: journalctl -u keepalived

## Service Management
``` bash
Expand All @@ -139,6 +136,21 @@ systemctl status etcd
systemctl start etcd
systemctl stop etcd

# HAProxy service
systemctl status haproxy
systemctl start haproxy
systemctl stop haproxy

# PgBouncer service
systemctl status pgbouncer
systemctl start pgbouncer
systemctl stop pgbouncer

# Keepalived service
systemctl status keepalived
systemctl start keepalived
systemctl stop keepalived

# Monitoring services
systemctl status node_exporter
systemctl status postgres_exporter
Expand Down
14 changes: 13 additions & 1 deletion group_vars/promoters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ patroni_retry_timeout: 10
patroni_max_lag: 1048576
patroni_use_pg_rewind: true
patroni_use_slots: true
patroni_config: "/etc/patroni.yml"

# etcd settings
etcd_client_port: 2379

# PostgreSQL settigns
pg_version: 16
data_dir: "/var/lib/postgresql/{{ pg_version }}/main"
postgresql_version: 16
postgresql_encoding: UTF8
postgresql_port: 5432
Expand All @@ -47,7 +50,16 @@ postgresql_custom_parameters:
wal_keep_segments: 32

# Additional pg_hba.conf rules (optional)
#postgresql_additional_pg_hba:
# postgresql_additional_pg_hba:

# PgBouncer params
pgbouncer_listen_port: 6432

# HAProxy params
haproxy_config: "/etc/haproxy/haproxy.cfg"

# Cluster variables
cluster_vip_1: "192.168.64.100"

# Prometheus settings
prometheus_retention: "30d"
Expand Down
35 changes: 0 additions & 35 deletions haproxy.yml

This file was deleted.

3 changes: 0 additions & 3 deletions inventory.ini.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,5 @@ patroni1 ansible_host=192.168.64.2 node_id=1
patroni2 ansible_host=192.168.64.3 node_id=2
patroni3 ansible_host=192.168.64.4 node_id=3

[haproxy]
haproxy1 ansible_host=192.168.64.5

[prometheus_grafana]
prometheus_grafana1 ansible_host=192.168.64.7
136 changes: 0 additions & 136 deletions pg_observe.yml

This file was deleted.

Loading