Customizing a Playbook
The cluster deployed by a playbook may host high-availability nodes that reside in a single zone or in multiple zones; you can also customize a playbook with other configuration options.
Configuring a Single-Zone HA Playbook File
The playbook in the following example deploys a single-zone HA cluster using HAProxy; you can customize this deployment with the code samples that follow this section:
- hosts: all
collections:
- pgedge.platform
roles:
- init_server
- hosts: pgedge
collections:
- pgedge.platform
roles:
- install_repos
- install_pgedge
- setup_postgres
- install_etcd
- install_patroni
- setup_etcd
- setup_patroni
- hosts: haproxy
collections:
- pgedge.platform
roles:
- setup_haproxy
- hosts: pgedge
collections:
- pgedge.platform
roles:
- setup_pgedge
This configuration deploys the following components:
- Patroni manages the Postgres cluster in zone 1.
- An etcd cluster provides distributed consensus across the three nodes.
- HAProxy routes new connections to the current Patroni primary.
- Automatic failover activates when the primary becomes unavailable.
Configuring Multi-Zone Playbooks
Cluster designs that use multiple node groups require a playbook that targets
all hosts at the top of the playbook. This ensures Ansible populates
host variables for every server in the inventory before role-specific plays
begin. Some roles require variables for hosts outside their own group; for
example, a pgedge node needs zone information from nodes in the backup
group.
The following pattern satisfies this requirement without running init_server
twice:
# Populate variables for all hosts first
- hosts: all
roles: []
# Then run roles on specific groups
- hosts: pgedge
collections:
- pgedge.platform
roles:
- init_server
- install_repos
# ...
Alternatively, run init_server against all as the first play, as shown
in the Ultra-HA sample playbook.
Execution Strategy
Every play that applies the collection's roles must use Ansible's default
linear strategy, over all of the play's hosts at once. Do not set
strategy: free, in a play or in ansible.cfg, and do not set serial on a
play.
free strategy or serial plays may deploy an inoperable cluster
These roles coordinate the hosts of a play with each other, and depend on every host finishing a task before any host starts the next. Hosts read facts and task results from each other throughout a deployment, and act on them in a fixed order.
The free strategy lets each host run ahead of the others, causing race
conditions that violate these assumptions. serial runs a play over a few
hosts at a time rather than all of the play's hosts at once, so each batch
sees only its own hosts, and steps meant for the whole cluster act on part
of it.
Either can leave the cluster in an inconsistent state. Some steps may never complete, or may deploy partially in ways that pass health checks but are otherwise invalid.
Check mode (--check) is not supported. The roles avoid failing under it where
they can, but a check-mode run does not predict what a real run would change:
many steps act on what an earlier step installed, wrote or started, and in check
mode that earlier step did nothing.
Customizing the Configuration
The following examples demonstrate some common configuration overrides you may want to incorporate into this playbook.
Custom Database Configuration
The following inventory creates multiple databases with custom user accounts:
pgedge:
vars:
db_names:
- app_db
- reporting_db
db_user: appuser
db_password: "{{ vault_db_password }}"
pgedge_user: replication
pgedge_password: "{{ vault_repl_password }}"
Custom Port Configuration
The following inventory configures HAProxy to listen on port 5432 while Postgres listens on port 5433, allowing HAProxy to run on the same node as Postgres:
pgedge:
vars:
pg_port: 5433
proxy_port: 5432
Strict Synchronous Replication Configuration
The following inventory enables strict synchronous replication, which prevents writes when no synchronous replicas respond:
pgedge:
vars:
is_ha_cluster: true
synchronous_mode: true
synchronous_mode_strict: true
S3 Backup Configuration
The following inventory configures PgBackRest to use an AWS S3 bucket instead of a dedicated SSH backup server:
pgedge:
vars:
backup_repo_type: s3
backup_repo_path: /pgbackrest
backup_repo_params:
region: us-west-2
endpoint: s3.amazonaws.com
bucket: my-pg-backups
access_key: "{{ vault_aws_access_key }}"
secret_key: "{{ vault_aws_secret_key }}"
full_backup_schedule: "0 2 * * 0"
diff_backup_schedule: "0 2 * * 1-6"
Ansible Vault Integration Configuration
Use Ansible Vault to protect sensitive variables. The following command creates an encrypted variable file:
ansible-vault create group_vars/pgedge/vault.yml
Place sensitive values in the vault file:
vault_db_password: secure_password_123
vault_pgedge_password: replication_password_456
vault_backup_cipher: encryption_key_789
Reference vault variables in the inventory:
pgedge:
vars:
db_password: "{{ vault_db_password }}"
pgedge_password: "{{ vault_pgedge_password }}"
Run the playbook with the vault password:
ansible-playbook -i inventory.yaml playbook.yaml --ask-vault-pass