Repository: vitabaks/autobase
Pull request #906: Add arm64 support
Author: login: pat-s
Labels: name: new feature
description: New functionality
name: automation
description: Automation functionality using Ansible
Created: 2025-03-04T22:50:36Z | Merged: 2025-03-16T18:10:32Z

fixes https://github.com/vitabaks/autobase/discussions/866

I had to comment the install of the postgresql `debuginfo` packages as these are not avail for aarch64. Not sure if these are essential, I think they are rather optional?

I've successfully deployed an arm64-only cluster on Alma9 with these changes.

### Additionally

Fixed the issue of Consul deployment for cloud providers.


Diff:
diff --git a/automation/consul.yml b/automation/consul.yml
index 645a9baef3..f0eec63f8e 100644
--- a/automation/consul.yml
+++ b/automation/consul.yml
@@ -128,6 +128,14 @@
         consul_dnsmasq_servers: "{{ consul_dnsmasq_servers | reject('equalto', '127.0.0.1') | list }}"
       when: dcs_type == "consul" and consul_dnsmasq_enable | bool and ('127.0.0.1' in (consul_dnsmasq_servers | default([])))
 
+    # Setting variables for Consul during cloud deployment
+    - name: Redefine the consul_node_role and consul_bootstrap_expect variables
+      ansible.builtin.set_fact:
+        consul_node_role: "{{ 'server' if not dcs_exists else 'client' }}"
+        consul_bootstrap_expect: "{{ not dcs_exists }}"
+        consul_datacenter: "{{ server_location | default('dc1') }}"
+      when: cloud_provider | default('') | length > 0
+
   roles:
     - role: ansible-role-firewall
       vars:
diff --git a/automation/molecule/default/converge.yml b/automation/molecule/default/converge.yml
index 576230c604..b3115cd7f4 100644
--- a/automation/molecule/default/converge.yml
+++ b/automation/molecule/default/converge.yml
@@ -69,10 +69,9 @@
         enable_pg_stat_kcache: true
         enable_pg_wait_sampling: true
         enable_pg_partman: true
-        # enable_citus: true  # TODO Postgres 17
+        enable_citus: "{{ 'false' if ansible_distribution_release == 'noble' else 'true' }}" # no packages for Ubuntu 24.04 (TODO)
         enable_paradedb: "{{ 'false' if ansible_distribution_release == 'bullseye' else 'true' }}" # pg_search and pg_analytics (no packages for debian 11)
         enable_pgvectorscale: "{{ 'true' if ansible_distribution_release in ['bookworm', 'jammy', 'noble'] else 'false' }}" # only deb packages are available
-        pgvectorscale_version: "0.5.1" # TODO (v0.6.0 does not contain packages)
         # create extension
         postgresql_schemas:
           - { schema: "paradedb", db: "postgres", owner: "postgres" } # pg_search must be installed in the paradedb schema.
diff --git a/automation/molecule/tests/variables/asserts/vip_manager_package_repo.yml b/automation/molecule/tests/variables/asserts/vip_manager_package_repo.yml
index 749a687793..cd1cf57616 100644
--- a/automation/molecule/tests/variables/asserts/vip_manager_package_repo.yml
+++ b/automation/molecule/tests/variables/asserts/vip_manager_package_repo.yml
@@ -7,7 +7,16 @@
 - name: Molecule.tests.variables.asserts.vip_manager_package_repo| Common | Setting vip_manager_version
   run_once: true
   ansible.builtin.set_fact:
-    vip_manager_version: "1.0.0"
+    vip_manager_version: "3.0.0"
+
+- name: Molecule.tests.variables.asserts.vip_manager_package_repo| Common | Setting vip_manager_architecture_map
+  ansible.builtin.set_fact:
+    vip_manager_architecture_map:
+      amd64: x86_64
+      x86_64: x86_64
+      aarch64: arm64
+      arm64: arm64
+  when: vip_manager_architecture_map is not defined
 
 # ===============================================
 # 💾 Start Debian-specific operations and tests
@@ -25,7 +34,7 @@
 - name: Molecule.tests.variables.asserts.vip_manager_package_repo | Debian | Define origin_vip_manager_package_repo
   run_once: true
   ansible.builtin.set_fact: # yamllint disable rule:line-length
-    origin_vip_manager_package_repo: "https://github.com/cybertec-postgresql/vip-manager/releases/download/v{{ vip_manager_version }}/vip-manager_{{ vip_manager_version }}_Linux_x86_64.deb"
+    origin_vip_manager_package_repo: "https://github.com/cybertec-postgresql/vip-manager/releases/download/v{{ vip_manager_version }}/vip-manager_{{ vip_manager_version }}_Linux_{{ vip_manager_architecture_map[ansible_architecture]}}.deb"
 
 # 🖨️ Debug the vip_manager_package_repo for Debian
 # This task prints the actual URL for the VIP Manager package for Debian OS
@@ -62,7 +71,7 @@
 - name: Molecule.tests.variables.asserts.vip_manager_package_repo | RedHat | Define origin_vip_manager_package_repo
   run_once: true
   ansible.builtin.set_fact: # yamllint disable rule:line-length
-    origin_vip_manager_package_repo: "https://github.com/cybertec-postgresql/vip-manager/releases/download/v{{ vip_manager_version }}/vip-manager_{{ vip_manager_version }}_Linux_x86_64.rpm"
+    origin_vip_manager_package_repo: "https://github.com/cybertec-postgresql/vip-manager/releases/download/v{{ vip_manager_version }}/vip-manager_{{ vip_manager_version }}_Linux_{{ vip_manager_architecture_map[ansible_architecture]}}.rpm"
 
 # 🖨️ Debug the vip_manager_package_repo for RedHat
 # This task prints the actual URL for the VIP Manager package for RedHat OS
diff --git a/automation/roles/add-repository/tasks/extensions.yml b/automation/roles/add-repository/tasks/extensions.yml
index 378d5b0aaa..f1edc3b47e 100644
--- a/automation/roles/add-repository/tasks/extensions.yml
+++ b/automation/roles/add-repository/tasks/extensions.yml
@@ -8,7 +8,7 @@
       ansible.builtin.deb822_repository:
         name: "timescaledb"
         types: [deb]
-        uris: "https://packagecloud.io/timescale/timescaledb/{{ ansible_distribution | lower }}"
+        uris: "https://packagecloud.io/timescale/timescaledb/{{ ansible_distribution | lower }}" # amd64 and arm64 are supported
         signed_by: "https://packagecloud.io/timescale/timescaledb/gpgkey"
         suites: "{{ ansible_distribution_release }}"
         components: [main]
@@ -21,10 +21,10 @@
       ansible.builtin.yum_repository:
         name: "timescaledb"
         description: "TimescaleDB Repository"
-        baseurl: "https://packagecloud.io/timescale/timescaledb/el/{{ ansible_distribution_major_version }}/x86_64"
+        baseurl: "https://packagecloud.io/timescale/timescaledb/el/{{ ansible_distribution_major_version }}/x86_64" # no arm64 support
         gpgkey: "https://packagecloud.io/timescale/timescaledb/gpgkey"
         gpgcheck: "no"
-      when: ansible_os_family == "RedHat"
+      when: ansible_os_family == "RedHat" and ansible_architecture in ["x86_64", "amd64"]
   environment: "{{ proxy_env | default({}) }}"
   when: (enable_timescale | default(false) | bool) or (enable_timescaledb | default(false) | bool)
   tags: add_repo, timescaledb, timescale
@@ -36,13 +36,13 @@
       ansible.builtin.deb822_repository:
         name: "citusdata"
         types: [deb]
-        uris: "https://repos.citusdata.com/community/{{ ansible_distribution | lower }}/"
+        uris: "https://repos.citusdata.com/community/{{ ansible_distribution | lower }}/" # no arm64 support (TODO)
         suites: "{{ ansible_distribution_release }}"
         components: [main]
         signed_by: "https://repos.citusdata.com/community/gpgkey"
         state: present
         enabled: true
-      when: ansible_os_family == "Debian"
+      when: ansible_os_family == "Debian" and ansible_architecture in ["x86_64", "amd64"]
 
     # RedHat based
     # TODO: Tests have shown that distributions such as Rocky Linux, AlmaLinux, Oracle Linux, and CentOS Stream are not yet supported.
diff --git a/automation/roles/add-repository/tasks/main.yml b/automation/roles/add-repository/tasks/main.yml
index 850bf18e52..ade841fc24 100644
--- a/automation/roles/add-repository/tasks/main.yml
+++ b/automation/roles/add-repository/tasks/main.yml
@@ -78,15 +78,15 @@
         - name: Enable PowerTools repository
           ansible.builtin.command: dnf config-manager --set-enabled "[Pp]ower[Tt]ools"
           when:
-            - ansible_distribution_major_version is version('8', '==')
+            - ansible_distribution_major_version is version("8", "==")
             - ansible_distribution != "OracleLinux"
-            - ansible_distribution != 'RedHat'
+            - ansible_distribution != "RedHat"
 
         # CodeReady Linux Builder (crb) repository
         - name: Enable CodeReady Linux Builder (crb) repository
           ansible.builtin.command: dnf config-manager --set-enabled crb
           when:
-            - ansible_distribution_major_version is version('9', '>=')
+            - ansible_distribution_major_version is version("9", ">=")
             - ansible_distribution != "OracleLinux"
 
         # CodeReady Builder repository for OracleLinux
@@ -94,7 +94,7 @@
           ansible.builtin.command: dnf config-manager --enable ol{{ ansible_distribution_major_version }}_codeready_builder
           when:
             - ansible_distribution == "OracleLinux"
-            - ansible_distribution_major_version is version('8', '>=')
+            - ansible_distribution_major_version is version("8", ">=")
       vars:
         pg_devel_package: "postgresql{{ postgresql_version | string | replace('.', '') }}-devel"
       when:
@@ -102,8 +102,8 @@
 
     # Install PostgreSQL Repository
     - name: Get pgdg-redhat-repo-latest.noarch.rpm
-      ansible.builtin.get_url:
-        url: "https://download.postgresql.org/pub/repos/yum/reporpms/EL-{{ ansible_distribution_major_version }}-x86_64/pgdg-redhat-repo-latest.noarch.rpm"
+      ansible.builtin.get_url: # yamllint disable rule:line-length
+        url: "https://download.postgresql.org/pub/repos/yum/reporpms/EL-{{ ansible_distribution_major_version }}-{{ pgdg_architecture_map[ansible_architecture] }}/pgdg-redhat-repo-latest.noarch.rpm"
         dest: /tmp/
         timeout: 30
         validate_certs: false
@@ -131,6 +131,7 @@
             sed -i '/\[pgdg[0-9]*-debuginfo\]/,/^$/ s/gpgcheck=1/gpgcheck=0/' {{ pgdg_redhat_repo_path }}
           vars:
             pgdg_redhat_repo_path: "/etc/yum.repos.d/pgdg-redhat-all.repo"
+          when: ansible_architecture in ["x86_64", "amd64"]
 
         # Check if the repository entry exists in the file
         - name: Check if pgdg{{ postgresql_version }}-debuginfo exists in repo file
@@ -146,10 +147,10 @@
 
         # If the entry does not exist, try to add the repository
         - name: Add pgdg{{ postgresql_version }}-debuginfo repo if not present
-          ansible.builtin.yum_repository:
+          ansible.builtin.yum_repository: # yamllint disable rule:line-length
             name: "pgdg{{ postgresql_version }}-debuginfo"
-            description: "PostgreSQL {{ postgresql_version }} for RHEL {{ ansible_distribution_major_version }} - x86_64 - Debuginfo"
-            baseurl: "https://download.postgresql.org/pub/repos/yum/debug/{{ postgresql_version }}/redhat/rhel-{{ ansible_distribution_major_version }}-x86_64/"
+            description: "PostgreSQL {{ postgresql_version }} for RHEL {{ ansible_distribution_major_version }} - {{ pgdg_architecture_map[ansible_architecture] }} - Debuginfo"
+            baseurl: "https://download.postgresql.org/pub/repos/yum/debug/{{ postgresql_version }}/redhat/rhel-{{ ansible_distribution_major_version }}-{{ pgdg_architecture_map[ansible_architecture] }}/"
             gpgcheck: false
             enabled: true
           when: repo_check.found == 0
diff --git a/automation/roles/cloud-resources/tasks/hetzner.yml b/automation/roles/cloud-resources/tasks/hetzner.yml
index 3eba27d3d3..6b8ad792aa 100644
--- a/automation/roles/cloud-resources/tasks/hetzner.yml
+++ b/automation/roles/cloud-resources/tasks/hetzner.yml
@@ -655,6 +655,7 @@
       until: hetzner_load_balancer is success
       delay: 5
       retries: 3
+      when: cloud_load_balancer | bool
   when: state == 'present'
 
 - name: Wait for host to be available via SSH
diff --git a/automation/roles/cloud-resources/tasks/inventory.yml b/automation/roles/cloud-resources/tasks/inventory.yml
index f18a78f3c6..c6301c104a 100644
--- a/automation/roles/cloud-resources/tasks/inventory.yml
+++ b/automation/roles/cloud-resources/tasks/inventory.yml
@@ -1,5 +1,5 @@
 ---
-- name: "Set variable: ssh_private_key_file"
+- name: "Inventory | Set variable: ssh_private_key_file"
   ansible.builtin.set_fact:
     ssh_private_key_file: "~{{ lookup('env', 'USER') }}/.ssh/{{ tmp_ssh_key_name }}"
   when:
@@ -64,9 +64,6 @@
     group: consul_instances
     ansible_ssh_host: "{{ item.public_ip }}"
     ansible_ssh_private_key_file: "{{ ssh_private_key_file | default(None) }}"
-    consul_node_role: "{{ not dcs_exists | ternary('server', 'client') }}"
-    consul_bootstrap_expect: true
-    consul_datacenter: "{{ server_location }}"
   loop: "{{ ip_addresses }}"
   loop_control:
     label: "{{ item.public_ip }}"
diff --git a/automation/roles/confd/defaults/main.yml b/automation/roles/confd/defaults/main.yml
new file mode 100644
index 0000000000..8ae0e3bf10
--- /dev/null
+++ b/automation/roles/confd/defaults/main.yml
@@ -0,0 +1,7 @@
+---
+confd_architecture_map:
+  amd64: amd64
+  x86_64: amd64
+  aarch64: arm64
+  arm64: arm64
+  64-bit: amd64
diff --git a/automation/roles/consul/tasks/main.yml b/automation/roles/consul/tasks/main.yml
index daf9370ef8..d20b428638 100644
--- a/automation/roles/consul/tasks/main.yml
+++ b/automation/roles/consul/tasks/main.yml
@@ -27,6 +27,8 @@
       ansible.builtin.pip:
         name: netaddr
         extra_args: --user
+      environment:
+        PIP_BREAK_SYSTEM_PACKAGES: "1"
       delegate_to: 127.0.0.1
       become: false
       vars:
@@ -37,6 +39,8 @@
     - name: Install netaddr dependency on controlling host (virtualenv)
       ansible.builtin.pip:
         name: netaddr
+      environment:
+        PIP_BREAK_SYSTEM_PACKAGES: "1"
       delegate_to: 127.0.0.1
       become: false
       vars:
diff --git a/automation/roles/etcd/defaults/main.yml b/automation/roles/etcd/defaults/main.yml
new file mode 100644
index 0000000000..a873d0ef76
--- /dev/null
+++ b/automation/roles/etcd/defaults/main.yml
@@ -0,0 +1,10 @@
+---
+etcd_architecture_map:
+  amd64: amd64
+  x86_64: amd64
+  armv6l: armhfv6
+  armv7l: armhfv6
+  aarch64: arm64
+  arm64: arm64
+  32-bit: "386"
+  64-bit: amd64
diff --git a/automation/roles/packages/defaults/main.yml b/automation/roles/packages/defaults/main.yml
new file mode 100644
index 0000000000..8e5e255ed4
--- /dev/null
+++ b/automation/roles/packages/defaults/main.yml
@@ -0,0 +1,24 @@
+---
+pgdg_architecture_map:
+  amd64: x86_64
+  x86_64: x86_64
+  aarch64: aarch64
+
+# Extension Auto-Setup:
+pgvectorscale_architecture_map:
+  x86_64: amd64
+  amd64: amd64
+  aarch64: arm64
+  arm64: arm64
+
+paradedb_architecture_map_dep:
+  x86_64: amd64
+  amd64: amd64
+  aarch64: arm64
+  arm64: arm64
+
+paradedb_architecture_map_rpm:
+  x86_64: x86_64
+  amd64: x86_64
+  aarch64: aarch64
+  arm64: aarch64
diff --git a/automation/roles/packages/tasks/extensions.yml b/automation/roles/packages/tasks/extensions.yml
index 1f7cde9a3a..600eadb115 100644
--- a/automation/roles/packages/tasks/extensions.yml
+++ b/automation/roles/packages/tasks/extensions.yml
@@ -29,8 +29,10 @@
   loop: "{{ citus_package }}"
   vars:
     citus_package: >-
-      [{% if ansible_os_family == 'Debian' and pg_version | default(postgresql_version) | int >= 14 %}
-      "postgresql-{{ pg_version | default(postgresql_version) }}-citus-{{ citus_version | default('12.1') }}"
+      [{% if ansible_os_family == 'Debian' and pg_version | default(postgresql_version) | int >= 15 %}
+      "postgresql-{{ pg_version | default(postgresql_version) }}-citus-{{ citus_version | default('13.0') }}"
+      {% elif ansible_os_family == 'Debian' and pg_version | default(postgresql_version) | int == 14 %}
+      "postgresql-{{ pg_version | default(postgresql_version) }}-citus-12.1"
       {% elif ansible_os_family == 'Debian' and pg_version | default(postgresql_version) | int == 13 %}
       "postgresql-{{ pg_version | default(postgresql_version) }}-citus-11.3"
       {% elif ansible_os_family == 'Debian' and pg_version | default(postgresql_version) | int == 12 %}
@@ -48,6 +50,7 @@
     - enable_citus | default(false) | bool
     - (ansible_os_family == 'Debian' and pg_version | default(postgresql_version) | int >= 11) or
       (ansible_os_family == 'RedHat' and pg_version | default(postgresql_version) | int >= 12)
+    - ansible_architecture in ["x86_64", "amd64"] # no arm64 support
   tags: citus
 
 # pg_repack (if 'enable_pg_repack' is 'true')
@@ -278,8 +281,8 @@
       retries: 3
   vars:
     pgvectorscale_repo: "https://github.com/timescale/pgvectorscale/releases/download/{{ pgvectorscale_version }}"
-    pgvectorscale_archive: "pgvectorscale-{{ pgvectorscale_version }}-pg{{ pg_version | default(postgresql_version) }}-amd64.zip" # yamllint disable rule:line-length
-    pgvectorscale_package: "pgvectorscale-postgresql-{{ pg_version | default(postgresql_version) }}_{{ pgvectorscale_version }}-Linux_amd64.deb" # yamllint disable rule:line-length
+    pgvectorscale_archive: "pgvectorscale-{{ pgvectorscale_version }}-pg{{ pg_version | default(postgresql_version) }}-{{ pgvectorscale_architecture_map[ansible_architecture] }}.zip" # yamllint disable rule:line-length
+    pgvectorscale_package: "pgvectorscale-postgresql-{{ pg_version | default(postgresql_version) }}_{{ pgvectorscale_version }}-Linux_{{ pgvectorscale_architecture_map[ansible_architecture] }}.deb" # yamllint disable rule:line-length
   when:
     - enable_pgvectorscale | default(false) | bool
     - ansible_os_family == "Debian"
@@ -310,7 +313,7 @@
           retries: 3
           vars:
             pg_search_repo: "https://github.com/paradedb/paradedb/releases/download/v{{ pg_search_version }}/"
-            pg_search_package: "{{ pg_search_repo }}/postgresql-{{ pg_version | default(postgresql_version) }}-pg-search_{{ pg_search_version }}-1PARADEDB-{{ ansible_distribution_release }}_amd64.deb" # yamllint disable rule:line-length
+            pg_search_package: "{{ pg_search_repo }}/postgresql-{{ pg_version | default(postgresql_version) }}-pg-search_{{ pg_search_version }}-1PARADEDB-{{ ansible_distribution_release }}_{{ paradedb_architecture_map_dep[ansible_architecture] }}.deb" # yamllint disable rule:line-length
           when:
             - ansible_os_family == "Debian"
             - ansible_distribution_release in ['bookworm', 'jammy', 'noble']
@@ -326,7 +329,7 @@
           retries: 3
           vars:
             pg_search_repo: "https://github.com/paradedb/paradedb/releases/download/v{{ pg_search_version }}/"
-            pg_search_package: "{{ pg_search_repo }}/pg_search_{{ pg_version | default(postgresql_version) }}-{{ pg_search_version }}-1PARADEDB.el{{ ansible_distribution_major_version }}.x86_64.rpm" # yamllint disable rule:line-length
+            pg_search_package: "{{ pg_search_repo }}/pg_search_{{ pg_version | default(postgresql_version) }}-{{ pg_search_version }}-1PARADEDB.el{{ ansible_distribution_major_version }}.{{ paradedb_architecture_map_rpm[ansible_architecture] }}.rpm" # yamllint disable rule:line-length
           when:
             - ansible_os_family == "RedHat"
             - ansible_distribution_major_version in ['8', '9']
@@ -354,7 +357,7 @@
           retries: 3
           vars:
             pg_analytics_repo: "https://github.com/paradedb/pg_analytics/releases/download/v{{ pg_analytics_version }}/"
-            pg_analytics_package: "{{ pg_analytics_repo }}/postgresql-{{ pg_version | default(postgresql_version) }}-pg-analytics_{{ pg_analytics_version }}-1PARADEDB-{{ ansible_distribution_release }}_amd64.deb" # yamllint disable rule:line-length
+            pg_analytics_package: "{{ pg_analytics_repo }}/postgresql-{{ pg_version | default(postgresql_version) }}-pg-analytics_{{ pg_analytics_version }}-1PARADEDB-{{ ansible_distribution_release }}_{{ paradedb_architecture_map_dep[ansible_architecture] }}.deb" # yamllint disable rule:line-length
           when:
             - ansible_os_family == "Debian"
             - ansible_distribution_release in ['bookworm', 'jammy', 'noble']
@@ -370,7 +373,7 @@
           retries: 3
           vars:
             pg_analytics_repo: "https://github.com/paradedb/pg_analytics/releases/download/v{{ pg_analytics_version }}/"
-            pg_analytics_package: "{{ pg_analytics_repo }}/pg_analytics_{{ pg_version | default(postgresql_version) }}-{{ pg_analytics_version }}-1PARADEDB.el{{ ansible_distribution_major_version }}.x86_64.rpm" # yamllint disable rule:line-length
+            pg_analytics_package: "{{ pg_analytics_repo }}/pg_analytics_{{ pg_version | default(postgresql_version) }}-{{ pg_analytics_version }}-1PARADEDB.el{{ ansible_distribution_major_version }}.{{ paradedb_architecture_map_rpm[ansible_architecture] }}.rpm" # yamllint disable rule:line-length
           when:
             - ansible_os_family == "RedHat"
             - ansible_distribution_major_version in ['8', '9']
diff --git a/automation/roles/pgbackrest/tasks/main.yml b/automation/roles/pgbackrest/tasks/main.yml
index 88aaa0369f..190c384499 100644
--- a/automation/roles/pgbackrest/tasks/main.yml
+++ b/automation/roles/pgbackrest/tasks/main.yml
@@ -51,7 +51,7 @@
     # RedHat pgdg repo
     - name: Get pgdg-redhat-repo-latest.noarch.rpm
       ansible.builtin.get_url:
-        url: "https://download.postgresql.org/pub/repos/yum/reporpms/EL-{{ ansible_distribution_major_version }}-x86_64/pgdg-redhat-repo-latest.noarch.rpm"
+        url: "https://download.postgresql.org/pub/repos/yum/reporpms/EL-{{ ansible_distribution_major_version }}-{{ pgdg_architecture_map[ansible_architecture] }}/pgdg-redhat-repo-latest.noarch.rpm" # yamllint disable rule:line-length
         dest: /tmp/
         timeout: 30
         validate_certs: false
@@ -74,34 +74,6 @@
     - pgbackrest_install_from_pgdg_repo|bool
   tags: pgbackrest, pgbackrest_repo, pgbackrest_install
 
-# (workaround for CentOS 8.0/8.1)
-# install libzstd RPM from an archived EPEL 8.1 release
-# The problem will be solved when CentOS 8.2 will be released.
-- block:
-    - name: Get libzstd rpm package from archived EPEL
-      ansible.builtin.get_url:
-        url: https://dl.fedoraproject.org/pub/archive/epel/8.1/Everything/x86_64/Packages/l/libzstd-1.4.4-1.el8.x86_64.rpm
-        dest: /tmp/
-        timeout: 120
-        validate_certs: false
-      register: get_libzstd_result
-
-    - name: Install libzstd
-      ansible.builtin.package:
-        name: /tmp/libzstd-1.4.4-1.el8.x86_64.rpm
-        state: present
-      register: package_status
-      until: package_status is success
-      delay: 5
-      retries: 3
-      when: get_libzstd_result is changed
-  environment: "{{ proxy_env | default({}) }}"
-  when:
-    - ansible_distribution == "CentOS"
-    - ansible_distribution_major_version == '8'
-    - ansible_distribution_version is version('8.1', '<=')
-  tags: pgbackrest, pgbackrest_install
-
 - name: Install pgbackrest
   ansible.builtin.package:
     name: pgbackrest
diff --git a/automation/roles/pre-checks/tasks/extensions.yml b/automation/roles/pre-checks/tasks/extensions.yml
index 96f92f9cb2..64657988fa 100644
--- a/automation/roles/pre-checks/tasks/extensions.yml
+++ b/automation/roles/pre-checks/tasks/extensions.yml
@@ -58,7 +58,7 @@
       {{
         (extensions | default([]))
         + (['timescaledb'] if ((enable_timescale | default(false) | bool) or (enable_timescaledb | default(false) | bool)) else [])
-        + (['citus'] if ((enable_citus | default(false) | bool) and (postgresql_version | int >= 11)) else [])
+        + (['citus'] if (enable_citus | default(false) | bool and postgresql_version | int >= 11 and ansible_architecture in ["x86_64", "amd64"]) else [])
         + (['pg_cron'] if (enable_pg_cron | default(false) | bool) else [])
         + (['pgaudit'] if (enable_pgaudit | default(false) | bool) else [])
         + (['pg_stat_statements'] if (enable_pg_stat_kcache | default(false) | bool) else [])
diff --git a/automation/roles/vip-manager/defaults/main.yml b/automation/roles/vip-manager/defaults/main.yml
new file mode 100644
index 0000000000..7a64b627cf
--- /dev/null
+++ b/automation/roles/vip-manager/defaults/main.yml
@@ -0,0 +1,8 @@
+---
+vip_manager_architecture_map:
+  amd64: x86_64
+  x86_64: x86_64
+  aarch64: arm64
+  arm64: arm64
+  32-bit: "i386"
+  64-bit: x86_64
diff --git a/automation/roles/wal-g/defaults/main.yml b/automation/roles/wal-g/defaults/main.yml
new file mode 100644
index 0000000000..0e3a60580f
--- /dev/null
+++ b/automation/roles/wal-g/defaults/main.yml
@@ -0,0 +1,13 @@
+---
+wal_g_architecture_map:
+  amd64: amd64
+  x86_64: amd64
+  aarch64: aarch64
+  arm64: aarch64
+
+# if 'wal_g_installation_method' is 'src'
+go_architecture_map:
+  amd64: amd64
+  x86_64: amd64
+  aarch64: arm64
+  arm64: arm64
diff --git a/automation/roles/wal-g/tasks/main.yml b/automation/roles/wal-g/tasks/main.yml
index a88a39da1b..af0f00b81f 100644
--- a/automation/roles/wal-g/tasks/main.yml
+++ b/automation/roles/wal-g/tasks/main.yml
@@ -42,7 +42,7 @@
       check_mode: false
       vars:
         wal_g_repo: "https://github.com/wal-g/wal-g/releases/download/v{{ wal_g_version | string | replace('v', '') }}"
-        wal_g_archive: "wal-g-pg-ubuntu-20.04-amd64.tar.gz"
+        wal_g_archive: "wal-g-pg-ubuntu-20.04-{{ wal_g_architecture_map[ansible_architecture] }}.tar.gz"
       environment: "{{ proxy_env | default({}) }}"
 
     # Note: We are using a precompiled binary on Ubuntu 20.04,
@@ -50,7 +50,7 @@
 
     - name: Extract WAL-G into /tmp
       ansible.builtin.unarchive:
-        src: "/tmp/wal-g-pg-ubuntu-20.04-amd64.tar.gz"
+        src: "/tmp/wal-g-pg-ubuntu-20.04-{{ wal_g_architecture_map[ansible_architecture] }}.tar.gz"
         dest: /tmp/
         extra_opts:
           - --no-same-owner
@@ -59,7 +59,7 @@
 
     - name: Copy WAL-G binary file to "{{ wal_g_path.split(' ')[0] }}"
       ansible.builtin.copy:
-        src: "/tmp/wal-g-pg-ubuntu-20.04-amd64"
+        src: "/tmp/wal-g-pg-ubuntu-20.04-{{ wal_g_architecture_map[ansible_architecture] }}"
         dest: "{{ wal_g_path.split(' ')[0] }}"
         mode: u+x,g+x,o+x
         remote_src: true
@@ -126,25 +126,25 @@
       args:
         executable: /bin/bash
       changed_when: false
-      register: wal_g_latest_version
+      register: go_latest_version
 
     - block: # Install latest Go compiler
-        - name: "Download Go v{{ wal_g_latest_version.stdout }}"
+        - name: "Download Go v{{ go_latest_version.stdout }}"
           ansible.builtin.get_url:
-            url: "https://go.dev/dl/go{{ wal_g_latest_version.stdout }}.linux-amd64.tar.gz"
+            url: "https://go.dev/dl/go{{ go_latest_version.stdout }}.linux-{{ go_architecture_map[ansible_architecture] }}.tar.gz"
             dest: /tmp/
             timeout: 60
             validate_certs: false
 
         - name: Install Go
           ansible.builtin.unarchive:
-            src: "/tmp/go{{ wal_g_latest_version.stdout }}.linux-amd64.tar.gz"
+            src: "/tmp/go{{ go_latest_version.stdout }}.linux-{{ go_architecture_map[ansible_architecture] }}.tar.gz"
             dest: /usr/local/
             extra_opts:
               - --no-same-owner
             remote_src: true
       when: go_installed_version.stderr is search("command not found") or
-        go_installed_version.stdout is version(wal_g_latest_version.stdout, '<')
+        go_installed_version.stdout is version(go_latest_version.stdout, '<')
 
     - name: "Download WAL-G v{{ wal_g_version | string | replace('v', '') }} source code"
       ansible.builtin.git:
diff --git a/automation/vars/Debian.yml b/automation/vars/Debian.yml
index a43d5492b4..29a27f0330 100644
--- a/automation/vars/Debian.yml
+++ b/automation/vars/Debian.yml
@@ -1,4 +1,6 @@
 ---
+# yamllint disable rule:line-length
+
 # PostgreSQL variables
 postgresql_cluster_name: "main"
 # You can specify custom data dir path. Example: "/pgdata/{{ postgresql_version }}/main"
@@ -9,7 +11,7 @@ postgresql_data_dir: "\
   /var/lib/postgresql/{{ postgresql_version }}/{{ postgresql_cluster_name }}\
   {% endif %}"
 # Note: When deploying to cloud providers, we create a disk and mount the data directory,
-# along the path defined in the 'pg_data_mount_path' variable (or use '/pgdata' by default).
+# along the path defined in the "pg_data_mount_path" variable (or use "/pgdata" by default).
 
 # You can specify custom WAL dir path. Example: "/pgwal/{{ postgresql_version }}/pg_wal"
 postgresql_wal_dir: "" # if defined, symlink will be created [optional]
@@ -72,8 +74,8 @@ postgresql_packages:
 #  - postgresql-{{ postgresql_version }}-partman
 
 # Extra packages
-etcd_package_repo: "https://github.com/etcd-io/etcd/releases/download/v{{ etcd_version }}/etcd-v{{ etcd_version }}-linux-amd64.tar.gz"
-vip_manager_package_repo: "https://github.com/cybertec-postgresql/vip-manager/releases/download/v{{ vip_manager_version }}/vip-manager_{{ vip_manager_version }}_Linux_x86_64.deb" # yamllint disable rule:line-length
+etcd_package_repo: "https://github.com/etcd-io/etcd/releases/download/v{{ etcd_version }}/etcd-v{{ etcd_version }}-linux-{{ etcd_architecture_map[ansible_architecture] }}.tar.gz"
+vip_manager_package_repo: "https://github.com/cybertec-postgresql/vip-manager/releases/download/v{{ vip_manager_version }}/vip-manager_{{ vip_manager_version }}_Linux_{{ vip_manager_architecture_map[ansible_architecture] }}.deb"
 
 installation_method: "repo" # "repo" (default) or "file"
 
@@ -123,9 +125,9 @@ patroni_pip_package_repo: []
 
 # if with_haproxy_load_balancing: true
 haproxy_installation_method: "deb" # "deb" (default) or "src"
-confd_package_repo: "https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-amd64"
+confd_package_repo: "https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-{{ confd_architecture_map[ansible_architecture] }}"
 
-# if haproxy_installation_method: 'src' (optional)
+# if haproxy_installation_method: "src" (optional)
 haproxy_major: "1.8"
 haproxy_version: "1.8.31" # version to build from source
 lua_src_repo: "https://www.lua.org/ftp/lua-5.3.5.tar.gz" # required for build haproxy
@@ -182,14 +184,15 @@ patroni_pip_package_file: []
 #  - "patroni-3.3.2.tar.gz"  # https://pypi.org/project/patroni/#files
 
 # additional packages
-etcd_package_file: "etcd-v3.5.15-linux-amd64.tar.gz" # https://github.com/etcd-io/etcd/releases
-vip_manager_package_file: "vip-manager_2.6.0_Linux_x86_64.deb" # https://github.com/cybertec-postgresql/vip-manager/releases
-wal_g_package_file: "wal-g-pg-ubuntu20.04-aarch64.tar.gz" # https://github.com/wal-g/wal-g/releases
+etcd_package_file: "etcd-v3.5.17-linux-{{ etcd_architecture_map[ansible_architecture] }}.tar.gz" # https://github.com/etcd-io/etcd/releases
+vip_manager_package_file: "vip-manager_3.0.0_Linux_{{ vip_manager_architecture_map[ansible_architecture] }}.deb" # https://github.com/cybertec-postgresql/vip-manager/releases
+wal_g_package_file: "wal-g-pg-ubuntu-20.04-{{ wal_g_architecture_map[ansible_architecture] }}.tar.gz" # https://github.com/wal-g/wal-g/releases
 
 # if with_haproxy_load_balancing: true
 haproxy_package_file: []
 #  - "haproxy_1.8.25-1~bpo9+1_amd64.deb"
-confd_package_file: "confd-0.16.0-linux-amd64" # https://github.com/kelseyhightower/confd/releases
+
+confd_package_file: "confd-0.16.0-linux-{{ confd_architecture_map[ansible_architecture] }}" # https://github.com/kelseyhightower/confd/releases
 
 # if haproxy_installation_method: 'src' (optional)
 lua_src_file: "lua-5.3.5.tar.gz" # https://www.lua.org/ftp/lua-5.3.5.tar.gz (required for build haproxy)
diff --git a/automation/vars/RedHat.yml b/automation/vars/RedHat.yml
index 3e3963d538..cbe40cde8f 100644
--- a/automation/vars/RedHat.yml
+++ b/automation/vars/RedHat.yml
@@ -1,4 +1,6 @@
 ---
+# yamllint disable rule:line-length
+
 # PostgreSQL variables
 #
 # You can specify custom data dir path. Example: "/pgdata/{{ postgresql_version }}/data"
@@ -9,7 +11,7 @@ postgresql_data_dir: "\
   /var/lib/pgsql/{{ postgresql_version }}/data\
   {% endif %}"
 # Note: When deploying to cloud providers, we create a disk and mount the data directory,
-# along the path defined in the 'pg_data_mount_path' variable (or use '/pgdata' by default).
+# along the path defined in the "pg_data_mount_path" variable (or use "/pgdata" by default).
 
 # You can specify custom WAL dir path. Example: "/pgwal/{{ postgresql_version }}/pg_wal"
 postgresql_wal_dir: "" # if defined, symlink will be created [optional]
@@ -86,7 +88,7 @@ postgresql_packages:
   - postgresql{{ postgresql_version }}-server
   - postgresql{{ postgresql_version }}-contrib
   - postgresql{{ postgresql_version }}-devel
-  - postgresql{{ postgresql_version }}-debuginfo
+# - postgresql{{ postgresql_version }}-debuginfo
 #  - pg_repack_{{ postgresql_version }}
 #  - pg_cron_{{ postgresql_version }}
 #  - pg_stat_kcache_{{ postgresql_version }}
@@ -98,8 +100,8 @@ postgresql_packages:
 #  - pg_partman_{{ postgresql_version }}
 
 # Extra packages
-etcd_package_repo: "https://github.com/etcd-io/etcd/releases/download/v{{ etcd_version }}/etcd-v{{ etcd_version }}-linux-amd64.tar.gz"
-vip_manager_package_repo: "https://github.com/cybertec-postgresql/vip-manager/releases/download/v{{ vip_manager_version }}/vip-manager_{{ vip_manager_version }}_Linux_x86_64.rpm" # yamllint disable rule:line-length
+etcd_package_repo: "https://github.com/etcd-io/etcd/releases/download/v{{ etcd_version }}/etcd-v{{ etcd_version }}-linux-{{ etcd_architecture_map[ansible_architecture] }}.tar.gz"
+vip_manager_package_repo: "https://github.com/cybertec-postgresql/vip-manager/releases/download/v{{ vip_manager_version }}/vip-manager_{{ vip_manager_version }}_Linux_{{ vip_manager_architecture_map[ansible_architecture] }}.rpm"
 
 installation_method: "repo" # "repo" (default) or "file"
 
@@ -149,9 +151,9 @@ patroni_pip_package_repo: []
 
 # if with_haproxy_load_balancing: true
 haproxy_installation_method: "rpm" # "rpm" (default) or "src"
-confd_package_repo: "https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-amd64"
+confd_package_repo: "https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-{{ confd_architecture_map[ansible_architecture] }}"
 
-# if haproxy_installation_method: 'src' (optional)
+# if haproxy_installation_method: "src" (optional)
 haproxy_major: "1.8"
 haproxy_version: "1.8.31" # version to build from source
 lua_src_repo: "https://www.lua.org/ftp/lua-5.3.5.tar.gz" # required for build haproxy
@@ -207,14 +209,15 @@ patroni_pip_package_file: []
 #  - "patroni-3.3.2.tar.gz"  # https://pypi.org/project/patroni/#files
 
 # additional packages
-etcd_package_file: "etcd-v3.5.15-linux-amd64.tar.gz" # https://github.com/etcd-io/etcd/releases
-vip_manager_package_file: "vip-manager-1.0.2-1.x86_64.rpm" # https://github.com/cybertec-postgresql/vip-manager/releases
-wal_g_package_file: "wal-g.linux-amd64.tar.gz" # https://github.com/wal-g/wal-g/releases
+etcd_package_file: "etcd-v3.5.17-linux-{{ etcd_architecture_map[ansible_architecture] }}.tar.gz" # https://github.com/etcd-io/etcd/releases
+vip_manager_package_file: "vip-manager_3.0.0_Linux_{{ vip_manager_architecture_map[ansible_architecture] }}.rpm" # https://github.com/cybertec-postgresql/vip-manager/releases
+wal_g_package_file: "wal-g-pg-ubuntu-20.04-{{ wal_g_architecture_map[ansible_architecture] }}.tar.gz" # https://github.com/wal-g/wal-g/releases
 
 # if with_haproxy_load_balancing: true
 haproxy_package_file: []
 #  - "rh-haproxy18-runtime-3.1-2.el7.x86_64.rpm"
 #  - "rh-haproxy18-haproxy-1.8.31-1.el7.x86_64.rpm"
+
 confd_package_file: "confd-0.16.0-linux-amd64" # https://github.com/kelseyhightower/confd/releases
 
 # if haproxy_installation_method: 'src' (optional)


Reviews:
user: login: vitabaks
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-05T07:08:07Z
user: login: pat-s
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T08:03:18Z
user: login: vitabaks
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-10T09:17:48Z

Review comments:
diff_hunk: @@ -125,45 +124,43 @@
 
     # Enable Debuginfo repository
     - block:
-        - name: Enable PostgreSQL debuginfo repository
-          ansible.builtin.shell: |
-            set -o pipefail;
-            sed -i '/\[pgdg[0-9]*-debuginfo\]/,/^$/ s/enabled=0/enabled=1/' {{ pgdg_redhat_repo_path }}
-            sed -i '/\[pgdg[0-9]*-debuginfo\]/,/^$/ s/gpgcheck=1/gpgcheck=0/' {{ pgdg_redhat_repo_path }}
-          vars:
-            pgdg_redhat_repo_path: "/etc/yum.repos.d/pgdg-redhat-all.repo"
+        # - name: Enable PostgreSQL debuginfo repository
+        #   ansible.builtin.shell: |
+        #     set -o pipefail;
+        #     sed -i '/\[pgdg[0-9]*-debuginfo\]/,/^$/ s/enabled=0/enabled=1/' {{ pgdg_redhat_repo_path }}
+        #     sed -i '/\[pgdg[0-9]*-debuginfo\]/,/^$/ s/gpgcheck=1/gpgcheck=0/' {{ pgdg_redhat_repo_path }}
+        #   vars:
+        #     pgdg_redhat_repo_path: '/etc/yum.repos.d/pgdg-redhat-all.repo'
path: automation/roles/add-repository/tasks/main.yml
user: login: vitabaks
body: I think we could use the condition for ansible_architecture here, instead of disabling the task completely.
created_at: 2025-03-05T07:08:07Z
author_association: MEMBER
diff_hunk: @@ -125,45 +124,43 @@
 
     # Enable Debuginfo repository
     - block:
-        - name: Enable PostgreSQL debuginfo repository
-          ansible.builtin.shell: |
-            set -o pipefail;
-            sed -i '/\[pgdg[0-9]*-debuginfo\]/,/^$/ s/enabled=0/enabled=1/' {{ pgdg_redhat_repo_path }}
-            sed -i '/\[pgdg[0-9]*-debuginfo\]/,/^$/ s/gpgcheck=1/gpgcheck=0/' {{ pgdg_redhat_repo_path }}
-          vars:
-            pgdg_redhat_repo_path: "/etc/yum.repos.d/pgdg-redhat-all.repo"
+        # - name: Enable PostgreSQL debuginfo repository
+        #   ansible.builtin.shell: |
+        #     set -o pipefail;
+        #     sed -i '/\[pgdg[0-9]*-debuginfo\]/,/^$/ s/enabled=0/enabled=1/' {{ pgdg_redhat_repo_path }}
+        #     sed -i '/\[pgdg[0-9]*-debuginfo\]/,/^$/ s/gpgcheck=1/gpgcheck=0/' {{ pgdg_redhat_repo_path }}
+        #   vars:
+        #     pgdg_redhat_repo_path: '/etc/yum.repos.d/pgdg-redhat-all.repo'
path: automation/roles/add-repository/tasks/main.yml
user: login: pat-s
body: Yeah surely, this was just a quick & dirty win to get started.
created_at: 2025-03-05T08:03:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -215,6 +215,8 @@ wal_g_package_file: "wal-g.linux-amd64.tar.gz" # https://github.com/wal-g/wal-g/
 haproxy_package_file: []
 #  - "rh-haproxy18-runtime-3.1-2.el7.x86_64.rpm"
 #  - "rh-haproxy18-haproxy-1.8.31-1.el7.x86_64.rpm"
+
+# if haproxy_installation_method: "src" (optional)
path: automation/vars/RedHat.yml
user: login: vitabaks
body: ```suggestion
```
created_at: 2025-03-10T09:17:48Z
author_association: MEMBER

PR comments:
user: login: vitabaks
created_at: 2025-03-05T07:00:15Z
body: @pat-s Thank you for your contribution! I think it can be useful for many people.
author_association: MEMBER
user: login: vitabaks
created_at: 2025-03-05T07:02:11Z
body: > I had to comment the install of the postgresql debuginfo packages as these are not avail for aarch64. Not sure if these are essential, I think they are rather optional?

Yes, debuginfo packages are optional, they make sense when installing perf (install_perl variable, false by default)
author_association: MEMBER
user: login: vitabaks
created_at: 2025-03-05T07:04:43Z
body: > Sorry for the quote changes, my editor autoformats and trims trailing whitespaces etc.

@pat-s can we return the quotes as they were to minimize the amount of changes?
author_association: MEMBER
user: login: pat-s
created_at: 2025-03-05T08:04:26Z
body: > can we return the quotes as they were to minimize the amount of changes?

Would you be ok with adding an editorconfig & prettier config to enforce these rules for editors with format-on-save enabled? This should then prevent similar cases in the future.
author_association: CONTRIBUTOR
user: login: vitabaks
created_at: 2025-03-05T08:40:20Z
body: @pat-s  I've made a few additional changes to support arm. 

By the way, it looks like Timescale and Citus repo don't support arm packages for RHEL (TODO: check In [pigsty](https://ext.pigsty.io/) repository)
author_association: MEMBER
user: login: pat-s
created_at: 2025-03-05T08:46:37Z
body: Not surprising that some services don't have support yet giving the high amount you're wrapping here. And yes, the [arm64 issue in Citus](https://github.com/citusdata/citus/issues/3854) is still open.

As most of these are rather optional and super crucial for the core support, listing these in a table so that arm64 interested people are aware should be enough?

Would you mind checking on my previous comment so I can make the required adjustments?
author_association: CONTRIBUTOR
user: login: vitabaks
created_at: 2025-03-05T08:59:49Z
body: > As most of these are rather optional and super crucial for the core support, listing these in a table so that arm64 interested people are aware should be enough?

Yes, nevertheless, we strive to anticipate everything to minimize mistakes. If the Pigsty repository includes arm packages for citus, enabling the default repository should be sufficient. I’ll look into this separately.

> Would you mind checking on my previous comment so I can make the required adjustments?

I may not be an Ansible expert like you, but I thought double quotes were perfectly acceptable. I would appreciate it if you could share the correct settings to meet the best practices. We may also need to configure the linter to meet these requirements.
author_association: MEMBER
user: login: pat-s
created_at: 2025-03-05T09:06:00Z
body: > I may not be an Ansible expert like you, but I thought double quotes were perfectly acceptable. I would appreciate it if you could share the correct settings to meet the best practices. We may also need to configure the linter to meet these requirements.

It doesn't matter whether single or double quotes 🙃️. 

My question was: can I add an editorconfig file so that editors automatically uses double-quotes and don't apply these changes on save? (There are also linters for that but this is actually something else). 

This achieves two things: 1. I don't have to do a search & replace for all changes here and 2. Similar cases for other contributors won't occur as the editorconfig is in place.
author_association: CONTRIBUTOR
user: login: vitabaks
created_at: 2025-03-05T09:32:37Z
body: > can I add an editorconfig file

let's do this) I think it will help to adhere to one standard.
author_association: MEMBER
user: login: vitabaks
created_at: 2025-03-05T17:33:45Z
body: It looks good, we need to perform thorough testing.
author_association: MEMBER
user: login: pat-s
created_at: 2025-03-06T11:07:46Z
body: Ideally tests should catch most/any download errors (at least on amd64). Errors for arm64 are not that problematic as its a new feature anyhow and nobody depends on it yet.
author_association: CONTRIBUTOR
user: login: vitabaks
created_at: 2025-03-10T14:52:31Z
body: ##  [Test 1] OS: Ubuntu 24.04, Components: etcd, patroni, postgres, pgbouncer

Note: for testing we enabled the installation of all extensions from [auto-setup](https://autobase.tech/docs/extensions/install#method-1-auto-setup) mode, **excluding**  `citus` (no arm64 support).

Deploy:

```
git clone --branch arm64 --single-branch https://github.com/pat-s/autobase.git
cd autobase
make docker-build-automation
```

```
export HCLOUD_API_TOKEN=<value>

docker run --rm -it \
  --env HCLOUD_API_TOKEN=${HCLOUD_API_TOKEN} \
  automation:local \
    ansible-playbook deploy_pgcluster.yml --extra-vars \
      "ansible_user=root \
       cloud_provider='hetzner' \
       cloud_load_balancer=false \
       server_count=1 \
       server_type='CAX11' \
       server_image='ubuntu-24.04' \
       server_location='fsn1' \
       volume_size=10 \
       postgresql_version=17 \
       patroni_cluster_name='test-pg-cluster-arm' \
       pgbackrest_auto_conf=false \
       ssh_public_keys='ssh-rsa AAAAB3NzaC1yc2EAAAA******whzcMINzKKCc7AVGbk=' \
       enable_timescaledb=true enable_paradedb=true enable_pgvector=true enable_pgvectorscale=true enable_postgis=true enable_pgrouting=true enable_pg_cron=true enable_pgaudit=true enable_pg_partman=true enable_pg_repack=true enable_pg_stat_kcache=true enable_pg_wait_sampling=true \
       pgvectorscale_version=0.6.0 pg_search_version=0.15.7 pg_analytics_version=0.3.5"
```

- cloud_provider='hetzner'
- server_type='CAX11' (ARM)

Result:

```
PLAY [Deploy PostgreSQL HA Cluster (based on "Patroni")] *******************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Include main variables] **********************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Generate a unique temporary SSH key name] **********************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Generate a new temporary SSH key to access the server for deployment] ******************************************************************************************************************************************************************
changed: [localhost]

TASK [cloud-resources : Set variable: ssh_key_name and ssh_key_content] ****************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Ensure that 'python3-pip' package is present on controlling host] **********************************************************************************************************************************************************************
ok: [localhost -> 127.0.0.1]

TASK [cloud-resources : Ensure that 'hcloud' dependency is present on controlling host] ************************************************************************************************************************************************************************
ok: [localhost -> 127.0.0.1]

TASK [cloud-resources : Hetzner Cloud: Remove temporary SSH key 'ssh_key_tmp_tbuwvly' from cloud (if any)] *****************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Hetzner Cloud: Add SSH key 'ssh_key_tmp_tbuwvly' to cloud] *****************************************************************************************************************************************************************************
changed: [localhost]

TASK [cloud-resources : Hetzner Cloud: Gather information about SSH key 'ssh_key_tmp_tbuwvly'] *****************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Set variable: ssh_key_names] ***********************************************************************************************************************************************************************************************************
ok: [localhost] => (item=None)
ok: [localhost]

TASK [cloud-resources : Hetzner Cloud: Gather information about network zones] *********************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Hetzner Cloud: Extract network zone for server_location] *******************************************************************************************************************************************************************************
ok: [localhost] => (item=network_zone: eu-central)

TASK [cloud-resources : Hetzner Cloud: Gather information about networks] **************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Hetzner Cloud: Create a network 'postgres-cluster-network-eu-central'] *****************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Hetzner Cloud: Create a subnetwork in network 'postgres-cluster-network-eu-central'] ***************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Set variable: server_network] **********************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Hetzner Cloud: Create or modify public firewall] ***************************************************************************************************************************************************************************************
changed: [localhost]

TASK [cloud-resources : Hetzner Cloud: Create or modify Postgres cluster firewall] *****************************************************************************************************************************************************************************
changed: [localhost]

TASK [cloud-resources : Hetzner Cloud: Create or modify server] ************************************************************************************************************************************************************************************************
changed: [localhost] => (item=test-pg-cluster-arm-pgnode01)

TASK [cloud-resources : Hetzner Cloud: Add server to network 'postgres-cluster-network-eu-central'] ************************************************************************************************************************************************************
ok: [localhost] => (item=test-pg-cluster-arm-pgnode01)

TASK [cloud-resources : Hetzner Cloud: Create or modify volume] ************************************************************************************************************************************************************************************************
changed: [localhost] => (item=test-pg-cluster-arm-pgnode01-storage)

TASK [cloud-resources : Wait for host to be available via SSH] *************************************************************************************************************************************************************************************************
ok: [localhost] => (item=167.235.240.131)

TASK [cloud-resources : Server info] ***************************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=167.235.240.131) => {
    "msg": {
        "id": "61158739",
        "image": "ubuntu-24.04",
        "name": "test-pg-cluster-arm-pgnode01",
        "private_ip": "10.0.1.1",
        "public_ip": "167.235.240.131",
        "type": "cax11",
        "volume_size": "10 GB"
    }
}

TASK [cloud-resources : Inventory | Initialize ip_addresses variable] ******************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Inventory | Extract IP addresses] ******************************************************************************************************************************************************************************************************
ok: [localhost] => (item=public_ip: 167.235.240.131, private_ip: 10.0.1.1)

TASK [cloud-resources : Set variable: ssh_private_key_file] ****************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Inventory | Add host to 'postgres_cluster', 'master' groups] ***************************************************************************************************************************************************************************
ok: [localhost] => (item=167.235.240.131)

TASK [cloud-resources : Inventory | Add host to 'etcd_cluster' group] ******************************************************************************************************************************************************************************************
ok: [localhost] => (item=167.235.240.131)

TASK [cloud-resources : Hetzner Cloud: Remove temporary SSH key ssh_key_tmp_tbuwvly from cloud] ****************************************************************************************************************************************************************
changed: [localhost]

PLAY [deploy_pgcluster.yml | Perform pre-checks] ***************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include main variables] **********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include system variables] ********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include OS-specific variables] ***************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [System info] *********************************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": {
        "architecture": "aarch64",
        "cpu": {
            "cores": "1",
            "count": "2",
            "model": "N/A"
        },
        "disk_space_total": "37.47 GB",
        "ip_address": "10.0.1.1",
        "kernel": "6.8.0-54-generic",
        "memory": "3.72 GB",
        "os": "Ubuntu 24.04",
        "product_name": "vServer",
        "server_location": "fsn1",
        "server_name": "test-pg-cluster-arm-pgnode01",
        "virtualization_type": "kvm"
    }
}

TASK [Update apt cache] ****************************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [Make sure the gnupg and apt-transport-https packages are present] ****************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [Make sure that the iproute is installed] *****************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [authorized-keys : Get system username] *******************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [authorized-keys : Add public keys to ~root/.ssh/authorized_keys] *****************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAgE*******EzbGg63wX2uPq35NlVL6Bn/whzcMINzKKCc7AVGbk=)

TASK [pre-checks : Set max_connections from vars or use default] ***********************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item={'option': 'max_connections', 'value': '1000'})

TASK [pre-checks : PgBouncer | Calculate pool_size] ************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item={'name': 'postgres', 'dbname': 'postgres', 'pool_parameters': ''})

TASK [pre-checks : PgBouncer | Calculate total pool_size] ******************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pre-checks : PgBouncer | Show total pool_size] ***********************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "pgbouncer_total_pool_size": "100"
}

TASK [pre-checks : PostgreSQL | check that data directory "/pgdata/17/main" is not initialized] ****************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pre-checks : HugePages | Get shared_buffers value from postgresql_parameters variable] *******************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pre-checks : HugePages | Set variable: shared_buffers_gb] ************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pre-checks : HugePages | No configuration is required] ***************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": "Current shared_buffers size: 951MB (less than 8GB). No HugePages configuration is required."
}

TASK [pre-checks : Generate the missing passwords] *************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=patroni_superuser_password)
ok: [10.0.1.1] => (item=patroni_replication_password)
ok: [10.0.1.1] => (item=patroni_restapi_password)
ok: [10.0.1.1] => (item=pgbouncer_auth_password)

TASK [pre-checks : Set password variables for all hosts] *******************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pre-checks : Create a list of extensions] ****************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pre-checks : Add required extensions to 'shared_preload_libraries' (if missing)] *************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=timescaledb)
ok: [10.0.1.1] => (item=pg_cron)
ok: [10.0.1.1] => (item=pgaudit)
ok: [10.0.1.1] => (item=pg_stat_statements)
ok: [10.0.1.1] => (item=pg_stat_kcache)
ok: [10.0.1.1] => (item=pg_wait_sampling)
ok: [10.0.1.1] => (item=pg_partman_bgw)
ok: [10.0.1.1] => (item=pg_search)
ok: [10.0.1.1] => (item=pg_analytics)

TASK [tls_certificate/generate : Make sure that the python3-cryptography package is present] *******************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [tls_certificate/generate : Clean up existing certificates (if any)] **************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=/etc/tls/server.key)
ok: [10.0.1.1] => (item=/etc/tls/server.crt)
ok: [10.0.1.1] => (item=/etc/tls/ca.crt)
ok: [10.0.1.1] => (item=/etc/tls/ca.key)
ok: [10.0.1.1] => (item=/etc/etcd/tls/server.crt)
ok: [10.0.1.1] => (item=/etc/etcd/tls/ca.crt)
ok: [10.0.1.1] => (item=/etc/etcd/tls/server.key)

TASK [tls_certificate/generate : Generate subjectAltName entries for all hosts] ********************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [tls_certificate/generate : Display Certificate subjectAltName future value] ******************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "subject_alt_name": "DNS:test-pg-cluster-arm-pgnode01,IP:10.0.1.1,DNS:localhost,IP:127.0.0.1"
}

TASK [tls_certificate/generate : Ensure TLS directory exist] ***************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Generate CA private key] ******************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Create CSR for CA certificate] ************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Create self-signed CA certificate from CSR] ***********************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Create server private key] ****************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Create server CSR] ************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Sign server certificate with the CA] ******************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Write server certificate] *****************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

PLAY [etcd_cluster.yml | Deploy etcd Cluster] ******************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include main variables] **********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include system variables] ********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include OS-specific variables] ***************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Update apt cache] ****************************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Make sure the gnupg and apt-transport-https packages are present] ****************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [etcd : Make sure the unzip/tar packages are present] *****************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [etcd : Download "etcd" package] **************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=https://github.com/etcd-io/etcd/releases/download/v3.5.17/etcd-v3.5.17-linux-arm64.tar.gz)

TASK [etcd : Extract "etcd" into /tmp] *************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [etcd : Copy "etcd" and "etcdctl" binary files to /usr/local/bin/] ****************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=etcd)
changed: [10.0.1.1] => (item=etcdctl)

TASK [etcd : Add etcd user] ************************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [etcd : Create etcd conf directory] ***********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [Fetch etcd TLS certificate, key and CA from the master node] *********************************************************************************************************************************************************************************************

TASK [../roles/tls_certificate/copy : Fetch TLS certificate, key and CA from the master node into memory] ******************************************************************************************************************************************************
ok: [10.0.1.1] => (item=/etc/tls/server.key)
ok: [10.0.1.1] => (item=/etc/tls/server.crt)
ok: [10.0.1.1] => (item=/etc/tls/ca.crt)

TASK [../roles/tls_certificate/copy : Create directory /etc/etcd/tls] ******************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [../roles/tls_certificate/copy : Copy PostgreSQL TLS certificate, key and CA to all nodes] ****************************************************************************************************************************************************************
changed: [10.0.1.1] => (item={'index': 1, 'path': '/etc/etcd/tls/server.crt', 'mode': '0644'})
changed: [10.0.1.1] => (item={'index': 2, 'path': '/etc/etcd/tls/ca.crt', 'mode': '0644'})
changed: [10.0.1.1] => (item={'index': 0, 'path': '/etc/etcd/tls/server.key', 'mode': '0400'})

TASK [etcd : Create etcd data directory] ***********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [etcd : Generate conf file "/etc/etcd/etcd.conf"] *********************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [etcd : Copy systemd service file] ************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [etcd : Enable and start etcd service] ********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [etcd : Wait for port 2379 to become open on the host] ****************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [etcd : Wait until the etcd cluster is healthy] ***********************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [etcd : cluster health] ***********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": "https://10.0.1.1:2379 is healthy: successfully committed proposal: took = 68.559498ms\n"
}

PLAY [consul.yml | Configure Consul instances] *****************************************************************************************************************************************************************************************************************
skipping: no hosts matched

PLAY [deploy_pgcluster.yml | Postgres Cluster Configuration] ***************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include main variables] **********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include system variables] ********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include OS-specific variables] ***************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [add-repository : Make sure the python3-debian package is present] ****************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [add-repository : Add repository] *************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item={'repo': 'deb https://apt.postgresql.org/pub/repos/apt/ noble-pgdg main', 'key': 'https://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc'})

TASK [add-repository : Update apt cache] ***********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [add-repository : Add TimescaleDB repository] *************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Update apt cache] *****************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install system packages] **********************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=python3)
changed: [10.0.1.1] => (item=python3-dev)
changed: [10.0.1.1] => (item=python3-psycopg2)
ok: [10.0.1.1] => (item=python3-setuptools)
changed: [10.0.1.1] => (item=python3-pip)
ok: [10.0.1.1] => (item=curl)
ok: [10.0.1.1] => (item=less)
ok: [10.0.1.1] => (item=sudo)
ok: [10.0.1.1] => (item=vim)
ok: [10.0.1.1] => (item=gcc)
changed: [10.0.1.1] => (item=jq)
ok: [10.0.1.1] => (item=iptables)
ok: [10.0.1.1] => (item=acl)
changed: [10.0.1.1] => (item=dnsutils)
changed: [10.0.1.1] => (item=moreutils)
ok: [10.0.1.1] => (item=unzip)
ok: [10.0.1.1] => (item=tar)
ok: [10.0.1.1] => (item=zstd)

TASK [packages : PostgreSQL | ensure postgresql database-cluster manager package] ******************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : PostgreSQL | disable initializing of a default postgresql cluster] ****************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : PostgreSQL | disable log rotation with logrotate for postgresql] ******************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install PostgreSQL packages] ******************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=postgresql-17)
ok: [10.0.1.1] => (item=postgresql-client-17)
ok: [10.0.1.1] => (item=postgresql-contrib-17)
changed: [10.0.1.1] => (item=postgresql-server-dev-17)
changed: [10.0.1.1] => (item=postgresql-17-dbgsym)

TASK [packages : Install TimescaleDB package] ******************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=timescaledb-2-postgresql-17)

TASK [packages : Install pg_repack package] ********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pg_cron package] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pgaudit package] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install postgis package] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pgrouting package] ********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pg_stat_kcache package] ***************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pg_wait_sampling package] *************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pg_partman package] *******************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pgvector package] *********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Download pgvectorscale archive] ***************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Extract pgvectorscale package] ****************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pgvectorscale v0.6.0 package] *********************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pg_search v0.15.7 package] ************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pg_analytics v0.3.5 package] **********************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [sudo : Add user to /etc/sudoers.d/] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item={'name': 'postgres', 'nopasswd': 'yes', 'commands': 'ALL'})

TASK [mount : Detect empty volume] *****************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [mount : Create "ext4" filesystem on the disk "/dev/sdb"] *************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [mount : Get UUID of the disk "/dev/sdb"] *****************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [mount : Set mount variables] *****************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [mount : Mount the filesystem] ****************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item={'src': 'UUID=5b4b0cc0-ea7a-49d4-8e56-a092b5876780', 'path': '/pgdata', 'fstype': 'ext4'})

TASK [swap : Ensure swap exists] *******************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [swap : Create swap file] *********************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [swap : Set permissions on swap file] *********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [swap : Make swap file if necessary] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [swap : Run swapon on the swap file] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [swap : Manage swap file entry in fstab] ******************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [sysctl : Build a sysctl_conf dynamic variable] ***********************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=etcd_cluster)
ok: [10.0.1.1] => (item=master)
ok: [10.0.1.1] => (item=postgres_cluster)

TASK [sysctl : Setting kernel parameters] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item={'name': 'vm.overcommit_memory', 'value': '2'})
changed: [10.0.1.1] => (item={'name': 'vm.swappiness', 'value': '1'})
changed: [10.0.1.1] => (item={'name': 'vm.min_free_kbytes', 'value': '102400'})
changed: [10.0.1.1] => (item={'name': 'vm.dirty_expire_centisecs', 'value': '1000'})
changed: [10.0.1.1] => (item={'name': 'vm.dirty_background_bytes', 'value': '67108864'})
changed: [10.0.1.1] => (item={'name': 'vm.dirty_bytes', 'value': '536870912'})
changed: [10.0.1.1] => (item={'name': 'vm.zone_reclaim_mode', 'value': '0'})
changed: [10.0.1.1] => (item={'name': 'kernel.numa_balancing', 'value': '0'})
changed: [10.0.1.1] => (item={'name': 'kernel.sched_autogroup_enabled', 'value': '0'})
changed: [10.0.1.1] => (item={'name': 'net.ipv4.ip_nonlocal_bind', 'value': '1'})
changed: [10.0.1.1] => (item={'name': 'net.ipv4.ip_forward', 'value': '1'})
changed: [10.0.1.1] => (item={'name': 'net.ipv4.ip_local_port_range', 'value': '10000 65535'})
changed: [10.0.1.1] => (item={'name': 'net.core.netdev_max_backlog', 'value': '10000'})
changed: [10.0.1.1] => (item={'name': 'net.ipv4.tcp_max_syn_backlog', 'value': '8192'})
changed: [10.0.1.1] => (item={'name': 'net.core.somaxconn', 'value': '65535'})
changed: [10.0.1.1] => (item={'name': 'net.ipv4.tcp_tw_reuse', 'value': '1'})

TASK [transparent_huge_pages : Create systemd service "disable-transparent-huge-pages.service"] ****************************************************************************************************************************************************************
changed: [10.0.1.1]

RUNNING HANDLER [transparent_huge_pages : Start disable-transparent-huge-pages service] ************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [pam_limits : Linux PAM limits | add or modify nofile limits] *********************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item={'limit_type': 'soft', 'limit_item': 'nofile', 'value': 65536})
changed: [10.0.1.1] => (item={'limit_type': 'hard', 'limit_item': 'nofile', 'value': 200000})

TASK [locales : Generate locales] ******************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item={'language_country': 'en_US', 'encoding': 'UTF-8'})

TASK [locales : Set locale "en_US.utf-8" into /etc/default/locale] *********************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=LANG=en_US.utf-8)
changed: [10.0.1.1] => (item=LANGUAGE=en_US.utf-8)
changed: [10.0.1.1] => (item=LC_ALL=en_US.utf-8)

PLAY [balancers.yml | Configure HAProxy load balancers] ********************************************************************************************************************************************************************************************************
skipping: no hosts matched

PLAY [deploy_pgcluster.yml | Install and configure pgBackRest] *************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include main variables] **********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include OS-specific variables] ***************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

PLAY [deploy_pgcluster.yml | PostgreSQL Cluster Deployment] ****************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include main variables] **********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include system variables] ********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include OS-specific variables] ***************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [tls_certificate/copy : Fetch TLS certificate, key and CA from the master node into memory] ***************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=/etc/tls/server.key)
ok: [10.0.1.1] => (item=/etc/tls/server.crt)
ok: [10.0.1.1] => (item=/etc/tls/ca.crt)

TASK [tls_certificate/copy : Create directory /etc/tls] ********************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/copy : Copy PostgreSQL TLS certificate, key and CA to all nodes] *************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item={'index': 1, 'path': '/etc/tls/server.crt', 'mode': '0644'})
changed: [10.0.1.1] => (item={'index': 2, 'path': '/etc/tls/ca.crt', 'mode': '0644'})
changed: [10.0.1.1] => (item={'index': 0, 'path': '/etc/tls/server.key', 'mode': '0400'})

TASK [pgbouncer : Install pgbouncer package] *******************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [pgbouncer : Ensure config directory "/etc/pgbouncer" exist] **********************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [pgbouncer : Ensure log directory "/var/log/pgbouncer" exist] *********************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [pgbouncer : Check if pgbouncer systemd service file exists] **********************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pgbouncer : Stop and disable standard init script] *******************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [pgbouncer : Configure pgbouncer systemd service file] ****************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

TASK [pgbouncer : Ensure pgbouncer service is enabled] *********************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

TASK [pgbouncer : Enable log rotation with logrotate] **********************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

TASK [pgbouncer : Configure pgbouncer.ini] *********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

TASK [pgpass : Configure a password file (/var/lib/postgresql/.pgpass)] ****************************************************************************************************************************************************************************************
changed: [10.0.1.1]

RUNNING HANDLER [Restart pgbouncer service] ********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

RUNNING HANDLER [Wait for port "6432" to become open on the host] **********************************************************************************************************************************************************************************************
ok: [10.0.1.1]

RUNNING HANDLER [Reload pgbouncer service] *********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

TASK [patroni : Install patroni package] ***********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Create conf directory] *************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Generate conf file "/etc/patroni/patroni.yml"] *************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Copy systemd service file "/etc/systemd/system/patroni.service"] *******************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | make sure the postgresql log directory "/var/log/postgresql" exists] ******************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | make sure PostgreSQL data directory "/pgdata/17/main" exists] *************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | make sure PostgreSQL config directory exists] *****************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | make sure PostgreSQL config files exists] *********************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | generate default PostgreSQL config files] *********************************************************************************************************************************************************************************
[WARNING]: Module remote_tmp /tmp/postgres/ansible did not exist and was created with a mode of 0700, this may cause issues when running as another user. To avoid this, create the remote_tmp dir with the correct permissions manually
changed: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | Make sure the patroni service is stopped] *********************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | make sure the data directory "/pgdata/17/main" is empty] ******************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=absent)
changed: [10.0.1.1] => (item=directory)

TASK [patroni : Start patroni service on the Master server] ****************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Wait for port 8008 to become open on the host] *************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [patroni : Check PostgreSQL is started and accepting connections] *****************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [patroni : Wait for the cluster to initialize (master is the leader with the lock)] ***********************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | generate pg_hba.conf] *****************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | reload for apply the pg_hba.conf] *****************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Turning off postgresql autostart from config "start.conf" (will be managed by patroni)] ********************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Disable "postgresql@17-main" service] **********************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [patroni : Add PATRONICTL_CONFIG_FILE environment variable into /etc/environment] *************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [postgresql-users : Make sure the PostgreSQL users are present] *******************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

TASK [pgbouncer/config : Ensure config directory "/etc/pgbouncer" exist] ***************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pgbouncer/config : Update pgbouncer.ini] *****************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=pgbouncer)

TASK [pgbouncer/config : Check if 'user_search' function exists] ***********************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pgbouncer/config : Create 'user_search' function for pgbouncer 'auth_query' option] **********************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [netdata : Download Netdata installation script] **********************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [netdata : Install Netdata] *******************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [netdata : Configure Netdata] *****************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [netdata : Restart Netdata] *******************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [deploy-finish : Get Postgres users] **********************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [deploy-finish : Get Postgres databases] ******************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [deploy-finish : Get Postgres cluster info] ***************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [deploy-finish : Postgres list of users] ******************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": [
        "                              List of roles",
        " Role name  |                         Attributes                         ",
        "------------+------------------------------------------------------------",
        " pgbouncer  | ",
        " postgres   | Superuser, Create role, Create DB, Replication, Bypass RLS",
        " replicator | Replication"
    ]
}

TASK [deploy-finish : Postgres list of databases] **************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": [
        "                                                     List of databases",
        "   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges   ",
        "-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------",
        " postgres  | postgres | UTF8     | libc            | en_US.UTF-8 | en_US.UTF-8 |        |           | ",
        " template0 | postgres | UTF8     | libc            | en_US.UTF-8 | en_US.UTF-8 |        |           | =c/postgres          +",
        "           |          |          |                 |             |             |        |           | postgres=CTc/postgres",
        " template1 | postgres | UTF8     | libc            | en_US.UTF-8 | en_US.UTF-8 |        |           | =c/postgres          +",
        "           |          |          |                 |             |             |        |           | postgres=CTc/postgres",
        "(3 rows)"
    ]
}

TASK [deploy-finish : Postgres Cluster info] *******************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": [
        "+ Cluster: test-pg-cluster-arm (7480193319394364989) --------+----+-----------+",
        "| Member                       | Host     | Role   | State   | TL | Lag in MB |",
        "+------------------------------+----------+--------+---------+----+-----------+",
        "| test-pg-cluster-arm-pgnode01 | 10.0.1.1 | Leader | running |  1 |           |",
        "+------------------------------+----------+--------+---------+----+-----------+"
    ]
}

TASK [deploy-finish : Connection info] *************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": {
        "address": "10.0.1.1",
        "password": "LsvDofWNIdNoL3MpdGMFfoMVZBRQC5XJ",
        "port": 6432,
        "superuser": "postgres"
    }
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************************************
10.0.1.1                   : ok=163  changed=92   unreachable=0    failed=0    skipped=425  rescued=0    ignored=0   
localhost                  : ok=30   changed=7    unreachable=0    failed=0    skipped=213  rescued=0    ignored=0   

```

Check:

```
root@test-pg-cluster-arm-pgnode01:~# lscpu
Architecture:             aarch64
  CPU op-mode(s):         32-bit, 64-bit
  Byte Order:             Little Endian
CPU(s):                   2
  On-line CPU(s) list:    0,1
Vendor ID:                ARM
  BIOS Vendor ID:         QEMU
  Model name:             Neoverse-N1
    BIOS Model name:      NotSpecified  CPU @ 2.0GHz
    BIOS CPU family:      1
    Model:                1
    Thread(s) per core:   1
    Core(s) per socket:   2
    Socket(s):            1
    Stepping:             r3p1
    BogoMIPS:             50.00
    Flags:                fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp ssbs
NUMA:                     
  NUMA node(s):           1
  NUMA node0 CPU(s):      0,1
Vulnerabilities:          
  Gather data sampling:   Not affected
  Itlb multihit:          Not affected
  L1tf:                   Not affected
  Mds:                    Not affected
  Meltdown:               Not affected
  Mmio stale data:        Not affected
  Reg file data sampling: Not affected
  Retbleed:               Not affected
  Spec rstack overflow:   Not affected
  Spec store bypass:      Mitigation; Speculative Store Bypass disabled via prctl
  Spectre v1:             Mitigation; __user pointer sanitization
  Spectre v2:             Mitigation; CSV2, BHB
  Srbds:                  Not affected
  Tsx async abort:        Not affected
root@test-pg-cluster-arm-pgnode01:~# 
root@test-pg-cluster-arm-pgnode01:~# uname -a
Linux test-pg-cluster-arm-pgnode01 6.8.0-54-generic #56-Ubuntu SMP PREEMPT_DYNAMIC Sat Feb  8 00:17:08 UTC 2025 aarch64 aarch64 aarch64 GNU/Linux

root@test-pg-cluster-arm-pgnode01:~# dpkg -l | grep postgres
ii  pgvectorscale-postgresql-17          1:0.6.0-Linux                           arm64        pgvectorscale for speeding up ANN search
ii  postgresql-17                        17.4-1.pgdg24.04+2                      arm64        The World's Most Advanced Open Source Relational Database
ii  postgresql-17-cron                   1.6.5-1.pgdg24.04+1                     arm64        Run periodic jobs in PostgreSQL
ii  postgresql-17-dbgsym                 17.4-1.pgdg24.04+2                      arm64        debug symbols for postgresql-17
ii  postgresql-17-partman                5.2.4-1.pgdg24.04+1                     arm64        PostgreSQL Partition Manager
ii  postgresql-17-pg-analytics           0.3.5                                   arm64        DuckDB-powered data lake analytics from PostgreSQL
ii  postgresql-17-pg-search              0.15.7                                  arm64        Postgres for Search and Analytics
ii  postgresql-17-pg-stat-kcache         2.3.0-1.pgdg24.04+1                     arm64        PostgreSQL extension to gather per-query kernel statistics.
ii  postgresql-17-pg-wait-sampling       1.1.8-1.pgdg24.04+1                     arm64        Extension providing statistics about PostgreSQL wait events
ii  postgresql-17-pgaudit                17.1-1.pgdg24.04+1                      arm64        PostgreSQL Audit Extension
ii  postgresql-17-pgrouting              3.7.3-1.pgdg24.04+1                     arm64        Routing functionality support for PostgreSQL/PostGIS
ii  postgresql-17-pgrouting-scripts      3.7.3-1.pgdg24.04+1                     all          Routing functionality support for PostgreSQL/PostGIS - SQL scripts
ii  postgresql-17-pgvector               0.8.0-1.pgdg24.04+1                     arm64        Open-source vector similarity search for Postgres
ii  postgresql-17-postgis-3              3.5.2+dfsg-1.pgdg24.04+1                arm64        Geographic objects support for PostgreSQL 17
ii  postgresql-17-postgis-3-scripts      3.5.2+dfsg-1.pgdg24.04+1                all          Geographic objects support for PostgreSQL 17 -- SQL scripts
ii  postgresql-17-repack                 1.5.2-1.pgdg24.04+1                     arm64        reorganize tables in PostgreSQL databases with minimal locks
ii  postgresql-client-17                 17.4-1.pgdg24.04+2                      arm64        front-end programs for PostgreSQL 17
ii  postgresql-client-common             274.pgdg24.04+1                         all          manager for multiple PostgreSQL client versions
ii  postgresql-common                    274.pgdg24.04+1                         all          PostgreSQL database-cluster manager
ii  postgresql-common-dev                274.pgdg24.04+1                         all          extension build tool for multiple PostgreSQL versions
ii  postgresql-server-dev-17             17.4-1.pgdg24.04+2                      arm64        development files for PostgreSQL 17 server-side programming
ii  timescaledb-2-loader-postgresql-17   2.18.2~ubuntu24.04                      arm64        The loader for TimescaleDB to load individual versions.
ii  timescaledb-2-postgresql-17          2.18.2~ubuntu24.04                      arm64        An open-source time-series database based on PostgreSQL, as an extension.
root@test-pg-cluster-arm-pgnode01:~# 
```

**passed**
author_association: MEMBER
user: login: vitabaks
created_at: 2025-03-10T16:40:48Z
body: ##  [Test 2] OS: Rocky Linux 9, Components: etcd, patroni, postgres, pgbouncer

Note: for testing we enabled the installation of all extensions from [auto-setup](https://autobase.tech/docs/extensions/install#method-1-auto-setup) mode, **excluding**  `citus` (no arm64 support on RHEL), `timescalesdb` (no arm64 support for RHEL) and `pgvectorscale` (only deb packages are available). 

Deploy:

```
git clone --branch arm64 --single-branch https://github.com/pat-s/autobase.git
cd autobase
make docker-build-automation
```

```
export HCLOUD_API_TOKEN=<value>

docker run --rm -it \
  --env HCLOUD_API_TOKEN=${HCLOUD_API_TOKEN} \
  automation:local \
    ansible-playbook deploy_pgcluster.yml --extra-vars \
      "ansible_user=root \
       cloud_provider='hetzner' \
       cloud_load_balancer=false \
       server_count=1 \
       server_type='CAX11' \
       server_image='rocky-9' \
       server_location='fsn1' \
       volume_size=10 \
       postgresql_version=17 \
       patroni_cluster_name='test-rocky-arm' \
       pgbackrest_auto_conf=false \
       ssh_public_keys='ssh-rsa AAAAB3NzaC1yc2EAAAA******whzcMINzKKCc7AVGbk=' \
       enable_paradedb=true enable_pgvector=true enable_postgis=true enable_pgrouting=true enable_pg_cron=true enable_pgaudit=true enable_pg_partman=true enable_pg_repack=true enable_pg_stat_kcache=true enable_pg_wait_sampling=true \
       pg_search_version=0.15.7 pg_analytics_version=0.3.5"
```

- cloud_provider='hetzner'
- server_type='CAX11' (ARM)

Result:

```
PLAY [Deploy PostgreSQL HA Cluster (based on "Patroni")] *******************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Include main variables] **********************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Generate a unique temporary SSH key name] **********************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Generate a new temporary SSH key to access the server for deployment] ******************************************************************************************************************************************************************
changed: [localhost]

TASK [cloud-resources : Set variable: ssh_key_name and ssh_key_content] ****************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Ensure that 'python3-pip' package is present on controlling host] **********************************************************************************************************************************************************************
ok: [localhost -> 127.0.0.1]

TASK [cloud-resources : Ensure that 'hcloud' dependency is present on controlling host] ************************************************************************************************************************************************************************
ok: [localhost -> 127.0.0.1]

TASK [cloud-resources : Hetzner Cloud: Remove temporary SSH key 'ssh_key_tmp_kpjrisc' from cloud (if any)] *****************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Hetzner Cloud: Add SSH key 'ssh_key_tmp_kpjrisc' to cloud] *****************************************************************************************************************************************************************************
changed: [localhost]

TASK [cloud-resources : Hetzner Cloud: Gather information about SSH key 'ssh_key_tmp_kpjrisc'] *****************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Set variable: ssh_key_names] ***********************************************************************************************************************************************************************************************************
ok: [localhost] => (item=None)
ok: [localhost]

TASK [cloud-resources : Hetzner Cloud: Gather information about network zones] *********************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Hetzner Cloud: Extract network zone for server_location] *******************************************************************************************************************************************************************************
ok: [localhost] => (item=network_zone: eu-central)

TASK [cloud-resources : Hetzner Cloud: Gather information about networks] **************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Hetzner Cloud: Create a network 'postgres-cluster-network-eu-central'] *****************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Hetzner Cloud: Create a subnetwork in network 'postgres-cluster-network-eu-central'] ***************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Set variable: server_network] **********************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Hetzner Cloud: Create or modify public firewall] ***************************************************************************************************************************************************************************************
changed: [localhost]

TASK [cloud-resources : Hetzner Cloud: Create or modify Postgres cluster firewall] *****************************************************************************************************************************************************************************
changed: [localhost]

TASK [cloud-resources : Hetzner Cloud: Create or modify server] ************************************************************************************************************************************************************************************************
changed: [localhost] => (item=test-rocky-arm-pgnode01)

TASK [cloud-resources : Hetzner Cloud: Add server to network 'postgres-cluster-network-eu-central'] ************************************************************************************************************************************************************
ok: [localhost] => (item=test-rocky-arm-pgnode01)

TASK [cloud-resources : Hetzner Cloud: Create or modify volume] ************************************************************************************************************************************************************************************************
changed: [localhost] => (item=test-rocky-arm-pgnode01-storage)

TASK [cloud-resources : Wait for host to be available via SSH] *************************************************************************************************************************************************************************************************
ok: [localhost] => (item=167.235.240.131)

TASK [cloud-resources : Server info] ***************************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=167.235.240.131) => {
    "msg": {
        "id": "61162553",
        "image": "rocky-9",
        "name": "test-rocky-arm-pgnode01",
        "private_ip": "10.0.1.1",
        "public_ip": "167.235.240.131",
        "type": "cax11",
        "volume_size": "10 GB"
    }
}

TASK [cloud-resources : Inventory | Initialize ip_addresses variable] ******************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Inventory | Extract IP addresses] ******************************************************************************************************************************************************************************************************
ok: [localhost] => (item=public_ip: 167.235.240.131, private_ip: 10.0.1.1)

TASK [cloud-resources : Set variable: ssh_private_key_file] ****************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [cloud-resources : Inventory | Add host to 'postgres_cluster', 'master' groups] ***************************************************************************************************************************************************************************
ok: [localhost] => (item=167.235.240.131)

TASK [cloud-resources : Inventory | Add host to 'etcd_cluster' group] ******************************************************************************************************************************************************************************************
ok: [localhost] => (item=167.235.240.131)

TASK [cloud-resources : Hetzner Cloud: Remove temporary SSH key ssh_key_tmp_kpjrisc from cloud] ****************************************************************************************************************************************************************
changed: [localhost]

PLAY [deploy_pgcluster.yml | Perform pre-checks] ***************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include main variables] **********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include system variables] ********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include OS-specific variables] ***************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [System info] *********************************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": {
        "architecture": "aarch64",
        "cpu": {
            "cores": "1",
            "count": "2",
            "model": "N/A"
        },
        "disk_space_total": "37.47 GB",
        "ip_address": "10.0.1.1",
        "kernel": "5.14.0-503.26.1.el9_5.aarch64",
        "memory": "3.41 GB",
        "os": "Rocky 9.5",
        "product_name": "vServer",
        "server_location": "fsn1",
        "server_name": "test-rocky-arm-pgnode01",
        "virtualization_type": "kvm"
    }
}

TASK [Clean dnf cache] *****************************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [Make sure that the iproute is installed] *****************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [authorized-keys : Get system username] *******************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [authorized-keys : Add public keys to ~root/.ssh/authorized_keys] *****************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAgEA0TU9YoE5MwvO*********bGg63wX2uPq35NlVL6Bn/whzcMINzKKCc7AVGbk=)

TASK [pre-checks : Set max_connections from vars or use default] ***********************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item={'option': 'max_connections', 'value': '1000'})

TASK [pre-checks : PgBouncer | Calculate pool_size] ************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item={'name': 'postgres', 'dbname': 'postgres', 'pool_parameters': ''})

TASK [pre-checks : PgBouncer | Calculate total pool_size] ******************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pre-checks : PgBouncer | Show total pool_size] ***********************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "pgbouncer_total_pool_size": "100"
}

TASK [pre-checks : PostgreSQL | check that data directory "/pgdata/17/data" is not initialized] ****************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pre-checks : HugePages | Get shared_buffers value from postgresql_parameters variable] *******************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pre-checks : HugePages | Set variable: shared_buffers_gb] ************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pre-checks : HugePages | No configuration is required] ***************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": "Current shared_buffers size: 871MB (less than 8GB). No HugePages configuration is required."
}

TASK [pre-checks : Generate the missing passwords] *************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=patroni_superuser_password)
ok: [10.0.1.1] => (item=patroni_replication_password)
ok: [10.0.1.1] => (item=patroni_restapi_password)
ok: [10.0.1.1] => (item=pgbouncer_auth_password)

TASK [pre-checks : Set password variables for all hosts] *******************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pre-checks : Create a list of extensions] ****************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pre-checks : Add required extensions to 'shared_preload_libraries' (if missing)] *************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=pg_cron)
ok: [10.0.1.1] => (item=pgaudit)
ok: [10.0.1.1] => (item=pg_stat_statements)
ok: [10.0.1.1] => (item=pg_stat_kcache)
ok: [10.0.1.1] => (item=pg_wait_sampling)
ok: [10.0.1.1] => (item=pg_partman_bgw)
ok: [10.0.1.1] => (item=pg_search)
ok: [10.0.1.1] => (item=pg_analytics)

TASK [tls_certificate/generate : Make sure that the python3-cryptography package is present] *******************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Clean up existing certificates (if any)] **************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=/etc/tls/server.key)
ok: [10.0.1.1] => (item=/etc/tls/server.crt)
ok: [10.0.1.1] => (item=/etc/tls/ca.crt)
ok: [10.0.1.1] => (item=/etc/tls/ca.key)
ok: [10.0.1.1] => (item=/etc/etcd/tls/server.crt)
ok: [10.0.1.1] => (item=/etc/etcd/tls/ca.crt)
ok: [10.0.1.1] => (item=/etc/etcd/tls/server.key)

TASK [tls_certificate/generate : Generate subjectAltName entries for all hosts] ********************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [tls_certificate/generate : Display Certificate subjectAltName future value] ******************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "subject_alt_name": "DNS:test-rocky-arm-pgnode01,IP:10.0.1.1,DNS:localhost,IP:127.0.0.1"
}

TASK [tls_certificate/generate : Ensure TLS directory exist] ***************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Generate CA private key] ******************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Create CSR for CA certificate] ************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Create self-signed CA certificate from CSR] ***********************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Create server private key] ****************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Create server CSR] ************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Sign server certificate with the CA] ******************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/generate : Write server certificate] *****************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

PLAY [etcd_cluster.yml | Deploy etcd Cluster] ******************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include main variables] **********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include system variables] ********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include OS-specific variables] ***************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [etcd : Make sure the unzip/tar packages are present] *****************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [etcd : Download "etcd" package] **************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=https://github.com/etcd-io/etcd/releases/download/v3.5.17/etcd-v3.5.17-linux-arm64.tar.gz)

TASK [etcd : Extract "etcd" into /tmp] *************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [etcd : Copy "etcd" and "etcdctl" binary files to /usr/local/bin/] ****************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=etcd)
changed: [10.0.1.1] => (item=etcdctl)

TASK [etcd : Add etcd user] ************************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [etcd : Create etcd conf directory] ***********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [Fetch etcd TLS certificate, key and CA from the master node] *********************************************************************************************************************************************************************************************

TASK [../roles/tls_certificate/copy : Fetch TLS certificate, key and CA from the master node into memory] ******************************************************************************************************************************************************
ok: [10.0.1.1] => (item=/etc/tls/server.key)
ok: [10.0.1.1] => (item=/etc/tls/server.crt)
ok: [10.0.1.1] => (item=/etc/tls/ca.crt)

TASK [../roles/tls_certificate/copy : Create directory /etc/etcd/tls] ******************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [../roles/tls_certificate/copy : Copy PostgreSQL TLS certificate, key and CA to all nodes] ****************************************************************************************************************************************************************
changed: [10.0.1.1] => (item={'index': 1, 'path': '/etc/etcd/tls/server.crt', 'mode': '0644'})
changed: [10.0.1.1] => (item={'index': 2, 'path': '/etc/etcd/tls/ca.crt', 'mode': '0644'})
changed: [10.0.1.1] => (item={'index': 0, 'path': '/etc/etcd/tls/server.key', 'mode': '0400'})

TASK [etcd : Create etcd data directory] ***********************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [etcd : Generate conf file "/etc/etcd/etcd.conf"] *********************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [etcd : Copy systemd service file] ************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [etcd : Enable and start etcd service] ********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [etcd : Wait for port 2379 to become open on the host] ****************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [etcd : Wait until the etcd cluster is healthy] ***********************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [etcd : cluster health] ***********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": "https://10.0.1.1:2379 is healthy: successfully committed proposal: took = 73.521868ms\n"
}

PLAY [consul.yml | Configure Consul instances] *****************************************************************************************************************************************************************************************************************
skipping: no hosts matched

PLAY [deploy_pgcluster.yml | Postgres Cluster Configuration] ***************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include main variables] **********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include system variables] ********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include OS-specific variables] ***************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [add-repository : Get epel-release-latest rpm package] ****************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [add-repository : Install EPEL repository] ****************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [add-repository : Enable CodeReady Linux Builder (crb) repository] ****************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [add-repository : Get pgdg-redhat-repo-latest.noarch.rpm] *************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [add-repository : Install PostgreSQL repository] **********************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Update dnf cache] *****************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install system packages] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=['python3-libselinux', 'python3-libsemanage', 'python3-policycoreutils', 'dnf-utils'])
ok: [10.0.1.1] => (item=python3)
changed: [10.0.1.1] => (item=python3-devel)
changed: [10.0.1.1] => (item=python3-psycopg2)
ok: [10.0.1.1] => (item=python3-setuptools)
ok: [10.0.1.1] => (item=python3-pip)
ok: [10.0.1.1] => (item=python3-urllib3)
ok: [10.0.1.1] => (item=less)
ok: [10.0.1.1] => (item=sudo)
ok: [10.0.1.1] => (item=vim)
changed: [10.0.1.1] => (item=gcc)
ok: [10.0.1.1] => (item=jq)
ok: [10.0.1.1] => (item=iptables)
ok: [10.0.1.1] => (item=acl)
changed: [10.0.1.1] => (item=bind-utils)
changed: [10.0.1.1] => (item=moreutils)
ok: [10.0.1.1] => (item=unzip)
ok: [10.0.1.1] => (item=tar)
changed: [10.0.1.1] => (item=zstd)

TASK [packages : PostgreSQL | check if appstream module is enabled] ********************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [packages : PostgreSQL | disable appstream module] ********************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install PostgreSQL packages] ******************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=postgresql17)
changed: [10.0.1.1] => (item=postgresql17-server)
changed: [10.0.1.1] => (item=postgresql17-contrib)
changed: [10.0.1.1] => (item=postgresql17-devel)

TASK [packages : PostgreSQL | check if appstream module is enabled] ********************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [packages : Install PostgreSQL packages] ******************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=postgresql17)
ok: [10.0.1.1] => (item=postgresql17-server)
ok: [10.0.1.1] => (item=postgresql17-contrib)
ok: [10.0.1.1] => (item=postgresql17-devel)

TASK [packages : Install pg_repack package] ********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pg_cron package] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pgaudit package] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install postgis package] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pgrouting package] ********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pg_stat_kcache package] ***************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pg_wait_sampling package] *************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pg_partman package] *******************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pgvector package] *********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pg_search v0.15.7 package] ************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [packages : Install pg_analytics v0.3.5 package] **********************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [sudo : Add user to /etc/sudoers.d/] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item={'name': 'postgres', 'nopasswd': 'yes', 'commands': 'ALL'})

TASK [mount : Detect empty volume] *****************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [mount : Create "ext4" filesystem on the disk "/dev/sdb"] *************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [mount : Get UUID of the disk "/dev/sdb"] *****************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [mount : Set mount variables] *****************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [mount : Mount the filesystem] ****************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item={'src': 'UUID=ee9621cb-d037-4a94-a15c-473b7ecac55e', 'path': '/pgdata', 'fstype': 'ext4'})

TASK [swap : Ensure swap exists] *******************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [swap : Create swap file] *********************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [swap : Set permissions on swap file] *********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [swap : Make swap file if necessary] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [swap : Run swapon on the swap file] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [swap : Manage swap file entry in fstab] ******************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [sysctl : Build a sysctl_conf dynamic variable] ***********************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=etcd_cluster)
ok: [10.0.1.1] => (item=master)
ok: [10.0.1.1] => (item=postgres_cluster)

TASK [sysctl : Setting kernel parameters] **********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item={'name': 'vm.overcommit_memory', 'value': '2'})
changed: [10.0.1.1] => (item={'name': 'vm.swappiness', 'value': '1'})
changed: [10.0.1.1] => (item={'name': 'vm.min_free_kbytes', 'value': '102400'})
changed: [10.0.1.1] => (item={'name': 'vm.dirty_expire_centisecs', 'value': '1000'})
changed: [10.0.1.1] => (item={'name': 'vm.dirty_background_bytes', 'value': '67108864'})
changed: [10.0.1.1] => (item={'name': 'vm.dirty_bytes', 'value': '536870912'})
changed: [10.0.1.1] => (item={'name': 'vm.zone_reclaim_mode', 'value': '0'})
changed: [10.0.1.1] => (item={'name': 'kernel.numa_balancing', 'value': '0'})
changed: [10.0.1.1] => (item={'name': 'kernel.sched_autogroup_enabled', 'value': '0'})
changed: [10.0.1.1] => (item={'name': 'net.ipv4.ip_nonlocal_bind', 'value': '1'})
changed: [10.0.1.1] => (item={'name': 'net.ipv4.ip_forward', 'value': '1'})
changed: [10.0.1.1] => (item={'name': 'net.ipv4.ip_local_port_range', 'value': '10000 65535'})
changed: [10.0.1.1] => (item={'name': 'net.core.netdev_max_backlog', 'value': '10000'})
changed: [10.0.1.1] => (item={'name': 'net.ipv4.tcp_max_syn_backlog', 'value': '8192'})
changed: [10.0.1.1] => (item={'name': 'net.core.somaxconn', 'value': '65535'})
changed: [10.0.1.1] => (item={'name': 'net.ipv4.tcp_tw_reuse', 'value': '1'})

TASK [transparent_huge_pages : Create systemd service "disable-transparent-huge-pages.service"] ****************************************************************************************************************************************************************
changed: [10.0.1.1]

RUNNING HANDLER [transparent_huge_pages : Start disable-transparent-huge-pages service] ************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [pam_limits : Linux PAM limits | add or modify nofile limits] *********************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item={'limit_type': 'soft', 'limit_item': 'nofile', 'value': 65536})
changed: [10.0.1.1] => (item={'limit_type': 'hard', 'limit_item': 'nofile', 'value': 200000})

TASK [locales : Install glibc-langpack] ************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=glibc-langpack-en)

TASK [locales : Check that the /etc/locale.conf exists] ********************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [locales : Set locale "en_US.utf-8" into /etc/locale.conf] ************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=LANG=en_US.utf-8)
changed: [10.0.1.1] => (item=LC_ALL=en_US.utf-8)

TASK [locales : Set locale "en_US.utf-8" into /etc/environment] ************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=export LANG=en_US.utf-8)
changed: [10.0.1.1] => (item=export LC_ALL=en_US.utf-8)

PLAY [balancers.yml | Configure HAProxy load balancers] ********************************************************************************************************************************************************************************************************
skipping: no hosts matched

PLAY [deploy_pgcluster.yml | Install and configure pgBackRest] *************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include main variables] **********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include OS-specific variables] ***************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

PLAY [deploy_pgcluster.yml | PostgreSQL Cluster Deployment] ****************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include main variables] **********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include system variables] ********************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [Include OS-specific variables] ***************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [tls_certificate/copy : Fetch TLS certificate, key and CA from the master node into memory] ***************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=/etc/tls/server.key)
ok: [10.0.1.1] => (item=/etc/tls/server.crt)
ok: [10.0.1.1] => (item=/etc/tls/ca.crt)

TASK [tls_certificate/copy : Create directory /etc/tls] ********************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [tls_certificate/copy : Copy PostgreSQL TLS certificate, key and CA to all nodes] *************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item={'index': 1, 'path': '/etc/tls/server.crt', 'mode': '0644'})
changed: [10.0.1.1] => (item={'index': 2, 'path': '/etc/tls/ca.crt', 'mode': '0644'})
changed: [10.0.1.1] => (item={'index': 0, 'path': '/etc/tls/server.key', 'mode': '0400'})

TASK [pgbouncer : Install pgbouncer package] *******************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [pgbouncer : Ensure config directory "/etc/pgbouncer" exist] **********************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [pgbouncer : Ensure log directory "/var/log/pgbouncer" exist] *********************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [pgbouncer : Check if pgbouncer systemd service file exists] **********************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pgbouncer : Configure pgbouncer systemd service file] ****************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

TASK [pgbouncer : Ensure pgbouncer service is enabled] *********************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

TASK [pgbouncer : Enable log rotation with logrotate] **********************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

TASK [pgbouncer : Configure pgbouncer.ini] *********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

TASK [pgpass : Configure a password file (/var/lib/pgsql/.pgpass)] *********************************************************************************************************************************************************************************************
changed: [10.0.1.1]

RUNNING HANDLER [Restart pgbouncer service] ********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

RUNNING HANDLER [Wait for port "6432" to become open on the host] **********************************************************************************************************************************************************************************************
ok: [10.0.1.1]

RUNNING HANDLER [Reload pgbouncer service] *********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

TASK [patroni : Install patroni package] ***********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Create conf directory] *************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Generate conf file "/etc/patroni/patroni.yml"] *************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Copy systemd service file "/etc/systemd/system/patroni.service"] *******************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | make sure the postgresql log directory "/var/log/postgresql" exists] ******************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | make sure PostgreSQL data directory "/pgdata/17/data" exists] *************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | Make sure the patroni service is stopped] *********************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | make sure the data directory "/pgdata/17/data" is empty] ******************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=absent)
changed: [10.0.1.1] => (item=directory)

TASK [patroni : Start patroni service on the Master server] ****************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Wait for port 8008 to become open on the host] *************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [patroni : Check PostgreSQL is started and accepting connections] *****************************************************************************************************************************************************************************************
[WARNING]: Module remote_tmp /tmp/postgres/ansible did not exist and was created with a mode of 0700, this may cause issues when running as another user. To avoid this, create the remote_tmp dir with the correct permissions manually
ok: [10.0.1.1]

TASK [patroni : Wait for the cluster to initialize (master is the leader with the lock)] ***********************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | generate pg_hba.conf] *****************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Prepare PostgreSQL | reload for apply the pg_hba.conf] *****************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [patroni : Disable "postgresql-17" service (will be managed by patroni)] **********************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [patroni : Add PATRONICTL_CONFIG_FILE environment variable into /etc/environment] *************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [postgresql-users : Make sure the PostgreSQL users are present] *******************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=pgbouncer)

TASK [pgbouncer/config : Ensure config directory "/etc/pgbouncer" exist] ***************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pgbouncer/config : Update pgbouncer.ini] *****************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => (item=pgbouncer)

TASK [pgbouncer/config : Check if 'user_search' function exists] ***********************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [pgbouncer/config : Create 'user_search' function for pgbouncer 'auth_query' option] **********************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [netdata : Download Netdata installation script] **********************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [netdata : Install Netdata] *******************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [netdata : Configure Netdata] *****************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [netdata : Restart Netdata] *******************************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [deploy-finish : Get Postgres users] **********************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [deploy-finish : Get Postgres databases] ******************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [deploy-finish : Get Postgres cluster info] ***************************************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [deploy-finish : Postgres list of users] ******************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": [
        "                              List of roles",
        " Role name  |                         Attributes                         ",
        "------------+------------------------------------------------------------",
        " pgbouncer  | ",
        " postgres   | Superuser, Create role, Create DB, Replication, Bypass RLS",
        " replicator | Replication"
    ]
}

TASK [deploy-finish : Postgres list of databases] **************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": [
        "                                                     List of databases",
        "   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges   ",
        "-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------",
        " postgres  | postgres | UTF8     | libc            | en_US.UTF-8 | en_US.UTF-8 |        |           | ",
        " template0 | postgres | UTF8     | libc            | en_US.UTF-8 | en_US.UTF-8 |        |           | =c/postgres          +",
        "           |          |          |                 |             |             |        |           | postgres=CTc/postgres",
        " template1 | postgres | UTF8     | libc            | en_US.UTF-8 | en_US.UTF-8 |        |           | =c/postgres          +",
        "           |          |          |                 |             |             |        |           | postgres=CTc/postgres",
        "(3 rows)"
    ]
}

TASK [deploy-finish : Postgres Cluster info] *******************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": [
        "+ Cluster: test-rocky-arm (7480218529028554106) --------+----+-----------+",
        "| Member                  | Host     | Role   | State   | TL | Lag in MB |",
        "+-------------------------+----------+--------+---------+----+-----------+",
        "| test-rocky-arm-pgnode01 | 10.0.1.1 | Leader | running |  1 |           |",
        "+-------------------------+----------+--------+---------+----+-----------+"
    ]
}

TASK [deploy-finish : Connection info] *************************************************************************************************************************************************************************************************************************
ok: [10.0.1.1] => {
    "msg": {
        "address": "10.0.1.1",
        "password": "PeqBfqxXEXbsUVluXzkl2VD0cOjwhBIN",
        "port": 6432,
        "superuser": "postgres"
    }
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************************************
10.0.1.1                   : ok=155  changed=85   unreachable=0    failed=0    skipped=433  rescued=0    ignored=0   
localhost                  : ok=30   changed=7    unreachable=0    failed=0    skipped=213  rescued=0    ignored=0   
```

Check:

```
[root@test-rocky-arm-pgnode01 ~]# dnf list installed | grep -i postgres
postgresql17.aarch64                   17.4-1PGDG.rhel9            @pgdg17      
postgresql17-contrib.aarch64           17.4-1PGDG.rhel9            @pgdg17      
postgresql17-devel.aarch64             17.4-1PGDG.rhel9            @pgdg17      
postgresql17-libs.aarch64              17.4-1PGDG.rhel9            @pgdg17      
postgresql17-server.aarch64            17.4-1PGDG.rhel9            @pgdg17      
[root@test-rocky-arm-pgnode01 ~]# 
[root@test-rocky-arm-pgnode01 ~]# dnf list installed | grep pg_
pg_analytics_17.aarch64                0.3.5-1.el9                 @@commandline
pg_cron_17.aarch64                     1.6.5-1PGDG.rhel9           @pgdg17      
pg_partman_17.aarch64                  5.2.4-1PGDG.rhel9           @pgdg17      
pg_repack_17.aarch64                   1.5.2-1PGDG.rhel9           @pgdg17      
pg_search_17.aarch64                   0.15.7-1.el9                @@commandline
pg_stat_kcache_17.aarch64              2.3.0-1PGDG.rhel9           @pgdg17      
pg_wait_sampling_17.aarch64            1.1.8-1PGDG.rhel9           @pgdg17   
```


**passed**
author_association: MEMBER
user: login: vitabaks
created_at: 2025-03-11T06:54:07Z
body: ## [Test 3] Other schemes. Components: vip-manager, HAProxy, confd, Keepalived

Make sure that we have tested all possible deployment schemes - https://autobase.tech/docs/overview/architecture

### Result:

vip-manager (Ubuntu 24.04)

Note: if `cluster_vip` is specified

```
TASK [vip-manager : Get vip-manager package] *******************************************************************************************************************************************************************************************************************
changed: [10.0.1.2] => (item=https://github.com/cybertec-postgresql/vip-manager/releases/download/v3.0.0/vip-manager_3.0.0_Linux_arm64.deb)

TASK [vip-manager : Install vip-manager] ***********************************************************************************************************************************************************************************************************************
changed: [10.0.1.2]

TASK [vip-manager : Make sure the conf directory "/etc/patroni" exist] *****************************************************************************************************************************************************************************************
ok: [10.0.1.2]

TASK [vip-manager : Generate conf file "/etc/patroni/vip-manager.yml"] *****************************************************************************************************************************************************************************************
changed: [10.0.1.2]

TASK [vip-manager : Generate systemd service file] *************************************************************************************************************************************************************************************************************
changed: [10.0.1.2]

RUNNING HANDLER [vip-manager : Restart vip-manager service] ****************************************************************************************************************************************************************************************************
changed: [10.0.1.2]

RUNNING HANDLER [vip-manager : Wait for the cluster ip address (VIP) "*******" is running] ******************************************************************************************************************************************************************
ok: [10.0.1.2]

```

vip-manager (Rocky Linux 9)
```
TASK [vip-manager : Get vip-manager package] *******************************************************************************************************************************************************************************************************************
changed: [10.0.1.1] => (item=https://github.com/cybertec-postgresql/vip-manager/releases/download/v3.0.0/vip-manager_3.0.0_Linux_arm64.rpm)

TASK [vip-manager : Install vip-manager] ***********************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [vip-manager : Make sure the conf directory "/etc/patroni" exist] *****************************************************************************************************************************************************************************************
ok: [10.0.1.1]

TASK [vip-manager : Generate conf file "/etc/patroni/vip-manager.yml"] *****************************************************************************************************************************************************************************************
changed: [10.0.1.1]

TASK [vip-manager : Generate systemd service file] *************************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

RUNNING HANDLER [vip-manager : Restart vip-manager service] ****************************************************************************************************************************************************************************************************
changed: [10.0.1.1]

RUNNING HANDLER [vip-manager : Wait for the cluster ip address (VIP) "********" is running] ******************************************************************************************************************************************************************
ok: [10.0.1.1]

```

HAProxy, confd, Keepalived (Ubuntu 24.04)

Note: if `with_haproxy_load_balancing` is `true` and `cluster_vip` is specified

```
PLAY [balancers.yml | Configure HAProxy load balancers] ***********************************************************************

TASK [Gathering Facts] ********************************************************************************************************
ok: [10.0.1.1]

TASK [Include main variables] *************************************************************************************************
ok: [10.0.1.1]

TASK [Include system variables] ***********************************************************************************************
ok: [10.0.1.1]

TASK [Include OS-specific variables] ******************************************************************************************
ok: [10.0.1.1]

TASK [Update apt cache] *******************************************************************************************************
ok: [10.0.1.1]

TASK [Make sure the gnupg and apt-transport-https packages are present] *******************************************************
ok: [10.0.1.1]

TASK [sysctl : Build a sysctl_conf dynamic variable] **************************************************************************
ok: [10.0.1.1] => (item=balancers)
ok: [10.0.1.1] => (item=etcd_cluster)
ok: [10.0.1.1] => (item=master)
ok: [10.0.1.1] => (item=postgres_cluster)

TASK [sysctl : Setting kernel parameters] *************************************************************************************
ok: [10.0.1.1] => (item={'name': 'net.ipv4.ip_nonlocal_bind', 'value': '1'})
ok: [10.0.1.1] => (item={'name': 'net.ipv4.ip_forward', 'value': '1'})
ok: [10.0.1.1] => (item={'name': 'net.ipv4.ip_local_port_range', 'value': '10000 65535'})
ok: [10.0.1.1] => (item={'name': 'net.core.netdev_max_backlog', 'value': '10000'})
ok: [10.0.1.1] => (item={'name': 'net.ipv4.tcp_max_syn_backlog', 'value': '8192'})
ok: [10.0.1.1] => (item={'name': 'net.core.somaxconn', 'value': '65535'})
ok: [10.0.1.1] => (item={'name': 'net.ipv4.tcp_tw_reuse', 'value': '1'})
ok: [10.0.1.1] => (item={'name': 'vm.overcommit_memory', 'value': '2'})
ok: [10.0.1.1] => (item={'name': 'vm.swappiness', 'value': '1'})
ok: [10.0.1.1] => (item={'name': 'vm.min_free_kbytes', 'value': '102400'})
ok: [10.0.1.1] => (item={'name': 'vm.dirty_expire_centisecs', 'value': '1000'})
ok: [10.0.1.1] => (item={'name': 'vm.dirty_background_bytes', 'value': '67108864'})
ok: [10.0.1.1] => (item={'name': 'vm.dirty_bytes', 'value': '536870912'})
ok: [10.0.1.1] => (item={'name': 'vm.zone_reclaim_mode', 'value': '0'})
ok: [10.0.1.1] => (item={'name': 'kernel.numa_balancing', 'value': '0'})
ok: [10.0.1.1] => (item={'name': 'kernel.sched_autogroup_enabled', 'value': '0'})

TASK [haproxy : Install HAProxy package] **************************************************************************************
changed: [10.0.1.1]

TASK [haproxy : Make sure the kernel parameter "net.ipv4.ip_nonlocal_bind" are enabled] ***************************************
ok: [10.0.1.1]

TASK [haproxy : Add haproxy group] ********************************************************************************************
ok: [10.0.1.1]

TASK [haproxy : Add haproxy user] *********************************************************************************************
changed: [10.0.1.1]

TASK [haproxy : Create directories] *******************************************************************************************
changed: [10.0.1.1] => (item=/etc/haproxy)
ok: [10.0.1.1] => (item=/run/haproxy)
changed: [10.0.1.1] => (item=/var/lib/haproxy/dev)

TASK [haproxy : Generate conf file "/etc/haproxy/haproxy.cfg"] ****************************************************************
changed: [10.0.1.1]

TASK [haproxy : Generate systemd service file "/etc/systemd/system/haproxy.service"] ******************************************
changed: [10.0.1.1]

TASK [confd : Download and copy "confd" binary file to /usr/local/bin/] *******************************************************
changed: [10.0.1.1] => (item=https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-arm64)

TASK [confd : Create conf directories] ****************************************************************************************
changed: [10.0.1.1] => (item=/etc/confd/conf.d)
changed: [10.0.1.1] => (item=/etc/confd/templates)

TASK [confd : Generate conf file "/etc/confd/confd.toml"] *********************************************************************
changed: [10.0.1.1]

TASK [confd : Generate conf file "/etc/confd/conf.d/haproxy.toml"] ************************************************************
changed: [10.0.1.1]

TASK [confd : Generate template "/etc/confd/templates/haproxy.tmpl"] **********************************************************
changed: [10.0.1.1]

TASK [confd : Copy systemd service file] **************************************************************************************
changed: [10.0.1.1]

TASK [keepalived : Install keepalived packages] *******************************************************************************
changed: [10.0.1.1]

TASK [keepalived : Make sure the kernel parameters "net.ipv4.ip_nonlocal_bind", "net.ipv4.ip_forward" are enabled] ************
ok: [10.0.1.1] => (item=net.ipv4.ip_nonlocal_bind)
ok: [10.0.1.1] => (item=net.ipv4.ip_forward)

TASK [keepalived : Make sure the "/usr/libexec/keepalived" directory exists] **************************************************
changed: [10.0.1.1]

TASK [keepalived : Create vrrp_script "/usr/libexec/keepalived/haproxy_check.sh"] *********************************************
changed: [10.0.1.1]

TASK [keepalived : Generate conf file "/etc/keepalived/keepalived.conf"] ******************************************************
changed: [10.0.1.1]

RUNNING HANDLER [haproxy : Restart haproxy service] ***************************************************************************
changed: [10.0.1.1]

RUNNING HANDLER [haproxy : Check HAProxy is started and accepting connections] ************************************************
ok: [10.0.1.1]

RUNNING HANDLER [confd : Restart confd service] *******************************************************************************
changed: [10.0.1.1]

RUNNING HANDLER [keepalived : Restart keepalived service] *********************************************************************
changed: [10.0.1.1]

RUNNING HANDLER [keepalived : Wait for the cluster ip address (VIP) "*******" is running] **********************************
ok: [10.0.1.1]
```

HAProxy, confd, Keepalived (Rocky Linux 9)
```
PLAY [balancers.yml | Configure HAProxy load balancers] **********************************************************************

TASK [Gathering Facts] *******************************************************************************************************
ok: [10.0.1.2]

TASK [Include main variables] ************************************************************************************************
ok: [10.0.1.2]

TASK [Include system variables] **********************************************************************************************
ok: [10.0.1.2]

TASK [Include OS-specific variables] *****************************************************************************************
ok: [10.0.1.2]

TASK [sysctl : Build a sysctl_conf dynamic variable] *************************************************************************
ok: [10.0.1.2] => (item=balancers)
ok: [10.0.1.2] => (item=etcd_cluster)
ok: [10.0.1.2] => (item=master)
ok: [10.0.1.2] => (item=postgres_cluster)

TASK [sysctl : Setting kernel parameters] ************************************************************************************
ok: [10.0.1.2] => (item={'name': 'net.ipv4.ip_nonlocal_bind', 'value': '1'})
ok: [10.0.1.2] => (item={'name': 'net.ipv4.ip_forward', 'value': '1'})
ok: [10.0.1.2] => (item={'name': 'net.ipv4.ip_local_port_range', 'value': '10000 65535'})
ok: [10.0.1.2] => (item={'name': 'net.core.netdev_max_backlog', 'value': '10000'})
ok: [10.0.1.2] => (item={'name': 'net.ipv4.tcp_max_syn_backlog', 'value': '8192'})
ok: [10.0.1.2] => (item={'name': 'net.core.somaxconn', 'value': '65535'})
ok: [10.0.1.2] => (item={'name': 'net.ipv4.tcp_tw_reuse', 'value': '1'})
ok: [10.0.1.2] => (item={'name': 'vm.overcommit_memory', 'value': '2'})
ok: [10.0.1.2] => (item={'name': 'vm.swappiness', 'value': '1'})
ok: [10.0.1.2] => (item={'name': 'vm.min_free_kbytes', 'value': '102400'})
ok: [10.0.1.2] => (item={'name': 'vm.dirty_expire_centisecs', 'value': '1000'})
ok: [10.0.1.2] => (item={'name': 'vm.dirty_background_bytes', 'value': '67108864'})
ok: [10.0.1.2] => (item={'name': 'vm.dirty_bytes', 'value': '536870912'})
ok: [10.0.1.2] => (item={'name': 'vm.zone_reclaim_mode', 'value': '0'})
ok: [10.0.1.2] => (item={'name': 'kernel.numa_balancing', 'value': '0'})
ok: [10.0.1.2] => (item={'name': 'kernel.sched_autogroup_enabled', 'value': '0'})

TASK [haproxy : Install HAProxy package] *************************************************************************************
changed: [10.0.1.2]

TASK [haproxy : Make sure the kernel parameter "net.ipv4.ip_nonlocal_bind" are enabled] **************************************
ok: [10.0.1.2]

TASK [haproxy : Add haproxy group] *******************************************************************************************
ok: [10.0.1.2]

TASK [haproxy : Add haproxy user] ********************************************************************************************
changed: [10.0.1.2]

TASK [haproxy : Create directories] ******************************************************************************************
changed: [10.0.1.2] => (item=/etc/haproxy)
changed: [10.0.1.2] => (item=/run/haproxy)
changed: [10.0.1.2] => (item=/var/lib/haproxy/dev)

TASK [haproxy : Generate conf file "/etc/haproxy/haproxy.cfg"] ***************************************************************
changed: [10.0.1.2]

TASK [haproxy : Generate systemd service file "/etc/systemd/system/haproxy.service"] *****************************************
changed: [10.0.1.2]

TASK [haproxy : selinux | make sure the python3-libsemanage, python3-policycoreutils packages is present] ********************
ok: [10.0.1.2]

TASK [haproxy : selinux | set haproxy_connect_any flag to enable tcp connections] ********************************************
changed: [10.0.1.2]

TASK [haproxy : selinux | change the haproxy_t domain to permissive] *********************************************************
changed: [10.0.1.2]

TASK [confd : Download and copy "confd" binary file to /usr/local/bin/] ******************************************************
changed: [10.0.1.2] => (item=https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-arm64)

TASK [confd : Create conf directories] ***************************************************************************************
changed: [10.0.1.2] => (item=/etc/confd/conf.d)
changed: [10.0.1.2] => (item=/etc/confd/templates)

TASK [confd : Generate conf file "/etc/confd/confd.toml"] ********************************************************************
changed: [10.0.1.2]

TASK [confd : Generate conf file "/etc/confd/conf.d/haproxy.toml"] ***********************************************************
changed: [10.0.1.2]

TASK [confd : Generate template "/etc/confd/templates/haproxy.tmpl"] *********************************************************
changed: [10.0.1.2]

TASK [confd : Copy systemd service file] *************************************************************************************
changed: [10.0.1.2]

TASK [keepalived : Install keepalived packages] ******************************************************************************
changed: [10.0.1.2]

TASK [keepalived : Make sure the kernel parameters "net.ipv4.ip_nonlocal_bind", "net.ipv4.ip_forward" are enabled] ***********
ok: [10.0.1.2] => (item=net.ipv4.ip_nonlocal_bind)
ok: [10.0.1.2] => (item=net.ipv4.ip_forward)

TASK [keepalived : Make sure the "/usr/libexec/keepalived" directory exists] *************************************************
changed: [10.0.1.2]

TASK [keepalived : Create vrrp_script "/usr/libexec/keepalived/haproxy_check.sh"] ********************************************
changed: [10.0.1.2]

TASK [keepalived : Generate conf file "/etc/keepalived/keepalived.conf"] *****************************************************
changed: [10.0.1.2]

TASK [keepalived : Selinux | Change the keepalived_t domain to permissive] ***************************************************
changed: [10.0.1.2]

RUNNING HANDLER [haproxy : Restart haproxy service] **************************************************************************
changed: [10.0.1.2]

RUNNING HANDLER [haproxy : Check HAProxy is started and accepting connections] ***********************************************
ok: [10.0.1.2]

RUNNING HANDLER [confd : Restart confd service] ******************************************************************************
changed: [10.0.1.2]

RUNNING HANDLER [keepalived : Restart keepalived service] ********************************************************************
changed: [10.0.1.2]

RUNNING HANDLER [keepalived : Wait for the cluster ip address (VIP) "*****" is running] *********************************
ok: [10.0.1.2]
```

**passed**
author_association: MEMBER
user: login: vitabaks
created_at: 2025-03-16T16:19:17Z
body: ## [Test 4] Other schemes. Components: Consul

Test the scheme using Consul - https://autobase.tech/docs/overview/architecture#3-postgresql-high-availability-with-consul-service-discovery

Note: If `dcs_type` is `consul`

Result:

```
PLAY [consul.yml | Configure Consul instances] ********************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [10.142.0.17]
ok: [10.142.0.16]
ok: [10.142.15.226]

TASK [Include main variables] *************************************************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [Include system variables] ***********************************************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [Include OS-specific variables] ******************************************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [Check if the consul role requirements (ansible.utils) are installed] ****************************************************************************************************************************************************
ok: [10.142.0.16 -> localhost]

TASK [Make sure the unzip package are present on the control host] ************************************************************************************************************************************************************
changed: [10.142.0.16 -> localhost]

TASK [Make sure the python3-pip package are present on the control host] ******************************************************************************************************************************************************
ok: [10.142.0.16 -> localhost]

TASK [Install netaddr dependency on the control host] *************************************************************************************************************************************************************************
changed: [10.142.0.16 -> localhost]

TASK [Update apt cache] *******************************************************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [Make sure the gnupg and apt-transport-https packages are present] *******************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.15.226]
ok: [10.142.0.17]

TASK [Make sure the python3-pip package are present] **************************************************************************************************************************************************************************
changed: [10.142.0.16]
changed: [10.142.15.226]
changed: [10.142.0.17]

TASK [Add a nameserver entry poining to localhost for dnsmasq] ****************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [Redefine the consul_dnsmasq_servers variable] ***************************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [Redefine the consul_node_role and consul_bootstrap_expect variables] ****************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [resolv_conf : Make sure /etc/resolv.conf exists] ************************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.15.226]
ok: [10.142.0.17]

TASK [resolv_conf : Add DNS server(s) into /etc/resolv.conf] ******************************************************************************************************************************************************************
changed: [10.142.0.16] => (item=127.0.0.1)
changed: [10.142.15.226] => (item=127.0.0.1)
[WARNING]: Module remote_tmp /tmp/root/ansible did not exist and was created with a mode of 0700, this may cause issues when running as another user. To avoid this, create the remote_tmp dir with the correct permissions
manually
changed: [10.142.0.17] => (item=127.0.0.1)

TASK [consul : Looking up latest version of Consul] ***************************************************************************************************************************************************************************
ok: [10.142.0.17]
ok: [10.142.0.16]
ok: [10.142.15.226]

TASK [consul : Make sure the python3-pip package are present on controlling host] *********************************************************************************************************************************************
ok: [10.142.0.16 -> 127.0.0.1]

TASK [consul : Install netaddr dependency on controlling host (with --user)] **************************************************************************************************************************************************
ok: [10.142.0.16 -> 127.0.0.1]

TASK [consul : Install netaddr dependency on controlling host (virtualenv)] ***************************************************************************************************************************************************
ok: [10.142.0.16 -> 127.0.0.1]

TASK [consul : Define supported *nix distributions] ***************************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [consul : Check if unzip is installed on control host] *******************************************************************************************************************************************************************
ok: [10.142.0.16 -> 127.0.0.1]

TASK [consul : Include OS-specific variables] *********************************************************************************************************************************************************************************
ok: [10.142.0.16] => (item=/autobase/automation/roles/consul/vars/Debian.yml)
ok: [10.142.0.17] => (item=/autobase/automation/roles/consul/vars/Debian.yml)
ok: [10.142.15.226] => (item=/autobase/automation/roles/consul/vars/Debian.yml)

TASK [consul : Include NIX tasks] *********************************************************************************************************************************************************************************************
included: /autobase/automation/roles/consul/tasks/nix.yml for 10.142.0.16, 10.142.0.17, 10.142.15.226

TASK [consul : Expose advertise_address(_wan) datacenter and node_role as facts] **********************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [consul : Read bootstrapped state] ***************************************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.15.226]
ok: [10.142.0.17]

TASK [consul : Install OS packages and consul - from the repository] **********************************************************************************************************************************************************
included: /autobase/automation/roles/consul/tasks/install_linux_repo.yml for 10.142.0.16, 10.142.0.17, 10.142.15.226

TASK [consul : Install OS packages] *******************************************************************************************************************************************************************************************
ok: [10.142.15.226]
ok: [10.142.0.16]
ok: [10.142.0.17]

TASK [consul : Gather the package facts] **************************************************************************************************************************************************************************************
ok: [10.142.15.226]
ok: [10.142.0.16]
ok: [10.142.0.17]

TASK [consul : Populate service facts] ****************************************************************************************************************************************************************************************
ok: [10.142.15.226]
ok: [10.142.0.16]
ok: [10.142.0.17]

TASK [consul : Remove consul service unit files from previous installation] ***************************************************************************************************************************************************
ok: [10.142.0.16] => (item=/usr/lib/systemd/system/consul.service)
ok: [10.142.0.17] => (item=/usr/lib/systemd/system/consul.service)
ok: [10.142.15.226] => (item=/usr/lib/systemd/system/consul.service)
ok: [10.142.15.226] => (item=/etc/init.d/consul)
ok: [10.142.0.17] => (item=/etc/init.d/consul)
ok: [10.142.0.16] => (item=/etc/init.d/consul)

TASK [consul : Remove the user 'consul'] **************************************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [consul : Make sure the python3-debian package is present] ***************************************************************************************************************************************************************
ok: [10.142.0.17]
ok: [10.142.15.226]
ok: [10.142.0.16]

TASK [consul : Add hashicorp repository] **************************************************************************************************************************************************************************************
changed: [10.142.0.16]
changed: [10.142.0.17]
changed: [10.142.15.226]

TASK [consul : Update apt cache] **********************************************************************************************************************************************************************************************
changed: [10.142.0.16]
changed: [10.142.0.17]
changed: [10.142.15.226]

TASK [consul : Install consul package] ****************************************************************************************************************************************************************************************
changed: [10.142.0.17]
changed: [10.142.0.16]
changed: [10.142.15.226]

TASK [consul : Create a directory /etc/systemd/system/consul.service.d] *******************************************************************************************************************************************************
changed: [10.142.0.16]
changed: [10.142.0.17]
changed: [10.142.15.226]

TASK [consul : Override systemd service params] *******************************************************************************************************************************************************************************
changed: [10.142.0.17]
changed: [10.142.15.226]
changed: [10.142.0.16]

RUNNING HANDLER [consul : restart consul on unix] *****************************************************************************************************************************************************************************
changed: [10.142.15.226]
changed: [10.142.0.17]
changed: [10.142.0.16]

RUNNING HANDLER [consul : systemctl daemon-reload] ****************************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [consul : As, this role work with json conf file only - delete file /etc/consul.d/consul.hcl] ****************************************************************************************************************************
changed: [10.142.0.17]
changed: [10.142.15.226]
changed: [10.142.0.16]

TASK [consul : Configuration and data directories] ****************************************************************************************************************************************************************************
changed: [10.142.0.16] => (item=/etc/consul)
changed: [10.142.0.17] => (item=/etc/consul)
changed: [10.142.15.226] => (item=/etc/consul)
changed: [10.142.0.17] => (item=/etc/consul/conf.d)
changed: [10.142.0.16] => (item=/etc/consul/conf.d)
changed: [10.142.15.226] => (item=/etc/consul/conf.d)
changed: [10.142.0.17] => (item=/var/lib/consul)
changed: [10.142.0.16] => (item=/var/lib/consul)
changed: [10.142.15.226] => (item=/var/lib/consul)

TASK [consul : Check for existing Consul binary] ******************************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.15.226]
ok: [10.142.0.17]

TASK [consul : Calculate whether to install consul binary] ********************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [consul : Generate gossip encryption key] ********************************************************************************************************************************************************************************
changed: [10.142.0.16]

TASK [consul : Write key locally to share with other nodes] *******************************************************************************************************************************************************************
changed: [10.142.0.16 -> localhost]

TASK [consul : Read gossip encryption key for servers that require it] ********************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [consul : Delete gossip encryption key file] *****************************************************************************************************************************************************************************
ok: [10.142.0.16 -> localhost]

TASK [consul : Create configuration] ******************************************************************************************************************************************************************************************
changed: [10.142.0.16] => (item={'dest': '/etc/consul/config.json', 'config_version': 'server', 'when': True})
changed: [10.142.0.17] => (item={'dest': '/etc/consul/config.json', 'config_version': 'server', 'when': True})
changed: [10.142.15.226] => (item={'dest': '/etc/consul/config.json', 'config_version': 'server', 'when': True})

TASK [consul : Set fact list with custom configuration file] ******************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [consul : Enable consul at startup (systemd)] ****************************************************************************************************************************************************************************
changed: [10.142.0.16]
changed: [10.142.0.17]
changed: [10.142.15.226]

TASK [consul : Start Consul] **************************************************************************************************************************************************************************************************
changed: [10.142.0.16]
changed: [10.142.0.17]
changed: [10.142.15.226]

TASK [consul : Check Consul HTTP API (via TCP socket)] ************************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [consul : Create bootstrapped state file] ********************************************************************************************************************************************************************************
changed: [10.142.0.16]
changed: [10.142.0.17]
changed: [10.142.15.226]

TASK [consul : ansible.builtin.include_tasks] *********************************************************************************************************************************************************************************
included: /autobase/automation/roles/consul/tasks/../tasks/dnsmasq.yml for 10.142.0.16, 10.142.0.17, 10.142.15.226

TASK [consul : Install Dnsmasq package] ***************************************************************************************************************************************************************************************
changed: [10.142.0.16]
changed: [10.142.15.226]
changed: [10.142.0.17]
[WARNING]: conditional statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: {{ dnsmasq_item.when }}

TASK [consul : Create Dnsmasq configuration] **********************************************************************************************************************************************************************************
changed: [10.142.15.226] => (item={'dest': '/etc/dnsmasq.d/10-consul', 'group': 'root', 'when': 'ansible_os_family|lower != "freebsd"'})
changed: [10.142.0.16] => (item={'dest': '/etc/dnsmasq.d/10-consul', 'group': 'root', 'when': 'ansible_os_family|lower != "freebsd"'})
changed: [10.142.0.17] => (item={'dest': '/etc/dnsmasq.d/10-consul', 'group': 'root', 'when': 'ansible_os_family|lower != "freebsd"'})

TASK [consul : Check if systemd-resolved service exists] **********************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [consul : Disable systemd-resolved service] ******************************************************************************************************************************************************************************
changed: [10.142.0.17]
changed: [10.142.15.226]
changed: [10.142.0.16]

TASK [consul : Check if resolv.conf is pointing to systemd-resolved] **********************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [consul : Remove resolv.conf association with systemd-resolved] **********************************************************************************************************************************************************
changed: [10.142.0.16]
changed: [10.142.0.17]
changed: [10.142.15.226]

TASK [consul : Create /etc/resolv.conf] ***************************************************************************************************************************************************************************************
changed: [10.142.0.16]
changed: [10.142.0.17]
changed: [10.142.15.226]

TASK [consul : Add a nameserver entry poining to localhost for dnsmasq] *******************************************************************************************************************************************************
changed: [10.142.0.16]
changed: [10.142.0.17]
changed: [10.142.15.226]

TASK [consul : Configure consul services] *************************************************************************************************************************************************************************************
changed: [10.142.15.226] => (item={'name': 'test-arm-ubuntu', 'id': 'test-arm-ubuntu-master', 'tags': ['master', 'primary'], 'port': 6432, 'checks': [{'http': 'http://10.142.15.226:8008/primary', 'interval': '2s'}, {'args': ['systemctl', 'status', 'pgbouncer'], 'interval': '5s'}]})
changed: [10.142.0.16] => (item={'name': 'test-arm-ubuntu', 'id': 'test-arm-ubuntu-master', 'tags': ['master', 'primary'], 'port': 6432, 'checks': [{'http': 'http://10.142.0.16:8008/primary', 'interval': '2s'}, {'args': ['systemctl', 'status', 'pgbouncer'], 'interval': '5s'}]})
changed: [10.142.0.17] => (item={'name': 'test-arm-ubuntu', 'id': 'test-arm-ubuntu-master', 'tags': ['master', 'primary'], 'port': 6432, 'checks': [{'http': 'http://10.142.0.17:8008/primary', 'interval': '2s'}, {'args': ['systemctl', 'status', 'pgbouncer'], 'interval': '5s'}]})
changed: [10.142.0.16] => (item={'name': 'test-arm-ubuntu', 'id': 'test-arm-ubuntu-replica', 'tags': ['replica'], 'port': 6432, 'checks': [{'http': 'http://10.142.0.16:8008/replica?lag=100MB', 'interval': '2s'}, {'args': ['systemctl', 'status', 'pgbouncer'], 'interval': '5s'}]})
changed: [10.142.15.226] => (item={'name': 'test-arm-ubuntu', 'id': 'test-arm-ubuntu-replica', 'tags': ['replica'], 'port': 6432, 'checks': [{'http': 'http://10.142.15.226:8008/replica?lag=100MB', 'interval': '2s'}, {'args': ['systemctl', 'status', 'pgbouncer'], 'interval': '5s'}]})
changed: [10.142.0.17] => (item={'name': 'test-arm-ubuntu', 'id': 'test-arm-ubuntu-replica', 'tags': ['replica'], 'port': 6432, 'checks': [{'http': 'http://10.142.0.17:8008/replica?lag=100MB', 'interval': '2s'}, {'args': ['systemctl', 'status', 'pgbouncer'], 'interval': '5s'}]})

TASK [consul : Get the list of service config files] **************************************************************************************************************************************************************************
ok: [10.142.15.226]
ok: [10.142.0.17]
ok: [10.142.0.16]

TASK [consul : Set var for enabled services] **********************************************************************************************************************************************************************************
ok: [10.142.0.16]
ok: [10.142.0.17]
ok: [10.142.15.226]

TASK [consul : Set fact with list of existing configuration files] ************************************************************************************************************************************************************
ok: [10.142.0.16] => (item={'path': '/etc/consul/conf.d/service_test-arm-ubuntu-replica.json', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 999, 'gid': 988, 'size': 288, 'inode': 524344, 'dev': 66305, 'nlink': 1, 'atime': 1742146825.6812077, 'mtime': 1742146823.5572073, 'ctime': 1742146825.6812077, 'gr_name': 'consul', 'pw_name': 'consul', 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False})
ok: [10.142.0.16] => (item={'path': '/etc/consul/conf.d/service_test-arm-ubuntu-master.json', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 999, 'gid': 988, 'size': 287, 'inode': 524311, 'dev': 66305, 'nlink': 1, 'atime': 1742146819.024207, 'mtime': 1742146816.935207, 'ctime': 1742146819.024207, 'gr_name': 'consul', 'pw_name': 'consul', 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False})
ok: [10.142.0.17] => (item={'path': '/etc/consul/conf.d/service_test-arm-ubuntu-replica.json', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 999, 'gid': 988, 'size': 288, 'inode': 524342, 'dev': 66305, 'nlink': 1, 'atime': 1742146825.6844492, 'mtime': 1742146823.5564492, 'ctime': 1742146825.6844492, 'gr_name': 'consul', 'pw_name': 'consul', 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False})
ok: [10.142.0.17] => (item={'path': '/etc/consul/conf.d/service_test-arm-ubuntu-master.json', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 999, 'gid': 988, 'size': 287, 'inode': 524322, 'dev': 66305, 'nlink': 1, 'atime': 1742146819.0204494, 'mtime': 1742146816.9334497, 'ctime': 1742146819.0214496, 'gr_name': 'consul', 'pw_name': 'consul', 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False})
ok: [10.142.15.226] => (item={'path': '/etc/consul/conf.d/service_test-arm-ubuntu-replica.json', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 999, 'gid': 988, 'size': 290, 'inode': 524342, 'dev': 66305, 'nlink': 1, 'atime': 1742146825.6709483, 'mtime': 1742146823.5569475, 'ctime': 1742146825.6709483, 'gr_name': 'consul', 'pw_name': 'consul', 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False})
ok: [10.142.15.226] => (item={'path': '/etc/consul/conf.d/service_test-arm-ubuntu-master.json', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 999, 'gid': 988, 'size': 289, 'inode': 524322, 'dev': 66305, 'nlink': 1, 'atime': 1742146819.0219457, 'mtime': 1742146816.9339447, 'ctime': 1742146819.0219457, 'gr_name': 'consul', 'pw_name': 'consul', 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False})

TASK [consul : Set fact with list of services we manage] **********************************************************************************************************************************************************************
ok: [10.142.0.16] => (item={'name': 'test-arm-ubuntu', 'id': 'test-arm-ubuntu-master', 'tags': ['master', 'primary'], 'port': 6432, 'checks': [{'http': 'http://10.142.0.16:8008/primary', 'interval': '2s'}, {'args': ['systemctl', 'status', 'pgbouncer'], 'interval': '5s'}]})
ok: [10.142.0.16] => (item={'name': 'test-arm-ubuntu', 'id': 'test-arm-ubuntu-replica', 'tags': ['replica'], 'port': 6432, 'checks': [{'http': 'http://10.142.0.16:8008/replica?lag=100MB', 'interval': '2s'}, {'args': ['systemctl', 'status', 'pgbouncer'], 'interval': '5s'}]})
ok: [10.142.0.17] => (item={'name': 'test-arm-ubuntu', 'id': 'test-arm-ubuntu-master', 'tags': ['master', 'primary'], 'port': 6432, 'checks': [{'http': 'http://10.142.0.17:8008/primary', 'interval': '2s'}, {'args': ['systemctl', 'status', 'pgbouncer'], 'interval': '5s'}]})
ok: [10.142.0.17] => (item={'name': 'test-arm-ubuntu', 'id': 'test-arm-ubuntu-replica', 'tags': ['replica'], 'port': 6432, 'checks': [{'http': 'http://10.142.0.17:8008/replica?lag=100MB', 'interval': '2s'}, {'args': ['systemctl', 'status', 'pgbouncer'], 'interval': '5s'}]})
ok: [10.142.15.226] => (item={'name': 'test-arm-ubuntu', 'id': 'test-arm-ubuntu-master', 'tags': ['master', 'primary'], 'port': 6432, 'checks': [{'http': 'http://10.142.15.226:8008/primary', 'interval': '2s'}, {'args': ['systemctl', 'status', 'pgbouncer'], 'interval': '5s'}]})
ok: [10.142.15.226] => (item={'name': 'test-arm-ubuntu', 'id': 'test-arm-ubuntu-replica', 'tags': ['replica'], 'port': 6432, 'checks': [{'http': 'http://10.142.15.226:8008/replica?lag=100MB', 'interval': '2s'}, {'args': ['systemctl', 'status', 'pgbouncer'], 'interval': '5s'}]})

RUNNING HANDLER [consul : restart consul on unix] *****************************************************************************************************************************************************************************
changed: [10.142.0.16]
changed: [10.142.0.17]
changed: [10.142.15.226]

RUNNING HANDLER [consul : restart dnsmasq] ************************************************************************************************************************************************************************************
changed: [10.142.0.17]
changed: [10.142.0.16]
changed: [10.142.15.226]
```
**passed**
author_association: MEMBER