From 73bbab9a03eda600b2cb6f63ca879ad279e979cd Mon Sep 17 00:00:00 2001 From: klention Date: Sat, 21 Dec 2024 15:31:45 +0100 Subject: [PATCH 01/36] Enabled TLS communication encryption --- automation/add_pgnode.yml | 2 + automation/deploy_pgcluster.yml | 17 ++- .../roles/confd/templates/confd.toml.j2 | 4 +- automation/roles/etcd/tasks/main.yml | 15 ++- automation/roles/etcd/templates/etcd.conf.j2 | 21 +++- .../roles/patroni/templates/patroni.yml.j2 | 18 ++- .../roles/patroni/templates/pg_hba.conf.j2 | 8 +- automation/roles/pgbouncer/tasks/main.yml | 8 ++ .../roles/tls_certificate/copy/tasks/main.yml | 73 +++++++----- .../tls_certificate/generate/tasks/main.yml | 109 ++++++++++++++++++ .../roles/tls_certificate/tasks/main.yml | 30 ----- .../vip-manager/templates/vip-manager.yml.j2 | 16 +-- automation/vars/Debian.yml | 1 - automation/vars/RedHat.yml | 1 - automation/vars/main.yml | 24 ++-- 15 files changed, 249 insertions(+), 98 deletions(-) create mode 100644 automation/roles/tls_certificate/generate/tasks/main.yml delete mode 100644 automation/roles/tls_certificate/tasks/main.yml diff --git a/automation/add_pgnode.yml b/automation/add_pgnode.yml index 9dd7c15f1..a1ceae9f8 100644 --- a/automation/add_pgnode.yml +++ b/automation/add_pgnode.yml @@ -236,6 +236,8 @@ when: pg_probackup_install|bool - role: tls_certificate/copy + vars: + copy_for: "pg" when: tls_cert_generate|bool - role: pgbouncer diff --git a/automation/deploy_pgcluster.yml b/automation/deploy_pgcluster.yml index cf2aed8b8..f4a592db8 100644 --- a/automation/deploy_pgcluster.yml +++ b/automation/deploy_pgcluster.yml @@ -83,6 +83,15 @@ - pgbackrest_auto_conf | default(true) | bool # to be able to disable auto backup settings tags: always + - name: Make sure that the python3-cryptography package is present + ansible.builtin.package: + name: python3-cryptography + state: present + register: pack_status + until: pack_status is success + delay: 5 + retries: 3 + roles: # (optional) if 'ssh_public_keys' is defined - role: authorized-keys @@ -94,6 +103,11 @@ timescale_minimal_pg_version: 12 # if enable_timescale is defined tags: always + - role: hostname + + - role: tls_certificate/generate + when: tls_cert_generate|bool + tasks: - name: Clean dnf cache ansible.builtin.command: dnf clean all @@ -356,9 +370,6 @@ - role: cron - - role: tls_certificate - when: tls_cert_generate|bool - - role: pgbouncer when: pgbouncer_install|bool diff --git a/automation/roles/confd/templates/confd.toml.j2 b/automation/roles/confd/templates/confd.toml.j2 index e27d66f9b..d9ee0f0da 100644 --- a/automation/roles/confd/templates/confd.toml.j2 +++ b/automation/roles/confd/templates/confd.toml.j2 @@ -4,12 +4,12 @@ watch = true nodes = [ {% if not dcs_exists|bool and dcs_type == 'etcd' %} {% for host in groups['etcd_cluster'] %} - "http://{{ hostvars[host]['inventory_hostname'] }}:2379", + "{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ hostvars[host]['inventory_hostname'] }}:2379", {% endfor %} {% endif %} {% if dcs_exists|bool and dcs_type == 'etcd' %} {% for etcd_hosts in patroni_etcd_hosts %} - "{{ patroni_etcd_protocol | default('http', true) }}://{{etcd_hosts.host}}:{{etcd_hosts.port}}", + "{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{etcd_hosts.host}}:{{etcd_hosts.port}}", {% endfor %} {% endif %} ] diff --git a/automation/roles/etcd/tasks/main.yml b/automation/roles/etcd/tasks/main.yml index c18b35941..c20e58a09 100644 --- a/automation/roles/etcd/tasks/main.yml +++ b/automation/roles/etcd/tasks/main.yml @@ -86,6 +86,14 @@ state: directory tags: etcd, etcd_conf +- name: Fetch etcd TLS certificate, key and CA from the master node + ansible.builtin.include_role: + name: ../roles/tls_certificate/copy + vars: + copy_for: "etcd" + when: tls_cert_generate|bool + tags: etcd, etcd_conf + - name: Create etcd data directory ansible.builtin.file: path: "{{ etcd_data_dir }}" @@ -128,7 +136,12 @@ - name: Wait until the etcd cluster is healthy ansible.builtin.command: > /usr/local/bin/etcdctl endpoint health - --endpoints=http://{{ inventory_hostname }}:2379 + --endpoints={% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ inventory_hostname }}:2379 + {% if tls_cert_generate | bool %} + --cacert=/etc/etcd/ca.crt + --cert=/etc/etcd/server.crt + --key=/etc/etcd/server.key + {% endif %} environment: ETCDCTL_API: "3" register: etcd_health_result diff --git a/automation/roles/etcd/templates/etcd.conf.j2 b/automation/roles/etcd/templates/etcd.conf.j2 index 0aa568c4a..de1aea647 100644 --- a/automation/roles/etcd/templates/etcd.conf.j2 +++ b/automation/roles/etcd/templates/etcd.conf.j2 @@ -1,13 +1,24 @@ ETCD_NAME="{{ ansible_hostname }}" -ETCD_LISTEN_CLIENT_URLS="http://{{ inventory_hostname }}:2379,http://127.0.0.1:2379" -ETCD_ADVERTISE_CLIENT_URLS="http://{{ inventory_hostname }}:2379" -ETCD_LISTEN_PEER_URLS="http://{{ inventory_hostname }}:2380" -ETCD_INITIAL_ADVERTISE_PEER_URLS="http://{{ inventory_hostname }}:2380" +ETCD_LISTEN_CLIENT_URLS="{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ inventory_hostname }}:2379,{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://127.0.0.1:2379" +ETCD_ADVERTISE_CLIENT_URLS="{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ inventory_hostname }}:2379" +ETCD_LISTEN_PEER_URLS="{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ inventory_hostname }}:2380" +ETCD_INITIAL_ADVERTISE_PEER_URLS="{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ inventory_hostname }}:2380" ETCD_INITIAL_CLUSTER_TOKEN="{{ etcd_cluster_name }}" -ETCD_INITIAL_CLUSTER="{% for host in groups['etcd_cluster'] %}{{ hostvars[host]['ansible_hostname'] }}=http://{{ hostvars[host]['inventory_hostname'] }}:2380{% if not loop.last %},{% endif %}{% endfor %}" +ETCD_INITIAL_CLUSTER="{% for host in groups['etcd_cluster'] %}{{ hostvars[host]['ansible_hostname'] }}={% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ hostvars[host]['inventory_hostname'] }}:2380{% if not loop.last %},{% endif %}{% endfor %}" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_DATA_DIR="{{ etcd_data_dir }}" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_INITIAL_ELECTION_TICK_ADVANCE="false" ETCD_AUTO_COMPACTION_RETENTION="1" +{% if tls_cert_generate | bool %} +ETCD_CERT_FILE="{{ tls_etcd_cert_path }}" +ETCD_KEY_FILE="{{ tls_etcd_privatekey_path }}" +ETCD_TRUSTED_CA_FILE="{{ tls_etcd_ca_cert_path }}" +ETCD_PEER_CERT_FILE="{{ tls_etcd_cert_path }}" +ETCD_PEER_KEY_FILE="{{ tls_etcd_privatekey_path }}" +ETCD_PEER_TRUSTED_CA_FILE="{{ tls_etcd_ca_cert_path }}" +ETCD_PEER_CLIENT_CERT_AUTH="true" +ETCD_CLIENT_CERT_AUTH="true" +ETCD_TLS_MIN_VERSION="TLS1.2" +{% endif %} diff --git a/automation/roles/patroni/templates/patroni.yml.j2 b/automation/roles/patroni/templates/patroni.yml.j2 index 011165ac3..241c5ed5a 100644 --- a/automation/roles/patroni/templates/patroni.yml.j2 +++ b/automation/roles/patroni/templates/patroni.yml.j2 @@ -38,20 +38,32 @@ restapi: {% if not dcs_exists|bool and dcs_type == 'etcd' %} etcd3: hosts: {% for host in groups['etcd_cluster'] %}{{ hostvars[host]['inventory_hostname'] }}:2379{% if not loop.last %},{% endif %}{% endfor %} + + {% if tls_cert_generate | bool %} + protocol: https + cacert: {{ tls_ca_cert_path | default('/etc/tls/ca.crt') }} + cert: {{ tls_cert_path | default('/etc/tls/server.crt') }} + key: {{ tls_privatekey_path | default('/etc/tls/server.key') }} + {% endif %} {% endif %} + {% if dcs_exists|bool and dcs_type == 'etcd' %} etcd3: hosts: {% for etcd_hosts in patroni_etcd_hosts %}{{etcd_hosts.host}}:{{etcd_hosts.port}}{% if not loop.last %},{% endif %}{% endfor %} + {% if tls_cert_generate | bool %} + protocol: https + cacert: {{ tls_ca_cert_path | default('/etc/tls/ca.crt') }} + cert: {{ tls_cert_path | default('/etc/tls/server.crt') }} + key: {{ tls_privatekey_path | default('/etc/tls/server.key') }} + {% endif %} + {% if patroni_etcd_username | default('') | length > 0 %} username: {{ patroni_etcd_username | default('') }} {% endif %} {% if patroni_etcd_password | default('') | length > 0 %} password: {{ patroni_etcd_password }} {% endif %} - {% if patroni_etcd_protocol | default('') | length > 0 %} - protocol: {{ patroni_etcd_protocol }} - {% endif %} {% endif %} {% if dcs_type == 'consul' %} diff --git a/automation/roles/patroni/templates/pg_hba.conf.j2 b/automation/roles/patroni/templates/pg_hba.conf.j2 index f3be1883a..8c1adaa03 100644 --- a/automation/roles/patroni/templates/pg_hba.conf.j2 +++ b/automation/roles/patroni/templates/pg_hba.conf.j2 @@ -85,14 +85,14 @@ # TYPE DATABASE USER ADDRESS METHOD {% for client in postgresql_pg_hba %} - {{ client.type.ljust(10) |default('host') }}{{ client.database.ljust(25) |default('all') }}{{ client.user.ljust(25) |default('all') }}{{ client.address.ljust(25) |default('') }}{{ client.method |default('md5') }} {{ client.options |default(None) }} + {{ client.type.ljust(10) |default('{% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %}') }}{{ client.database.ljust(25) |default('all') }}{{ client.user.ljust(25) |default('all') }}{{ client.address.ljust(25) |default('') }}{{ client.method |default('md5') }} {{ client.options |default(None) }} {% endfor %} {% for patroni in groups['postgres_cluster'] %} - host all all {{ hostvars[patroni]['inventory_hostname'] }}/32 {{ postgresql_password_encryption_algorithm }} + {% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %} all all {{ hostvars[patroni]['inventory_hostname'] }}/32 {{ postgresql_password_encryption_algorithm }} {% endfor %} # Allow replication connections from localhost, by a user with the # replication privilege. - host replication {{ patroni_replication_username }} localhost trust + {% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %} replication {{ patroni_replication_username }} localhost trust {% for host in groups['postgres_cluster'] %} - host replication {{ patroni_replication_username }} {{ hostvars[host]['inventory_hostname'] }}/32 {{ postgresql_password_encryption_algorithm }} + {% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %} replication {{ patroni_replication_username }} {{ hostvars[host]['inventory_hostname'] }}/32 {{ postgresql_password_encryption_algorithm }} {% endfor %} diff --git a/automation/roles/pgbouncer/tasks/main.yml b/automation/roles/pgbouncer/tasks/main.yml index cd2fb08fe..ba4402e9f 100644 --- a/automation/roles/pgbouncer/tasks/main.yml +++ b/automation/roles/pgbouncer/tasks/main.yml @@ -36,6 +36,14 @@ mode: "0750" tags: pgbouncer_conf, pgbouncer +- name: Fetch PostgreSQL TLS certificate, key and CA from the master node + ansible.builtin.include_role: + name: ../roles/tls_certificate/copy + vars: + copy_for: "pg" + when: tls_cert_generate|bool + tags: pgbouncer_conf, pgbouncer + - name: Ensure log directory "{{ pgbouncer_log_dir }}" exist ansible.builtin.file: path: "{{ pgbouncer_log_dir }}" diff --git a/automation/roles/tls_certificate/copy/tasks/main.yml b/automation/roles/tls_certificate/copy/tasks/main.yml index a0038ecc4..fe8c05448 100644 --- a/automation/roles/tls_certificate/copy/tasks/main.yml +++ b/automation/roles/tls_certificate/copy/tasks/main.yml @@ -1,42 +1,53 @@ --- -# for add_pgnode.yml - -- name: Ensure TLS directories exist - ansible.builtin.file: - path: "{{ item | dirname }}" - state: directory - owner: "{{ tls_owner | default('postgres') }}" - group: "{{ tls_owner | default('postgres') }}" - mode: "0750" - loop: - - "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" - - "{{ tls_cert_path | default('/etc/tls/server.crt') }}" - -- name: Fetch TLS certificate and key from master +- name: Fetch TLS certificate, key and CA from the master node into memory run_once: true - ansible.builtin.fetch: + ansible.builtin.slurp: src: "{{ item }}" - dest: "files/tls/" - validate_checksum: true - flat: true delegate_to: "{{ groups.master[0] }}" + register: tls_files loop: - - "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" - - "{{ tls_cert_path | default('/etc/tls/server.crt') }}" + - "/etc/tls/server.key" + - "/etc/tls/server.crt" + - "/etc/tls/ca.crt" -- name: Copy TLS certificate and key to replica +- name: Copy etcd TLS certificate, key and CA to all nodes from memory ansible.builtin.copy: - src: "files/tls/{{ item.path | basename }}" + content: "{{ tls_files.results[item.index].content | b64decode }}" dest: "{{ item.path }}" - owner: "{{ tls_owner | default('postgres') }}" - group: "{{ tls_owner | default('postgres') }}" + owner: "etcd" + group: "etcd" mode: "{{ item.mode }}" loop: - - { path: "{{ tls_privatekey_path | default('/etc/tls/server.key') }}", mode: "{{ tls_privatekey_mode | default('0400') }}" } - - { path: "{{ tls_cert_path | default('/etc/tls/server.crt') }}", mode: "{{ tls_cert_mode | default('0644') }}" } + - { index: 0, path: "{{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }}", mode: "0400" } + - { index: 1, path: "{{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }}", mode: "0644" } + - { index: 2, path: "{{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }}", mode: "0644" } + when: copy_for == 'etcd' + +- block: + - name: Create directory {{ tls_privatekey_path | dirname }} + ansible.builtin.file: + dest: "{{ tls_privatekey_path | dirname }}" + state: directory + owner: "{{ tls_owner }}" + group: "{{ tls_owner }}" + mode: "0755" + + - name: Copy PostgreSQL TLS certificate, key and CA to all nodes + ansible.builtin.copy: + content: "{{ tls_files.results[item.index].content | b64decode }}" + dest: "{{ item.path }}" + owner: "{{ tls_owner }}" + group: "{{ tls_owner }}" + mode: "{{ item.mode }}" + loop: + - { index: 0, path: "{{ tls_privatekey_path | default('/etc/tls/server.key') }}", mode: "0400" } + - { index: 1, path: "{{ tls_cert_path | default('/etc/tls/server.crt') }}", mode: "0644" } + - { index: 2, path: "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}", mode: "0644" } -- name: Delete TLS certificate and key from the ansible controller - ansible.builtin.file: - path: "files/tls/" - state: absent - delegate_to: localhost + - name: Delete TLS certificate and key from the ansible controller + ansible.builtin.file: + path: "files/tls/" + state: absent + delegate_to: localhost + run_once: true + when: copy_for == 'pg' diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml new file mode 100644 index 000000000..4c99cb60d --- /dev/null +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -0,0 +1,109 @@ +--- +- name: "Clean up existing certificates" + ansible.builtin.file: + path: "{{ item }}" + state: absent + loop: + - "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" + - "{{ tls_cert_path | default('/etc/tls/server.crt') }}" + - "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}" + - "{{ tls_ca_privatekey_path | default('/etc/tls/ca.key') }}" + - "{{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }}" + - "{{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }}" + - "{{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }}" + - "/etc/tls" + +- ansible.builtin.set_fact: + all_san_entries: [] + +- name: "Gather host-specific network information" + ansible.builtin.set_fact: + san_entry: >- + DNS:{{ ansible_hostname }},DNS:{{ ansible_fqdn }},IP:{{ ansible_default_ipv4.address }} + +- block: + - name: "Aggregate all subjectAltName entries" + ansible.builtin.set_fact: + all_san_entries: "{{ all_san_entries + [hostvars[item].san_entry] }}" + with_items: "{{ ansible_play_hosts }}" + + - name: "Join subjectAltName entries into a single string" + ansible.builtin.set_fact: + subject_alt_name: "{{ all_san_entries | join(',') + ',DNS:localhost,IP:127.0.0.1' }}" + when: ansible_play_hosts | length > 1 + + - name: "Display Certificate subjectAltName future value" + ansible.builtin.debug: + var: subject_alt_name + +######## Generate CA ######## + - name: "Ensure TLS directory exist" + ansible.builtin.file: + path: "/etc/tls" + state: directory + mode: "0700" + + - name: "Generate CA private key" + community.crypto.openssl_privatekey: + path: "/etc/tls/ca.key" + size: "{{ tls_privatekey_size | default(4096) }}" + type: "{{ tls_privatekey_type | default('RSA') }}" + + - name: "Create CSR for CA certificate" + community.crypto.openssl_csr_pipe: + privatekey_path: "/etc/tls/ca.key" + common_name: PostgreSQL CA + use_common_name_for_san: false + basic_constraints: + - 'CA:TRUE' + basic_constraints_critical: true + key_usage: + - keyCertSign + key_usage_critical: true + register: ca_csr + + - name: "Create self-signed CA certificate from CSR" + community.crypto.x509_certificate: + path: "/etc/tls/ca.crt" + csr_content: "{{ ca_csr.csr }}" + privatekey_path: "/etc/tls/ca.key" + provider: "{{ tls_cert_provider | default('selfsigned') }}" + entrust_not_after: "+{{ tls_cert_valid_days | default(3650) }}d" + +######## Generate Server cert/key ######## + - name: "Create server private key" + community.crypto.openssl_privatekey: + path: "/etc/tls/server.key" + size: "{{ tls_privatekey_size | default(4096) }}" + type: "{{ tls_privatekey_type | default('RSA') }}" + + - name: "Create server CSR" + community.crypto.openssl_csr_pipe: + privatekey_path: "/etc/tls/server.key" + common_name: postgresql.cluster + key_usage: + - digitalSignature + - keyEncipherment + - dataEncipherment + extended_key_usage: + - clientAuth + - serverAuth + subject_alt_name: "{{ subject_alt_name }}" + register: csr + + - name: "Sign server certificate with the CA" + community.crypto.x509_certificate_pipe: + csr_content: "{{ csr.csr }}" + provider: ownca + ownca_path: "/etc/tls/ca.crt" + ownca_privatekey_path: "/etc/tls/ca.key" + ownca_not_after: +3650d + ownca_not_before: "-1d" + register: certificate + + - name: "Write server certificate" + ansible.builtin.copy: + dest: "/etc/tls/server.crt" + content: "{{ certificate.certificate }}" + delegate_to: "{{ groups.master[0] }}" + run_once: true diff --git a/automation/roles/tls_certificate/tasks/main.yml b/automation/roles/tls_certificate/tasks/main.yml deleted file mode 100644 index 07ee54dd1..000000000 --- a/automation/roles/tls_certificate/tasks/main.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- -- name: Ensure TLS directories exist - ansible.builtin.file: - path: "{{ item | dirname }}" - state: directory - owner: "{{ tls_owner | default('postgres') }}" - group: "{{ tls_owner | default('postgres') }}" - mode: "0750" - loop: - - "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" - - "{{ tls_cert_path | default('/etc/tls/server.crt') }}" - -- name: "Generate private TLS key {{ tls_privatekey_path | default('/etc/tls/server.key') }}" - community.crypto.openssl_privatekey: - path: "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" - owner: "{{ tls_owner | default('postgres') }}" - group: "{{ tls_owner | default('postgres') }}" - mode: "{{ tls_privatekey_mode | default('0400') }}" - size: "{{ tls_privatekey_size | default(4096) }}" - type: "{{ tls_privatekey_type | default('RSA') }}" - -- name: "Generate self-signed TLS certificate {{ tls_cert_path | default('/etc/tls/server.crt') }}" - community.crypto.x509_certificate: - path: "{{ tls_cert_path | default('/etc/tls/server.crt') }}" - privatekey_path: "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" - owner: "{{ tls_owner | default('postgres') }}" - group: "{{ tls_owner | default('postgres') }}" - mode: "{{ tls_cert_mode | default('0644') }}" - provider: "{{ tls_cert_provider | default('selfsigned') }}" - entrust_not_after: "+{{ tls_cert_valid_days | default(3650) }}d" diff --git a/automation/roles/vip-manager/templates/vip-manager.yml.j2 b/automation/roles/vip-manager/templates/vip-manager.yml.j2 index ded0bd395..4222d79e8 100644 --- a/automation/roles/vip-manager/templates/vip-manager.yml.j2 +++ b/automation/roles/vip-manager/templates/vip-manager.yml.j2 @@ -27,12 +27,12 @@ dcs-type: {{ vip_manager_dcs_type | default(dcs_type) }} # etcd, consul or patro {% if not dcs_exists | bool %} dcs-endpoints: {% for host in groups['etcd_cluster'] %} - - http://{{ hostvars[host]['inventory_hostname'] }}:2379 + - {% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ hostvars[host]['inventory_hostname'] }}:2379 {% endfor %} {% else %} dcs-endpoints: {% for etcd_hosts in patroni_etcd_hosts %} - - {{ patroni_etcd_protocol | default('http', true) }}://{{ etcd_hosts.host }}:{{ etcd_hosts.port }} + - {% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ etcd_hosts.host }}:{{ etcd_hosts.port }} {% endfor %} {% endif %} {% endif %} @@ -64,16 +64,16 @@ etcd-user: {{ patroni_etcd_username | default("") }} {% if patroni_etcd_password | default("") | length > 0 %} etcd-password: {{ patroni_etcd_password | default("") }} {% endif %} -{% if patroni_etcd_ca_file | default("") | length > 0 %} +{% if tls_cert_generate | bool %} # when etcd-ca-file is specified, TLS connections to the etcd endpoints will be used. -etcd-ca-file: {{ patroni_etcd_ca_file | default("") }} +etcd-ca-file: {{ tls_ca_cert_path | default('/etc/tls/ca.crt') }} {% endif %} -{% if patroni_etcd_cert_file | default("") | length > 0 %} +{% if tls_cert_generate | bool %} # when etcd-cert-file and etcd-key-file are specified, we will authenticate at the etcd endpoints using this certificate and key. -etcd-cert-file: {{ patroni_etcd_cert_file | default("") }} +etcd-cert-file: {{ tls_cert_path | default('/etc/tls/server.crt') }} {% endif %} -{% if patroni_etcd_key_file | default("") | length > 0 %} -etcd-key-file: {{ patroni_etcd_key_file | default("") }} +{% if tls_cert_generate | bool %} +etcd-key-file: {{ tls_privatekey_path | default('/etc/tls/server.key') }} {% endif %} {% endif %} diff --git a/automation/vars/Debian.yml b/automation/vars/Debian.yml index 4f1ea629b..5e2d99900 100644 --- a/automation/vars/Debian.yml +++ b/automation/vars/Debian.yml @@ -40,7 +40,6 @@ system_packages: - python3-psycopg2 - python3-setuptools - python3-pip - - python3-cryptography - curl - less - sudo diff --git a/automation/vars/RedHat.yml b/automation/vars/RedHat.yml index 86fb6be98..46e158bcc 100644 --- a/automation/vars/RedHat.yml +++ b/automation/vars/RedHat.yml @@ -60,7 +60,6 @@ system_packages: - python{{ python_version }}-setuptools - python{{ python_version }}-pip - python{{ python_version }}-urllib3 - - python3-cryptography - less - sudo - vim diff --git a/automation/vars/main.yml b/automation/vars/main.yml index e8fa0c4fc..bb187268a 100644 --- a/automation/vars/main.yml +++ b/automation/vars/main.yml @@ -104,7 +104,7 @@ patroni_etcd_hosts: [] # list of servers of an existing etcd cluster patroni_etcd_namespace: "service" # (optional) etcd namespace (prefix) patroni_etcd_username: "" # (optional) username for etcd authentication patroni_etcd_password: "" # (optional) password for etcd authentication -patroni_etcd_protocol: "" # (optional) http or https, if not specified http is used +patroni_etcd_protocol: "https" # (optional) http or https, if not specified http is used # more options you can specify in the roles/patroni/templates/patroni.yml.j2 # https://patroni.readthedocs.io/en/latest/yaml_configuration.html#etcd @@ -174,12 +174,16 @@ consul_services: # - { http: "http://{{ inventory_hostname }}:{{ patroni_restapi_port }}/async?lag={{ patroni_maximum_lag_on_replica }}", interval: "2s" } # - { args: ["systemctl", "status", "pgbouncer"], interval: "5s" } -# TLS certificate (for PostgreSQL & PgBouncer) +# TLS certificate (for PostgreSQL, PgBouncer and etcd) tls_cert_generate: true tls_cert_valid_days: 3650 tls_cert_path: "{{ postgresql_home_dir }}/tls/server.crt" tls_privatekey_path: "{{ postgresql_home_dir }}/tls/server.key" +tls_ca_cert_path: "{{ postgresql_home_dir }}/tls/ca.crt" tls_owner: "postgres" +tls_etcd_cert_path: "/etc/etcd/server.crt" +tls_etcd_ca_cert_path: "/etc/etcd/ca.crt" +tls_etcd_privatekey_path: "/etc/etcd/server.key" # PostgreSQL variables postgresql_version: 17 @@ -241,9 +245,11 @@ postgresql_parameters: - { option: "max_connections", value: "1000" } - { option: "superuser_reserved_connections", value: "5" } - { option: "password_encryption", value: "{{ postgresql_password_encryption_algorithm }}" } - - { option: "ssl", value: "on"} - - { option: "ssl_cert_file", value: "{{ tls_cert_path }}"} - - { option: "ssl_key_file", value: "{{ tls_privatekey_path }}"} + - { option: "ssl", value: "{% if tls_cert_generate | bool %}on{% else %}off{% endif %}"} + - { option: "ssl_prefer_server_ciphers", value: "{% if tls_cert_generate | bool %}on{% else %}off{% endif %}"} + - { option: "ssl_cert_file", value: "{{ tls_cert_path | default('') }}"} + - { option: "ssl_key_file", value: "{{ tls_privatekey_path | default('') }}"} + - { option: "ssl_ca_file", value: "{{ tls_ca_cert_path | default('') }}"} - { option: "ssl_min_protocol_version", value: "TLSv1.2"} - { option: "max_locks_per_transaction", value: "512" } - { option: "max_prepared_transactions", value: "0" } @@ -338,9 +344,9 @@ postgresql_pg_hba: - { type: "local", database: "all", user: "all", address: "", method: "{{ postgresql_password_encryption_algorithm }}" } - { type: "host", database: "all", user: "all", address: "127.0.0.1/32", method: "{{ postgresql_password_encryption_algorithm }}" } - { type: "host", database: "all", user: "all", address: "::1/128", method: "{{ postgresql_password_encryption_algorithm }}" } - - { type: "host", database: "all", user: "all", address: "0.0.0.0/0", method: "{{ postgresql_password_encryption_algorithm }}" } -# - { type: "host", database: "mydatabase", user: "mydb-user", address: "192.168.0.0/24", method: "{{ postgresql_password_encryption_algorithm }}" } -# - { type: "host", database: "all", user: "all", address: "192.168.0.0/24", method: "ident", options: "map=main" } # use pg_ident + - { type: "{% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %}", database: "all", user: "all", address: "0.0.0.0/0", method: "{{ postgresql_password_encryption_algorithm }}" } +# - { type: "{% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %}", database: "mydatabase", user: "mydb-user", address: "192.168.0.0/24", method: "{{ postgresql_password_encryption_algorithm }}" } +# - { type: "{% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %}", database: "all", user: "all", address: "192.168.0.0/24", method: "ident", options: "map=main" } # use pg_ident # list of lines that Patroni will use to generate pg_ident.conf postgresql_pg_ident: [] @@ -387,7 +393,7 @@ pgbouncer_server_tls_protocols: "secure" pgbouncer_server_tls_ciphers: "secure" pgbouncer_server_tls_cert_file: "{{ tls_cert_path }}" pgbouncer_server_tls_key_file: "{{ tls_privatekey_path }}" -pgbouncer_server_tls_ca_file: "" +pgbouncer_server_tls_ca_file: "{{ tls_ca_cert_path }}" pgbouncer_pools: - { name: "postgres", dbname: "postgres", pool_parameters: "" } From 1e74ad83140cf829bce090ebc63aa14c371ab5b1 Mon Sep 17 00:00:00 2001 From: klention Date: Sat, 21 Dec 2024 15:45:26 +0100 Subject: [PATCH 02/36] Brake the long lines into shorter ones --- automation/vars/main.yml | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/automation/vars/main.yml b/automation/vars/main.yml index bb187268a..4e4aa3ef5 100644 --- a/automation/vars/main.yml +++ b/automation/vars/main.yml @@ -344,11 +344,35 @@ postgresql_pg_hba: - { type: "local", database: "all", user: "all", address: "", method: "{{ postgresql_password_encryption_algorithm }}" } - { type: "host", database: "all", user: "all", address: "127.0.0.1/32", method: "{{ postgresql_password_encryption_algorithm }}" } - { type: "host", database: "all", user: "all", address: "::1/128", method: "{{ postgresql_password_encryption_algorithm }}" } - - { type: "{% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %}", database: "all", user: "all", address: "0.0.0.0/0", method: "{{ postgresql_password_encryption_algorithm }}" } -# - { type: "{% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %}", database: "mydatabase", user: "mydb-user", address: "192.168.0.0/24", method: "{{ postgresql_password_encryption_algorithm }}" } -# - { type: "{% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %}", database: "all", user: "all", address: "192.168.0.0/24", method: "ident", options: "map=main" } # use pg_ident - + - type: > + {% if tls_cert_generate | bool %}hostssl + {% else %}host + {% endif %} + database: "all" + user: "all" + address: "0.0.0.0/0" + method: "{{ postgresql_password_encryption_algorithm }}" + +# - type: > +# {% if tls_cert_generate | bool %}hostssl +# {% else %}host +# {% endif %} +# database: "mydatabase" +# user: "mydb-user" +# address: "192.168.0.0/24" +# method: "{{ postgresql_password_encryption_algorithm }}" + +# - type: > +# {% if tls_cert_generate | bool %}hostssl +# {% else %}host +# {% endif %} +# database: "all" +# user: "all" +# address: "192.168.0.0/24" +# method: "ident" +# options: "map=main" # use pg_ident # list of lines that Patroni will use to generate pg_ident.conf + postgresql_pg_ident: [] # - { mapname: "main", system_username: "postgres", pg_username: "backup" } # - { mapname: "", system_username: "", pg_username: "" } From 3a34ac1d1065c256150eb4bcb9751a28dfb9cb41 Mon Sep 17 00:00:00 2001 From: klention Date: Sat, 21 Dec 2024 18:00:13 +0100 Subject: [PATCH 03/36] Removed extra space from pg_hba/conf --- automation/roles/tls_certificate/copy/tasks/main.yml | 7 ------- automation/vars/main.yml | 6 +++--- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/automation/roles/tls_certificate/copy/tasks/main.yml b/automation/roles/tls_certificate/copy/tasks/main.yml index fe8c05448..3fad3ac28 100644 --- a/automation/roles/tls_certificate/copy/tasks/main.yml +++ b/automation/roles/tls_certificate/copy/tasks/main.yml @@ -43,11 +43,4 @@ - { index: 0, path: "{{ tls_privatekey_path | default('/etc/tls/server.key') }}", mode: "0400" } - { index: 1, path: "{{ tls_cert_path | default('/etc/tls/server.crt') }}", mode: "0644" } - { index: 2, path: "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}", mode: "0644" } - - - name: Delete TLS certificate and key from the ansible controller - ansible.builtin.file: - path: "files/tls/" - state: absent - delegate_to: localhost - run_once: true when: copy_for == 'pg' diff --git a/automation/vars/main.yml b/automation/vars/main.yml index 4e4aa3ef5..f66b447e4 100644 --- a/automation/vars/main.yml +++ b/automation/vars/main.yml @@ -344,7 +344,7 @@ postgresql_pg_hba: - { type: "local", database: "all", user: "all", address: "", method: "{{ postgresql_password_encryption_algorithm }}" } - { type: "host", database: "all", user: "all", address: "127.0.0.1/32", method: "{{ postgresql_password_encryption_algorithm }}" } - { type: "host", database: "all", user: "all", address: "::1/128", method: "{{ postgresql_password_encryption_algorithm }}" } - - type: > + - type: >- {% if tls_cert_generate | bool %}hostssl {% else %}host {% endif %} @@ -353,7 +353,7 @@ postgresql_pg_hba: address: "0.0.0.0/0" method: "{{ postgresql_password_encryption_algorithm }}" -# - type: > +# - type: >- # {% if tls_cert_generate | bool %}hostssl # {% else %}host # {% endif %} @@ -362,7 +362,7 @@ postgresql_pg_hba: # address: "192.168.0.0/24" # method: "{{ postgresql_password_encryption_algorithm }}" -# - type: > +# - type: >- # {% if tls_cert_generate | bool %}hostssl # {% else %}host # {% endif %} From e4b34d3ad89223ba4f20c18bdf10d133af7a866f Mon Sep 17 00:00:00 2001 From: klention Date: Sat, 21 Dec 2024 19:03:34 +0100 Subject: [PATCH 04/36] Updated etcd molecule test to check on different protocols --- automation/inventory | 24 ++++++++++++------------ automation/molecule/tests/etcd/etcd.yml | 9 +++++++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/automation/inventory b/automation/inventory index 17bbf3980..cc74e5278 100644 --- a/automation/inventory +++ b/automation/inventory @@ -11,33 +11,33 @@ # if dcs_exists: false and dcs_type: "etcd" [etcd_cluster] # recommendation: 3, or 5-7 nodes -#10.128.64.140 -#10.128.64.142 -#10.128.64.143 +10.16.16.209 +10.16.16.210 +10.16.16.211 # if dcs_exists: false and dcs_type: "consul" [consul_instances] # recommendation: 3 or 5-7 nodes -#10.128.64.140 consul_node_role=server consul_bootstrap_expect=true consul_datacenter=dc1 -#10.128.64.142 consul_node_role=server consul_bootstrap_expect=true consul_datacenter=dc1 -#10.128.64.143 consul_node_role=server consul_bootstrap_expect=true consul_datacenter=dc1 +10.16.16.209 consul_node_role=server consul_bootstrap_expect=true consul_datacenter=dc1 +10.16.16.210 consul_node_role=server consul_bootstrap_expect=true consul_datacenter=dc1 +10.16.16.211 consul_node_role=server consul_bootstrap_expect=true consul_datacenter=dc1 #10.128.64.144 consul_node_role=client consul_datacenter=dc2 #10.128.64.145 consul_node_role=client consul_datacenter=dc2 # if with_haproxy_load_balancing: true [balancers] -#10.128.64.140 # balancer_tags="datacenter=dc1" -#10.128.64.142 # balancer_tags="datacenter=dc1" -#10.128.64.143 # balancer_tags="datacenter=dc1" +10.16.16.209 # balancer_tags="datacenter=dc1" +10.16.16.210 # balancer_tags="datacenter=dc1" +10.16.16.211 # balancer_tags="datacenter=dc1" #10.128.64.144 balancer_tags="datacenter=dc2" #10.128.64.145 balancer_tags="datacenter=dc2" new_node=true # PostgreSQL nodes [master] -#10.128.64.140 hostname=pgnode01 postgresql_exists=false # patroni_tags="datacenter=dc1" +10.16.16.209 hostname=pgnode01 postgresql_exists=false # patroni_tags="datacenter=dc1" [replica] -#10.128.64.142 hostname=pgnode02 postgresql_exists=false # patroni_tags="datacenter=dc1" -#10.128.64.143 hostname=pgnode03 postgresql_exists=false # patroni_tags="datacenter=dc1" +10.16.16.210 hostname=pgnode02 postgresql_exists=false # patroni_tags="datacenter=dc1" +10.16.16.211 hostname=pgnode03 postgresql_exists=false # patroni_tags="datacenter=dc1" #10.128.64.144 hostname=pgnode04 postgresql_exists=false patroni_tags="datacenter=dc2" #10.128.64.145 hostname=pgnode04 postgresql_exists=false patroni_tags="datacenter=dc2" new_node=true diff --git a/automation/molecule/tests/etcd/etcd.yml b/automation/molecule/tests/etcd/etcd.yml index c564cabc6..83cd3684c 100644 --- a/automation/molecule/tests/etcd/etcd.yml +++ b/automation/molecule/tests/etcd/etcd.yml @@ -1,8 +1,13 @@ --- -- name: Check etcd health +- name: Check etcd health with TLS ansible.builtin.uri: - url: "http://{{ inventory_hostname }}:2379/health" + url: "{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ inventory_hostname }}:2379/health" + method: GET return_content: true + validate_certs: "{% if tls_cert_generate | bool %}true{% else %}false{% endif %}" + ca_path: "{% if tls_cert_generate | bool %}/var/lib/pgsql/tls/ca.crt{% else %}''{% endif %}" + client_cert: "{% if tls_cert_generate | bool %}/var/lib/pgsql/tls/server.crt{% else %}''{% endif %}" + client_key: "{% if tls_cert_generate | bool %}/var/lib/pgsql/tls/server.key{% else %}''{% endif %}" register: etcd_health_status failed_when: "(etcd_health_status.content | from_json).health != 'true'" when: dcs_type == "etcd" From 444cf7182a36e27c6c973a2d04a3bef62912d1b9 Mon Sep 17 00:00:00 2001 From: klention Date: Sat, 21 Dec 2024 19:49:37 +0100 Subject: [PATCH 05/36] Fetch machine IPs differently --- automation/roles/tls_certificate/generate/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml index 4c99cb60d..826eaf5d3 100644 --- a/automation/roles/tls_certificate/generate/tasks/main.yml +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -19,7 +19,7 @@ - name: "Gather host-specific network information" ansible.builtin.set_fact: san_entry: >- - DNS:{{ ansible_hostname }},DNS:{{ ansible_fqdn }},IP:{{ ansible_default_ipv4.address }} + DNS:{{ ansible_hostname }},DNS:{{ ansible_fqdn }},{% for p in ansible_facts.all_ipv4_addresses %}IP:{{ p }}{% if not loop.last %},{% endif %}{% endfor %} - block: - name: "Aggregate all subjectAltName entries" From da78fd716bee163d496225574e02ad926e971f86 Mon Sep 17 00:00:00 2001 From: klention Date: Sat, 21 Dec 2024 20:30:18 +0100 Subject: [PATCH 06/36] Fetch machine's IP from variable inventory_hostname --- automation/roles/tls_certificate/generate/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml index 826eaf5d3..06a3d58e7 100644 --- a/automation/roles/tls_certificate/generate/tasks/main.yml +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -19,7 +19,7 @@ - name: "Gather host-specific network information" ansible.builtin.set_fact: san_entry: >- - DNS:{{ ansible_hostname }},DNS:{{ ansible_fqdn }},{% for p in ansible_facts.all_ipv4_addresses %}IP:{{ p }}{% if not loop.last %},{% endif %}{% endfor %} + DNS:{{ ansible_hostname }},DNS:{{ ansible_fqdn }},IP:{{ inventory_hostname }} - block: - name: "Aggregate all subjectAltName entries" From c51523887becf2ae1d261cfcdd7726e32f6e8d0a Mon Sep 17 00:00:00 2001 From: klention Date: Sat, 21 Dec 2024 22:29:22 +0100 Subject: [PATCH 07/36] Set inventory file content to default --- automation/inventory | 26 ++++++++++++------------- automation/molecule/tests/etcd/etcd.yml | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/automation/inventory b/automation/inventory index cc74e5278..8c5e5dc67 100644 --- a/automation/inventory +++ b/automation/inventory @@ -11,33 +11,33 @@ # if dcs_exists: false and dcs_type: "etcd" [etcd_cluster] # recommendation: 3, or 5-7 nodes -10.16.16.209 -10.16.16.210 -10.16.16.211 +#10.128.64.140 +#10.128.64.142 +#10.128.64.143 # if dcs_exists: false and dcs_type: "consul" [consul_instances] # recommendation: 3 or 5-7 nodes -10.16.16.209 consul_node_role=server consul_bootstrap_expect=true consul_datacenter=dc1 -10.16.16.210 consul_node_role=server consul_bootstrap_expect=true consul_datacenter=dc1 -10.16.16.211 consul_node_role=server consul_bootstrap_expect=true consul_datacenter=dc1 +#10.128.64.140 consul_node_role=server consul_bootstrap_expect=true consul_datacenter=dc1 +#10.128.64.142 consul_node_role=server consul_bootstrap_expect=true consul_datacenter=dc1 +#10.128.64.143 consul_node_role=server consul_bootstrap_expect=true consul_datacenter=dc1 #10.128.64.144 consul_node_role=client consul_datacenter=dc2 #10.128.64.145 consul_node_role=client consul_datacenter=dc2 # if with_haproxy_load_balancing: true [balancers] -10.16.16.209 # balancer_tags="datacenter=dc1" -10.16.16.210 # balancer_tags="datacenter=dc1" -10.16.16.211 # balancer_tags="datacenter=dc1" +#10.128.64.140 # balancer_tags="datacenter=dc1" +#10.128.64.142 # balancer_tags="datacenter=dc1" +#10.128.64.143 # balancer_tags="datacenter=dc1" #10.128.64.144 balancer_tags="datacenter=dc2" #10.128.64.145 balancer_tags="datacenter=dc2" new_node=true # PostgreSQL nodes [master] -10.16.16.209 hostname=pgnode01 postgresql_exists=false # patroni_tags="datacenter=dc1" +#10.128.64.140 hostname=pgnode01 postgresql_exists=false # patroni_tags="datacenter=dc1" [replica] -10.16.16.210 hostname=pgnode02 postgresql_exists=false # patroni_tags="datacenter=dc1" -10.16.16.211 hostname=pgnode03 postgresql_exists=false # patroni_tags="datacenter=dc1" +#10.128.64.142 hostname=pgnode02 postgresql_exists=false # patroni_tags="datacenter=dc1" +#10.128.64.143 hostname=pgnode03 postgresql_exists=false # patroni_tags="datacenter=dc1" #10.128.64.144 hostname=pgnode04 postgresql_exists=false patroni_tags="datacenter=dc2" #10.128.64.145 hostname=pgnode04 postgresql_exists=false patroni_tags="datacenter=dc2" new_node=true @@ -60,4 +60,4 @@ ansible_ssh_port='22' #ansible_user='root' #ansible_ssh_pass='secretpassword' # "sshpass" package is required for use "ansible_ssh_pass" #ansible_ssh_private_key_file= -#ansible_python_interpreter='/usr/bin/python3' +#ansible_python_interpreter='/usr/bin/python3' \ No newline at end of file diff --git a/automation/molecule/tests/etcd/etcd.yml b/automation/molecule/tests/etcd/etcd.yml index 83cd3684c..749db9186 100644 --- a/automation/molecule/tests/etcd/etcd.yml +++ b/automation/molecule/tests/etcd/etcd.yml @@ -1,5 +1,5 @@ --- -- name: Check etcd health with TLS +- name: Check etcd health ansible.builtin.uri: url: "{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ inventory_hostname }}:2379/health" method: GET From d99b1eacdd43b7ffaa93883e146ce36711e7f104 Mon Sep 17 00:00:00 2001 From: klention Date: Sun, 22 Dec 2024 14:15:15 +0100 Subject: [PATCH 08/36] Updated etcd certificate path on molecule tests --- automation/molecule/tests/etcd/etcd.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/automation/molecule/tests/etcd/etcd.yml b/automation/molecule/tests/etcd/etcd.yml index 749db9186..ea7d41ab4 100644 --- a/automation/molecule/tests/etcd/etcd.yml +++ b/automation/molecule/tests/etcd/etcd.yml @@ -5,9 +5,9 @@ method: GET return_content: true validate_certs: "{% if tls_cert_generate | bool %}true{% else %}false{% endif %}" - ca_path: "{% if tls_cert_generate | bool %}/var/lib/pgsql/tls/ca.crt{% else %}''{% endif %}" - client_cert: "{% if tls_cert_generate | bool %}/var/lib/pgsql/tls/server.crt{% else %}''{% endif %}" - client_key: "{% if tls_cert_generate | bool %}/var/lib/pgsql/tls/server.key{% else %}''{% endif %}" + ca_path: "{% if tls_cert_generate | bool %}{{ tls_etcd_ca_cert_path }}{% else %}''{% endif %}" + client_cert: "{% if tls_cert_generate | bool %}{{ tls_etcd_cert_path }}{% else %}''{% endif %}" + client_key: "{% if tls_cert_generate | bool %}{{ tls_etcd_privatekey_path }}{% else %}''{% endif %}" register: etcd_health_status failed_when: "(etcd_health_status.content | from_json).health != 'true'" when: dcs_type == "etcd" From f60b26b394d6a284ad9773cff147f1663f76438f Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Mon, 23 Dec 2024 15:53:13 +0500 Subject: [PATCH 09/36] Update inventory --- automation/inventory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automation/inventory b/automation/inventory index 8c5e5dc67..17bbf3980 100644 --- a/automation/inventory +++ b/automation/inventory @@ -60,4 +60,4 @@ ansible_ssh_port='22' #ansible_user='root' #ansible_ssh_pass='secretpassword' # "sshpass" package is required for use "ansible_ssh_pass" #ansible_ssh_private_key_file= -#ansible_python_interpreter='/usr/bin/python3' \ No newline at end of file +#ansible_python_interpreter='/usr/bin/python3' From 2901a028645f5309e52f93518409fd686b57a1c4 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Mon, 23 Dec 2024 16:04:52 +0500 Subject: [PATCH 10/36] Use patroni_etcd_protocol variable --- automation/molecule/tests/etcd/etcd.yml | 2 +- automation/roles/confd/templates/confd.toml.j2 | 4 ++-- automation/roles/etcd/tasks/main.yml | 2 +- automation/roles/etcd/templates/etcd.conf.j2 | 10 +++++----- .../roles/vip-manager/templates/vip-manager.yml.j2 | 4 ++-- automation/vars/main.yml | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/automation/molecule/tests/etcd/etcd.yml b/automation/molecule/tests/etcd/etcd.yml index ea7d41ab4..f94fe69da 100644 --- a/automation/molecule/tests/etcd/etcd.yml +++ b/automation/molecule/tests/etcd/etcd.yml @@ -1,7 +1,7 @@ --- - name: Check etcd health ansible.builtin.uri: - url: "{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ inventory_hostname }}:2379/health" + url: "{{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2379/health" method: GET return_content: true validate_certs: "{% if tls_cert_generate | bool %}true{% else %}false{% endif %}" diff --git a/automation/roles/confd/templates/confd.toml.j2 b/automation/roles/confd/templates/confd.toml.j2 index d9ee0f0da..add558254 100644 --- a/automation/roles/confd/templates/confd.toml.j2 +++ b/automation/roles/confd/templates/confd.toml.j2 @@ -4,12 +4,12 @@ watch = true nodes = [ {% if not dcs_exists|bool and dcs_type == 'etcd' %} {% for host in groups['etcd_cluster'] %} - "{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ hostvars[host]['inventory_hostname'] }}:2379", + "{{ patroni_etcd_protocol }}://{{ hostvars[host]['inventory_hostname'] }}:2379", {% endfor %} {% endif %} {% if dcs_exists|bool and dcs_type == 'etcd' %} {% for etcd_hosts in patroni_etcd_hosts %} - "{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{etcd_hosts.host}}:{{etcd_hosts.port}}", + "{{ patroni_etcd_protocol }}://{{etcd_hosts.host}}:{{etcd_hosts.port}}", {% endfor %} {% endif %} ] diff --git a/automation/roles/etcd/tasks/main.yml b/automation/roles/etcd/tasks/main.yml index c20e58a09..2933b7402 100644 --- a/automation/roles/etcd/tasks/main.yml +++ b/automation/roles/etcd/tasks/main.yml @@ -136,7 +136,7 @@ - name: Wait until the etcd cluster is healthy ansible.builtin.command: > /usr/local/bin/etcdctl endpoint health - --endpoints={% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ inventory_hostname }}:2379 + --endpoints={{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2379 {% if tls_cert_generate | bool %} --cacert=/etc/etcd/ca.crt --cert=/etc/etcd/server.crt diff --git a/automation/roles/etcd/templates/etcd.conf.j2 b/automation/roles/etcd/templates/etcd.conf.j2 index de1aea647..ada454ef1 100644 --- a/automation/roles/etcd/templates/etcd.conf.j2 +++ b/automation/roles/etcd/templates/etcd.conf.j2 @@ -1,10 +1,10 @@ ETCD_NAME="{{ ansible_hostname }}" -ETCD_LISTEN_CLIENT_URLS="{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ inventory_hostname }}:2379,{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://127.0.0.1:2379" -ETCD_ADVERTISE_CLIENT_URLS="{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ inventory_hostname }}:2379" -ETCD_LISTEN_PEER_URLS="{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ inventory_hostname }}:2380" -ETCD_INITIAL_ADVERTISE_PEER_URLS="{% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ inventory_hostname }}:2380" +ETCD_LISTEN_CLIENT_URLS="{{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2379,{{ patroni_etcd_protocol }}://127.0.0.1:2379" +ETCD_ADVERTISE_CLIENT_URLS="{{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2379" +ETCD_LISTEN_PEER_URLS="{{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2380" +ETCD_INITIAL_ADVERTISE_PEER_URLS="{{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2380" ETCD_INITIAL_CLUSTER_TOKEN="{{ etcd_cluster_name }}" -ETCD_INITIAL_CLUSTER="{% for host in groups['etcd_cluster'] %}{{ hostvars[host]['ansible_hostname'] }}={% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ hostvars[host]['inventory_hostname'] }}:2380{% if not loop.last %},{% endif %}{% endfor %}" +ETCD_INITIAL_CLUSTER="{% for host in groups['etcd_cluster'] %}{{ hostvars[host]['ansible_hostname'] }}={{ patroni_etcd_protocol }}://{{ hostvars[host]['inventory_hostname'] }}:2380{% if not loop.last %},{% endif %}{% endfor %}" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_DATA_DIR="{{ etcd_data_dir }}" ETCD_ELECTION_TIMEOUT="5000" diff --git a/automation/roles/vip-manager/templates/vip-manager.yml.j2 b/automation/roles/vip-manager/templates/vip-manager.yml.j2 index 4222d79e8..ca02f929a 100644 --- a/automation/roles/vip-manager/templates/vip-manager.yml.j2 +++ b/automation/roles/vip-manager/templates/vip-manager.yml.j2 @@ -27,12 +27,12 @@ dcs-type: {{ vip_manager_dcs_type | default(dcs_type) }} # etcd, consul or patro {% if not dcs_exists | bool %} dcs-endpoints: {% for host in groups['etcd_cluster'] %} - - {% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ hostvars[host]['inventory_hostname'] }}:2379 + - {{ patroni_etcd_protocol }}://{{ hostvars[host]['inventory_hostname'] }}:2379 {% endfor %} {% else %} dcs-endpoints: {% for etcd_hosts in patroni_etcd_hosts %} - - {% if tls_cert_generate | bool %}https{% else %}http{% endif %}://{{ etcd_hosts.host }}:{{ etcd_hosts.port }} + - {{ patroni_etcd_protocol }}://{{ etcd_hosts.host }}:{{ etcd_hosts.port }} {% endfor %} {% endif %} {% endif %} diff --git a/automation/vars/main.yml b/automation/vars/main.yml index f66b447e4..3ee237689 100644 --- a/automation/vars/main.yml +++ b/automation/vars/main.yml @@ -104,7 +104,7 @@ patroni_etcd_hosts: [] # list of servers of an existing etcd cluster patroni_etcd_namespace: "service" # (optional) etcd namespace (prefix) patroni_etcd_username: "" # (optional) username for etcd authentication patroni_etcd_password: "" # (optional) password for etcd authentication -patroni_etcd_protocol: "https" # (optional) http or https, if not specified http is used +patroni_etcd_protocol: "{{ 'https' if tls_cert_generate | bool else 'http' }}" # more options you can specify in the roles/patroni/templates/patroni.yml.j2 # https://patroni.readthedocs.io/en/latest/yaml_configuration.html#etcd From f13c39ae1648cf04d767ad0b6d63f99bb66e934b Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Mon, 23 Dec 2024 16:07:55 +0500 Subject: [PATCH 11/36] Use 'default(omit)' to skip the parameter if it is not defined --- automation/molecule/tests/etcd/etcd.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/automation/molecule/tests/etcd/etcd.yml b/automation/molecule/tests/etcd/etcd.yml index f94fe69da..ac64b101c 100644 --- a/automation/molecule/tests/etcd/etcd.yml +++ b/automation/molecule/tests/etcd/etcd.yml @@ -4,10 +4,10 @@ url: "{{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2379/health" method: GET return_content: true - validate_certs: "{% if tls_cert_generate | bool %}true{% else %}false{% endif %}" - ca_path: "{% if tls_cert_generate | bool %}{{ tls_etcd_ca_cert_path }}{% else %}''{% endif %}" - client_cert: "{% if tls_cert_generate | bool %}{{ tls_etcd_cert_path }}{% else %}''{% endif %}" - client_key: "{% if tls_cert_generate | bool %}{{ tls_etcd_privatekey_path }}{% else %}''{% endif %}" + validate_certs: "{{ tls_cert_generate | bool }}" + ca_path: "{{ tls_etcd_ca_cert_path | default(omit) }}" + client_cert: "{{ tls_etcd_cert_path | default(omit) }}" + client_key: "{{ tls_etcd_privatekey_path | default(omit) }}" register: etcd_health_status failed_when: "(etcd_health_status.content | from_json).health != 'true'" when: dcs_type == "etcd" From decadb798fa8dcf6eac08d302c0e65fe56e072e2 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Mon, 23 Dec 2024 16:11:15 +0500 Subject: [PATCH 12/36] Update etcd.yml --- automation/molecule/tests/etcd/etcd.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/automation/molecule/tests/etcd/etcd.yml b/automation/molecule/tests/etcd/etcd.yml index ac64b101c..c37599fd6 100644 --- a/automation/molecule/tests/etcd/etcd.yml +++ b/automation/molecule/tests/etcd/etcd.yml @@ -5,9 +5,9 @@ method: GET return_content: true validate_certs: "{{ tls_cert_generate | bool }}" - ca_path: "{{ tls_etcd_ca_cert_path | default(omit) }}" - client_cert: "{{ tls_etcd_cert_path | default(omit) }}" - client_key: "{{ tls_etcd_privatekey_path | default(omit) }}" + ca_path: "{{ tls_etcd_ca_cert_path if tls_cert_generate | bool else omit }}" + client_cert: "{{ tls_etcd_cert_path if tls_cert_generate | bool else omit }}" + client_key: "{{ tls_etcd_privatekey_path if tls_cert_generate | bool else omit }}" register: etcd_health_status failed_when: "(etcd_health_status.content | from_json).health != 'true'" when: dcs_type == "etcd" From f143688ee00d46c7c90e42738d79d85b813d3ed5 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Mon, 23 Dec 2024 16:20:27 +0500 Subject: [PATCH 13/36] Update main.yml --- automation/roles/etcd/tasks/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/automation/roles/etcd/tasks/main.yml b/automation/roles/etcd/tasks/main.yml index 2933b7402..ff3985177 100644 --- a/automation/roles/etcd/tasks/main.yml +++ b/automation/roles/etcd/tasks/main.yml @@ -138,9 +138,9 @@ /usr/local/bin/etcdctl endpoint health --endpoints={{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2379 {% if tls_cert_generate | bool %} - --cacert=/etc/etcd/ca.crt - --cert=/etc/etcd/server.crt - --key=/etc/etcd/server.key + --cacert={{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }} + --cert={{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }} + --key={{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }} {% endif %} environment: ETCDCTL_API: "3" From 73689119febb0c0bb7c83171219ed046cdf83c92 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Mon, 23 Dec 2024 16:28:15 +0500 Subject: [PATCH 14/36] add 'default' variable value --- automation/molecule/tests/etcd/etcd.yml | 2 +- .../roles/confd/templates/confd.toml.j2 | 4 ++-- automation/roles/etcd/tasks/main.yml | 2 +- automation/roles/etcd/templates/etcd.conf.j2 | 22 +++++++++---------- .../vip-manager/templates/vip-manager.yml.j2 | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/automation/molecule/tests/etcd/etcd.yml b/automation/molecule/tests/etcd/etcd.yml index c37599fd6..161fa6944 100644 --- a/automation/molecule/tests/etcd/etcd.yml +++ b/automation/molecule/tests/etcd/etcd.yml @@ -1,7 +1,7 @@ --- - name: Check etcd health ansible.builtin.uri: - url: "{{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2379/health" + url: "{{ patroni_etcd_protocol | default('http', true) }}://{{ inventory_hostname }}:2379/health" method: GET return_content: true validate_certs: "{{ tls_cert_generate | bool }}" diff --git a/automation/roles/confd/templates/confd.toml.j2 b/automation/roles/confd/templates/confd.toml.j2 index add558254..dcd8e39f9 100644 --- a/automation/roles/confd/templates/confd.toml.j2 +++ b/automation/roles/confd/templates/confd.toml.j2 @@ -4,12 +4,12 @@ watch = true nodes = [ {% if not dcs_exists|bool and dcs_type == 'etcd' %} {% for host in groups['etcd_cluster'] %} - "{{ patroni_etcd_protocol }}://{{ hostvars[host]['inventory_hostname'] }}:2379", + "{{ patroni_etcd_protocol | default('http', true) }}://{{ hostvars[host]['inventory_hostname'] }}:2379", {% endfor %} {% endif %} {% if dcs_exists|bool and dcs_type == 'etcd' %} {% for etcd_hosts in patroni_etcd_hosts %} - "{{ patroni_etcd_protocol }}://{{etcd_hosts.host}}:{{etcd_hosts.port}}", + "{{ patroni_etcd_protocol | default('http', true) }}://{{etcd_hosts.host}}:{{etcd_hosts.port}}", {% endfor %} {% endif %} ] diff --git a/automation/roles/etcd/tasks/main.yml b/automation/roles/etcd/tasks/main.yml index ff3985177..fc8c47f47 100644 --- a/automation/roles/etcd/tasks/main.yml +++ b/automation/roles/etcd/tasks/main.yml @@ -136,7 +136,7 @@ - name: Wait until the etcd cluster is healthy ansible.builtin.command: > /usr/local/bin/etcdctl endpoint health - --endpoints={{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2379 + --endpoints={{ patroni_etcd_protocol | default('http', true) }}://{{ inventory_hostname }}:2379 {% if tls_cert_generate | bool %} --cacert={{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }} --cert={{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }} diff --git a/automation/roles/etcd/templates/etcd.conf.j2 b/automation/roles/etcd/templates/etcd.conf.j2 index ada454ef1..cd46d54bb 100644 --- a/automation/roles/etcd/templates/etcd.conf.j2 +++ b/automation/roles/etcd/templates/etcd.conf.j2 @@ -1,10 +1,10 @@ ETCD_NAME="{{ ansible_hostname }}" -ETCD_LISTEN_CLIENT_URLS="{{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2379,{{ patroni_etcd_protocol }}://127.0.0.1:2379" -ETCD_ADVERTISE_CLIENT_URLS="{{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2379" -ETCD_LISTEN_PEER_URLS="{{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2380" -ETCD_INITIAL_ADVERTISE_PEER_URLS="{{ patroni_etcd_protocol }}://{{ inventory_hostname }}:2380" +ETCD_LISTEN_CLIENT_URLS="{{ patroni_etcd_protocol | default('http', true) }}://{{ inventory_hostname }}:2379,{{ patroni_etcd_protocol | default('http', true) }}://127.0.0.1:2379" +ETCD_ADVERTISE_CLIENT_URLS="{{ patroni_etcd_protocol | default('http', true) }}://{{ inventory_hostname }}:2379" +ETCD_LISTEN_PEER_URLS="{{ patroni_etcd_protocol | default('http', true) }}://{{ inventory_hostname }}:2380" +ETCD_INITIAL_ADVERTISE_PEER_URLS="{{ patroni_etcd_protocol | default('http', true) }}://{{ inventory_hostname }}:2380" ETCD_INITIAL_CLUSTER_TOKEN="{{ etcd_cluster_name }}" -ETCD_INITIAL_CLUSTER="{% for host in groups['etcd_cluster'] %}{{ hostvars[host]['ansible_hostname'] }}={{ patroni_etcd_protocol }}://{{ hostvars[host]['inventory_hostname'] }}:2380{% if not loop.last %},{% endif %}{% endfor %}" +ETCD_INITIAL_CLUSTER="{% for host in groups['etcd_cluster'] %}{{ hostvars[host]['ansible_hostname'] }}={{ patroni_etcd_protocol | default('http', true) }}://{{ hostvars[host]['inventory_hostname'] }}:2380{% if not loop.last %},{% endif %}{% endfor %}" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_DATA_DIR="{{ etcd_data_dir }}" ETCD_ELECTION_TIMEOUT="5000" @@ -12,12 +12,12 @@ ETCD_HEARTBEAT_INTERVAL="1000" ETCD_INITIAL_ELECTION_TICK_ADVANCE="false" ETCD_AUTO_COMPACTION_RETENTION="1" {% if tls_cert_generate | bool %} -ETCD_CERT_FILE="{{ tls_etcd_cert_path }}" -ETCD_KEY_FILE="{{ tls_etcd_privatekey_path }}" -ETCD_TRUSTED_CA_FILE="{{ tls_etcd_ca_cert_path }}" -ETCD_PEER_CERT_FILE="{{ tls_etcd_cert_path }}" -ETCD_PEER_KEY_FILE="{{ tls_etcd_privatekey_path }}" -ETCD_PEER_TRUSTED_CA_FILE="{{ tls_etcd_ca_cert_path }}" +ETCD_CERT_FILE="{{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }}" +ETCD_KEY_FILE="{{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }}" +ETCD_TRUSTED_CA_FILE="{{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }}" +ETCD_PEER_CERT_FILE="{{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }}" +ETCD_PEER_KEY_FILE="{{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }}" +ETCD_PEER_TRUSTED_CA_FILE="{{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }}" ETCD_PEER_CLIENT_CERT_AUTH="true" ETCD_CLIENT_CERT_AUTH="true" ETCD_TLS_MIN_VERSION="TLS1.2" diff --git a/automation/roles/vip-manager/templates/vip-manager.yml.j2 b/automation/roles/vip-manager/templates/vip-manager.yml.j2 index ca02f929a..2ace2a3a5 100644 --- a/automation/roles/vip-manager/templates/vip-manager.yml.j2 +++ b/automation/roles/vip-manager/templates/vip-manager.yml.j2 @@ -27,12 +27,12 @@ dcs-type: {{ vip_manager_dcs_type | default(dcs_type) }} # etcd, consul or patro {% if not dcs_exists | bool %} dcs-endpoints: {% for host in groups['etcd_cluster'] %} - - {{ patroni_etcd_protocol }}://{{ hostvars[host]['inventory_hostname'] }}:2379 + - {{ patroni_etcd_protocol | default('http', true) }}://{{ hostvars[host]['inventory_hostname'] }}:2379 {% endfor %} {% else %} dcs-endpoints: {% for etcd_hosts in patroni_etcd_hosts %} - - {{ patroni_etcd_protocol }}://{{ etcd_hosts.host }}:{{ etcd_hosts.port }} + - {{ patroni_etcd_protocol | default('http', true) }}://{{ etcd_hosts.host }}:{{ etcd_hosts.port }} {% endfor %} {% endif %} {% endif %} From d30cd4f2ca5e3b5b22ddcb8d55ce6c18f5ab95e5 Mon Sep 17 00:00:00 2001 From: klention Date: Tue, 24 Dec 2024 16:22:30 +0100 Subject: [PATCH 15/36] Added subject to the TLS certificate signing request --- automation/roles/tls_certificate/generate/tasks/main.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml index 06a3d58e7..9f869d81c 100644 --- a/automation/roles/tls_certificate/generate/tasks/main.yml +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -80,7 +80,7 @@ - name: "Create server CSR" community.crypto.openssl_csr_pipe: privatekey_path: "/etc/tls/server.key" - common_name: postgresql.cluster + common_name: "{{ patroni_cluster_name }}" key_usage: - digitalSignature - keyEncipherment @@ -88,6 +88,10 @@ extended_key_usage: - clientAuth - serverAuth + subject: + C: "AL" + O: "autobase" + CN: "{{ patroni_cluster_name }}" subject_alt_name: "{{ subject_alt_name }}" register: csr From adf6dbeeaa459fe643136dbca26650f6f6a89dde Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik <37010174+vitabaks@users.noreply.github.com> Date: Thu, 26 Dec 2024 15:09:26 +0500 Subject: [PATCH 16/36] Update automation/vars/main.yml --- automation/vars/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/automation/vars/main.yml b/automation/vars/main.yml index 3ee237689..6ee85fb85 100644 --- a/automation/vars/main.yml +++ b/automation/vars/main.yml @@ -245,8 +245,8 @@ postgresql_parameters: - { option: "max_connections", value: "1000" } - { option: "superuser_reserved_connections", value: "5" } - { option: "password_encryption", value: "{{ postgresql_password_encryption_algorithm }}" } - - { option: "ssl", value: "{% if tls_cert_generate | bool %}on{% else %}off{% endif %}"} - - { option: "ssl_prefer_server_ciphers", value: "{% if tls_cert_generate | bool %}on{% else %}off{% endif %}"} + - { option: "ssl", value: "{{ 'on' if tls_cert_generate | bool else 'off' }}" } + - { option: "ssl_prefer_server_ciphers", value: "{{ 'on' if tls_cert_generate | bool else 'off' }}" } - { option: "ssl_cert_file", value: "{{ tls_cert_path | default('') }}"} - { option: "ssl_key_file", value: "{{ tls_privatekey_path | default('') }}"} - { option: "ssl_ca_file", value: "{{ tls_ca_cert_path | default('') }}"} From 9c554f69f3550513bd54d3e7569c3af7cb83a870 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik <37010174+vitabaks@users.noreply.github.com> Date: Thu, 26 Dec 2024 15:27:38 +0500 Subject: [PATCH 17/36] hba_host_type --- automation/vars/main.yml | 34 ++++++---------------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/automation/vars/main.yml b/automation/vars/main.yml index 6ee85fb85..2fa3c9bfb 100644 --- a/automation/vars/main.yml +++ b/automation/vars/main.yml @@ -344,35 +344,13 @@ postgresql_pg_hba: - { type: "local", database: "all", user: "all", address: "", method: "{{ postgresql_password_encryption_algorithm }}" } - { type: "host", database: "all", user: "all", address: "127.0.0.1/32", method: "{{ postgresql_password_encryption_algorithm }}" } - { type: "host", database: "all", user: "all", address: "::1/128", method: "{{ postgresql_password_encryption_algorithm }}" } - - type: >- - {% if tls_cert_generate | bool %}hostssl - {% else %}host - {% endif %} - database: "all" - user: "all" - address: "0.0.0.0/0" - method: "{{ postgresql_password_encryption_algorithm }}" - -# - type: >- -# {% if tls_cert_generate | bool %}hostssl -# {% else %}host -# {% endif %} -# database: "mydatabase" -# user: "mydb-user" -# address: "192.168.0.0/24" -# method: "{{ postgresql_password_encryption_algorithm }}" - -# - type: >- -# {% if tls_cert_generate | bool %}hostssl -# {% else %}host -# {% endif %} -# database: "all" -# user: "all" -# address: "192.168.0.0/24" -# method: "ident" -# options: "map=main" # use pg_ident -# list of lines that Patroni will use to generate pg_ident.conf + - { type: "{{ hba_host_type }}", database: "all", user: "all", address: "0.0.0.0/0", method: "{{ postgresql_password_encryption_algorithm }}" } +# - { type: "{{ hba_host_type }}", database: "mydatabase", user: "mydb-user", address: "192.168.0.0/24", method: "{{ postgresql_password_encryption_algorithm }}" } +# - { type: "{{ hba_host_type }}", database: "all", user: "all", address: "192.168.0.0/24", method: "ident", options: "map=main" } # use pg_ident + +hba_host_type: "{{ 'hostssl' if tls_cert_generate | bool else 'host' }}" +# list of lines that Patroni will use to generate pg_ident.conf postgresql_pg_ident: [] # - { mapname: "main", system_username: "postgres", pg_username: "backup" } # - { mapname: "", system_username: "", pg_username: "" } From ddfea61c472a9cde2e2fbe4f4527199d861d1818 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik <37010174+vitabaks@users.noreply.github.com> Date: Thu, 26 Dec 2024 15:33:40 +0500 Subject: [PATCH 18/36] host_type --- automation/vars/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/automation/vars/main.yml b/automation/vars/main.yml index 2fa3c9bfb..b9f14fdc9 100644 --- a/automation/vars/main.yml +++ b/automation/vars/main.yml @@ -344,11 +344,11 @@ postgresql_pg_hba: - { type: "local", database: "all", user: "all", address: "", method: "{{ postgresql_password_encryption_algorithm }}" } - { type: "host", database: "all", user: "all", address: "127.0.0.1/32", method: "{{ postgresql_password_encryption_algorithm }}" } - { type: "host", database: "all", user: "all", address: "::1/128", method: "{{ postgresql_password_encryption_algorithm }}" } - - { type: "{{ hba_host_type }}", database: "all", user: "all", address: "0.0.0.0/0", method: "{{ postgresql_password_encryption_algorithm }}" } -# - { type: "{{ hba_host_type }}", database: "mydatabase", user: "mydb-user", address: "192.168.0.0/24", method: "{{ postgresql_password_encryption_algorithm }}" } -# - { type: "{{ hba_host_type }}", database: "all", user: "all", address: "192.168.0.0/24", method: "ident", options: "map=main" } # use pg_ident + - { type: "{{ host_type }}", database: "all", user: "all", address: "0.0.0.0/0", method: "{{ postgresql_password_encryption_algorithm }}" } +# - { type: "{{ host_type }}", database: "mydatabase", user: "mydb-user", address: "192.168.0.0/24", method: "{{ postgresql_password_encryption_algorithm }}" } +# - { type: "{{ host_type }}", database: "all", user: "all", address: "192.168.0.0/24", method: "ident", options: "map=main" } # use pg_ident -hba_host_type: "{{ 'hostssl' if tls_cert_generate | bool else 'host' }}" +host_type: "{{ 'hostssl' if tls_cert_generate | bool else 'host' }}" # list of lines that Patroni will use to generate pg_ident.conf postgresql_pg_ident: [] From d7ad3f79f600a4133fcca2199fb65cf3ac11bac1 Mon Sep 17 00:00:00 2001 From: klention Date: Fri, 27 Dec 2024 01:39:20 +0100 Subject: [PATCH 19/36] Minor updates --- automation/deploy_pgcluster.yml | 14 +++++--------- automation/roles/pgbouncer/tasks/main.yml | 8 -------- .../roles/tls_certificate/generate/tasks/main.yml | 11 ++++++++++- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/automation/deploy_pgcluster.yml b/automation/deploy_pgcluster.yml index f4a592db8..ed2060d52 100644 --- a/automation/deploy_pgcluster.yml +++ b/automation/deploy_pgcluster.yml @@ -83,15 +83,6 @@ - pgbackrest_auto_conf | default(true) | bool # to be able to disable auto backup settings tags: always - - name: Make sure that the python3-cryptography package is present - ansible.builtin.package: - name: python3-cryptography - state: present - register: pack_status - until: pack_status is success - delay: 5 - retries: 3 - roles: # (optional) if 'ssh_public_keys' is defined - role: authorized-keys @@ -370,6 +361,11 @@ - role: cron + - role: tls_certificate/copy + when: tls_cert_generate|bool + vars: + copy_for: "pg" + - role: pgbouncer when: pgbouncer_install|bool diff --git a/automation/roles/pgbouncer/tasks/main.yml b/automation/roles/pgbouncer/tasks/main.yml index ba4402e9f..cd2fb08fe 100644 --- a/automation/roles/pgbouncer/tasks/main.yml +++ b/automation/roles/pgbouncer/tasks/main.yml @@ -36,14 +36,6 @@ mode: "0750" tags: pgbouncer_conf, pgbouncer -- name: Fetch PostgreSQL TLS certificate, key and CA from the master node - ansible.builtin.include_role: - name: ../roles/tls_certificate/copy - vars: - copy_for: "pg" - when: tls_cert_generate|bool - tags: pgbouncer_conf, pgbouncer - - name: Ensure log directory "{{ pgbouncer_log_dir }}" exist ansible.builtin.file: path: "{{ pgbouncer_log_dir }}" diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml index 9f869d81c..1b5d2729b 100644 --- a/automation/roles/tls_certificate/generate/tasks/main.yml +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -1,4 +1,13 @@ --- +- name: Make sure that the python3-cryptography package is present + ansible.builtin.package: + name: python3-cryptography + state: present + register: pack_status + until: pack_status is success + delay: 5 + retries: 3 + - name: "Clean up existing certificates" ansible.builtin.file: path: "{{ item }}" @@ -101,7 +110,7 @@ provider: ownca ownca_path: "/etc/tls/ca.crt" ownca_privatekey_path: "/etc/tls/ca.key" - ownca_not_after: +3650d + ownca_not_after: +{{ tls_cert_valid_days | default(3650) }}d ownca_not_before: "-1d" register: certificate From 38b384da4bdf78843fa604de81c214f3f007ab50 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Fri, 27 Dec 2024 17:20:19 +0500 Subject: [PATCH 20/36] Add default for tls_cert_generate variable --- automation/molecule/tests/etcd/etcd.yml | 8 ++++---- automation/roles/etcd/tasks/main.yml | 2 +- automation/roles/etcd/templates/etcd.conf.j2 | 2 +- automation/roles/patroni/templates/patroni.yml.j2 | 4 ++-- automation/roles/patroni/templates/pg_hba.conf.j2 | 8 ++++---- automation/roles/vip-manager/templates/vip-manager.yml.j2 | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/automation/molecule/tests/etcd/etcd.yml b/automation/molecule/tests/etcd/etcd.yml index 161fa6944..42991a5c4 100644 --- a/automation/molecule/tests/etcd/etcd.yml +++ b/automation/molecule/tests/etcd/etcd.yml @@ -4,10 +4,10 @@ url: "{{ patroni_etcd_protocol | default('http', true) }}://{{ inventory_hostname }}:2379/health" method: GET return_content: true - validate_certs: "{{ tls_cert_generate | bool }}" - ca_path: "{{ tls_etcd_ca_cert_path if tls_cert_generate | bool else omit }}" - client_cert: "{{ tls_etcd_cert_path if tls_cert_generate | bool else omit }}" - client_key: "{{ tls_etcd_privatekey_path if tls_cert_generate | bool else omit }}" + validate_certs: "{{ tls_cert_generate | default(false) | bool }}" + ca_path: "{{ tls_etcd_ca_cert_path if tls_cert_generate | default(false) | bool else omit }}" + client_cert: "{{ tls_etcd_cert_path if tls_cert_generate | default(false) | bool else omit }}" + client_key: "{{ tls_etcd_privatekey_path if tls_cert_generate | default(false) | bool else omit }}" register: etcd_health_status failed_when: "(etcd_health_status.content | from_json).health != 'true'" when: dcs_type == "etcd" diff --git a/automation/roles/etcd/tasks/main.yml b/automation/roles/etcd/tasks/main.yml index fc8c47f47..3d1807e46 100644 --- a/automation/roles/etcd/tasks/main.yml +++ b/automation/roles/etcd/tasks/main.yml @@ -137,7 +137,7 @@ ansible.builtin.command: > /usr/local/bin/etcdctl endpoint health --endpoints={{ patroni_etcd_protocol | default('http', true) }}://{{ inventory_hostname }}:2379 - {% if tls_cert_generate | bool %} + {% if tls_cert_generate | default(false) | bool %} --cacert={{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }} --cert={{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }} --key={{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }} diff --git a/automation/roles/etcd/templates/etcd.conf.j2 b/automation/roles/etcd/templates/etcd.conf.j2 index cd46d54bb..737b179c7 100644 --- a/automation/roles/etcd/templates/etcd.conf.j2 +++ b/automation/roles/etcd/templates/etcd.conf.j2 @@ -11,7 +11,7 @@ ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_INITIAL_ELECTION_TICK_ADVANCE="false" ETCD_AUTO_COMPACTION_RETENTION="1" -{% if tls_cert_generate | bool %} +{% if tls_cert_generate | default(false) | bool %} ETCD_CERT_FILE="{{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }}" ETCD_KEY_FILE="{{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }}" ETCD_TRUSTED_CA_FILE="{{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }}" diff --git a/automation/roles/patroni/templates/patroni.yml.j2 b/automation/roles/patroni/templates/patroni.yml.j2 index 241c5ed5a..a1755f8d7 100644 --- a/automation/roles/patroni/templates/patroni.yml.j2 +++ b/automation/roles/patroni/templates/patroni.yml.j2 @@ -39,7 +39,7 @@ restapi: etcd3: hosts: {% for host in groups['etcd_cluster'] %}{{ hostvars[host]['inventory_hostname'] }}:2379{% if not loop.last %},{% endif %}{% endfor %} - {% if tls_cert_generate | bool %} + {% if tls_cert_generate | default(false) | bool %} protocol: https cacert: {{ tls_ca_cert_path | default('/etc/tls/ca.crt') }} cert: {{ tls_cert_path | default('/etc/tls/server.crt') }} @@ -51,7 +51,7 @@ etcd3: etcd3: hosts: {% for etcd_hosts in patroni_etcd_hosts %}{{etcd_hosts.host}}:{{etcd_hosts.port}}{% if not loop.last %},{% endif %}{% endfor %} - {% if tls_cert_generate | bool %} + {% if tls_cert_generate | default(false) | bool %} protocol: https cacert: {{ tls_ca_cert_path | default('/etc/tls/ca.crt') }} cert: {{ tls_cert_path | default('/etc/tls/server.crt') }} diff --git a/automation/roles/patroni/templates/pg_hba.conf.j2 b/automation/roles/patroni/templates/pg_hba.conf.j2 index 8c1adaa03..53187ecb1 100644 --- a/automation/roles/patroni/templates/pg_hba.conf.j2 +++ b/automation/roles/patroni/templates/pg_hba.conf.j2 @@ -85,14 +85,14 @@ # TYPE DATABASE USER ADDRESS METHOD {% for client in postgresql_pg_hba %} - {{ client.type.ljust(10) |default('{% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %}') }}{{ client.database.ljust(25) |default('all') }}{{ client.user.ljust(25) |default('all') }}{{ client.address.ljust(25) |default('') }}{{ client.method |default('md5') }} {{ client.options |default(None) }} + {{ client.type.ljust(10) |default('{% if tls_cert_generate | default(false) | bool %}hostssl{% else %}host{% endif %}') }}{{ client.database.ljust(25) |default('all') }}{{ client.user.ljust(25) |default('all') }}{{ client.address.ljust(25) |default('') }}{{ client.method |default('md5') }} {{ client.options |default(None) }} {% endfor %} {% for patroni in groups['postgres_cluster'] %} - {% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %} all all {{ hostvars[patroni]['inventory_hostname'] }}/32 {{ postgresql_password_encryption_algorithm }} + {% if tls_cert_generate | default(false) | bool %}hostssl{% else %}host{% endif %} all all {{ hostvars[patroni]['inventory_hostname'] }}/32 {{ postgresql_password_encryption_algorithm }} {% endfor %} # Allow replication connections from localhost, by a user with the # replication privilege. - {% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %} replication {{ patroni_replication_username }} localhost trust + {% if tls_cert_generate | default(false) | bool %}hostssl{% else %}host{% endif %} replication {{ patroni_replication_username }} localhost trust {% for host in groups['postgres_cluster'] %} - {% if tls_cert_generate | bool %}hostssl{% else %}host{% endif %} replication {{ patroni_replication_username }} {{ hostvars[host]['inventory_hostname'] }}/32 {{ postgresql_password_encryption_algorithm }} + {% if tls_cert_generate | default(false) | bool %}hostssl{% else %}host{% endif %} replication {{ patroni_replication_username }} {{ hostvars[host]['inventory_hostname'] }}/32 {{ postgresql_password_encryption_algorithm }} {% endfor %} diff --git a/automation/roles/vip-manager/templates/vip-manager.yml.j2 b/automation/roles/vip-manager/templates/vip-manager.yml.j2 index 2ace2a3a5..f20e051d4 100644 --- a/automation/roles/vip-manager/templates/vip-manager.yml.j2 +++ b/automation/roles/vip-manager/templates/vip-manager.yml.j2 @@ -64,15 +64,15 @@ etcd-user: {{ patroni_etcd_username | default("") }} {% if patroni_etcd_password | default("") | length > 0 %} etcd-password: {{ patroni_etcd_password | default("") }} {% endif %} -{% if tls_cert_generate | bool %} +{% if tls_cert_generate | default(false) | bool %} # when etcd-ca-file is specified, TLS connections to the etcd endpoints will be used. etcd-ca-file: {{ tls_ca_cert_path | default('/etc/tls/ca.crt') }} {% endif %} -{% if tls_cert_generate | bool %} +{% if tls_cert_generate | default(false) | bool %} # when etcd-cert-file and etcd-key-file are specified, we will authenticate at the etcd endpoints using this certificate and key. etcd-cert-file: {{ tls_cert_path | default('/etc/tls/server.crt') }} {% endif %} -{% if tls_cert_generate | bool %} +{% if tls_cert_generate | default(false) | bool %} etcd-key-file: {{ tls_privatekey_path | default('/etc/tls/server.key') }} {% endif %} {% endif %} From 71e33f157a90eefbfafcf6fd18a084ccfa1c764b Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Fri, 27 Dec 2024 17:24:14 +0500 Subject: [PATCH 21/36] Update vip-manager.yml.j2 --- .../roles/vip-manager/templates/vip-manager.yml.j2 | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/automation/roles/vip-manager/templates/vip-manager.yml.j2 b/automation/roles/vip-manager/templates/vip-manager.yml.j2 index f20e051d4..93388e57c 100644 --- a/automation/roles/vip-manager/templates/vip-manager.yml.j2 +++ b/automation/roles/vip-manager/templates/vip-manager.yml.j2 @@ -66,14 +66,10 @@ etcd-password: {{ patroni_etcd_password | default("") }} {% endif %} {% if tls_cert_generate | default(false) | bool %} # when etcd-ca-file is specified, TLS connections to the etcd endpoints will be used. -etcd-ca-file: {{ tls_ca_cert_path | default('/etc/tls/ca.crt') }} -{% endif %} -{% if tls_cert_generate | default(false) | bool %} +etcd-ca-file: {{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }} # when etcd-cert-file and etcd-key-file are specified, we will authenticate at the etcd endpoints using this certificate and key. -etcd-cert-file: {{ tls_cert_path | default('/etc/tls/server.crt') }} -{% endif %} -{% if tls_cert_generate | default(false) | bool %} -etcd-key-file: {{ tls_privatekey_path | default('/etc/tls/server.key') }} +etcd-cert-file: {{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }} +etcd-key-file: {{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }} {% endif %} {% endif %} From c166664467c7a95a480383e8f46e2d3f8d13816a Mon Sep 17 00:00:00 2001 From: Klention Mali <45871249+klention@users.noreply.github.com> Date: Fri, 27 Dec 2024 17:44:28 +0100 Subject: [PATCH 22/36] Update automation/roles/tls_certificate/generate/tasks/main.yml Co-authored-by: Vitaliy Kukharik <37010174+vitabaks@users.noreply.github.com> --- automation/roles/tls_certificate/generate/tasks/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml index 1b5d2729b..2758ef34f 100644 --- a/automation/roles/tls_certificate/generate/tasks/main.yml +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -20,7 +20,6 @@ - "{{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }}" - "{{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }}" - "{{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }}" - - "/etc/tls" - ansible.builtin.set_fact: all_san_entries: [] From 4d521f52e2d6c9b6f6d73eae607d024bd8fd5c11 Mon Sep 17 00:00:00 2001 From: klention Date: Fri, 27 Dec 2024 18:25:33 +0100 Subject: [PATCH 23/36] Remove the source of TLS cert/key/ca --- automation/roles/tls_certificate/generate/tasks/main.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml index 2758ef34f..2f20b82aa 100644 --- a/automation/roles/tls_certificate/generate/tasks/main.yml +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -20,6 +20,9 @@ - "{{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }}" - "{{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }}" - "{{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }}" + - "/etc/tls/server.key" + - "/etc/tls/server.crt" + - "/etc/tls/ca.crt" - ansible.builtin.set_fact: all_san_entries: [] From 52536a314cac0e3d44f0a8f1f189f89fc2aa535f Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Sat, 28 Dec 2024 10:26:32 +0000 Subject: [PATCH 24/36] Update deploy_pgcluster.yml --- automation/deploy_pgcluster.yml | 34 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/automation/deploy_pgcluster.yml b/automation/deploy_pgcluster.yml index ed2060d52..4625428fa 100644 --- a/automation/deploy_pgcluster.yml +++ b/automation/deploy_pgcluster.yml @@ -83,23 +83,6 @@ - pgbackrest_auto_conf | default(true) | bool # to be able to disable auto backup settings tags: always - roles: - # (optional) if 'ssh_public_keys' is defined - - role: authorized-keys - tags: ssh_public_keys - - - role: pre-checks - vars: - minimal_ansible_version: 2.16.0 - timescale_minimal_pg_version: 12 # if enable_timescale is defined - tags: always - - - role: hostname - - - role: tls_certificate/generate - when: tls_cert_generate|bool - - tasks: - name: Clean dnf cache ansible.builtin.command: dnf clean all when: @@ -207,6 +190,22 @@ when: pre_deploy_command | default('') | length > 0 tags: pre_deploy, pre_deploy_command + roles: + # (optional) if 'ssh_public_keys' is defined + - role: authorized-keys + tags: ssh_public_keys + + - role: pre-checks + vars: + minimal_ansible_version: 2.16.0 + timescale_minimal_pg_version: 12 # if enable_timescale is defined + tags: always + + - role: hostname + + - role: tls_certificate/generate + when: tls_cert_generate|bool + - name: deploy_pgcluster.yml | Deploy etcd cluster ansible.builtin.import_playbook: etcd_cluster.yml when: not dcs_exists|bool and dcs_type == "etcd" @@ -266,7 +265,6 @@ when: firewall_enabled_at_boot|bool tags: firewall - - role: hostname - role: resolv_conf - role: etc_hosts - role: add-repository From eae83bb9a57bf2e0ec2891e52e0b280e0a2febe5 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Sat, 28 Dec 2024 10:41:58 +0000 Subject: [PATCH 25/36] Create tls directory for etcd --- .../roles/tls_certificate/copy/tasks/main.yml | 31 ++++++++++++------- automation/vars/main.yml | 2 +- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/automation/roles/tls_certificate/copy/tasks/main.yml b/automation/roles/tls_certificate/copy/tasks/main.yml index 3fad3ac28..e0081a764 100644 --- a/automation/roles/tls_certificate/copy/tasks/main.yml +++ b/automation/roles/tls_certificate/copy/tasks/main.yml @@ -10,17 +10,26 @@ - "/etc/tls/server.crt" - "/etc/tls/ca.crt" -- name: Copy etcd TLS certificate, key and CA to all nodes from memory - ansible.builtin.copy: - content: "{{ tls_files.results[item.index].content | b64decode }}" - dest: "{{ item.path }}" - owner: "etcd" - group: "etcd" - mode: "{{ item.mode }}" - loop: - - { index: 0, path: "{{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }}", mode: "0400" } - - { index: 1, path: "{{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }}", mode: "0644" } - - { index: 2, path: "{{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }}", mode: "0644" } +- block: + - name: Create directory {{ tls_etcd_privatekey_path | dirname }} + ansible.builtin.file: + dest: "{{ tls_etcd_privatekey_path | dirname }}" + state: directory + owner: "etcd" + group: "etcd" + mode: "0755" + + - name: Copy etcd TLS certificate, key and CA to all nodes from memory + ansible.builtin.copy: + content: "{{ tls_files.results[item.index].content | b64decode }}" + dest: "{{ item.path }}" + owner: "etcd" + group: "etcd" + mode: "{{ item.mode }}" + loop: + - { index: 0, path: "{{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }}", mode: "0400" } + - { index: 1, path: "{{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }}", mode: "0644" } + - { index: 2, path: "{{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }}", mode: "0644" } when: copy_for == 'etcd' - block: diff --git a/automation/vars/main.yml b/automation/vars/main.yml index b9f14fdc9..af6e06335 100644 --- a/automation/vars/main.yml +++ b/automation/vars/main.yml @@ -181,7 +181,7 @@ tls_cert_path: "{{ postgresql_home_dir }}/tls/server.crt" tls_privatekey_path: "{{ postgresql_home_dir }}/tls/server.key" tls_ca_cert_path: "{{ postgresql_home_dir }}/tls/ca.crt" tls_owner: "postgres" -tls_etcd_cert_path: "/etc/etcd/server.crt" +tls_etcd_cert_path: "/etc/etcd/tls/server.crt" tls_etcd_ca_cert_path: "/etc/etcd/ca.crt" tls_etcd_privatekey_path: "/etc/etcd/server.key" From 0187bd1366fffb87a4708c4b7e53e6ecafd9a4f8 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Sat, 28 Dec 2024 10:52:04 +0000 Subject: [PATCH 26/36] update patroni.yml template for etcd --- .../roles/patroni/templates/patroni.yml.j2 | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/automation/roles/patroni/templates/patroni.yml.j2 b/automation/roles/patroni/templates/patroni.yml.j2 index a1755f8d7..337d79ea3 100644 --- a/automation/roles/patroni/templates/patroni.yml.j2 +++ b/automation/roles/patroni/templates/patroni.yml.j2 @@ -35,29 +35,20 @@ restapi: # password: password {% endif %} -{% if not dcs_exists|bool and dcs_type == 'etcd' %} +{% if dcs_type == 'etcd' %} etcd3: + {% if not dcs_exists|bool %} hosts: {% for host in groups['etcd_cluster'] %}{{ hostvars[host]['inventory_hostname'] }}:2379{% if not loop.last %},{% endif %}{% endfor %} - - {% if tls_cert_generate | default(false) | bool %} - protocol: https - cacert: {{ tls_ca_cert_path | default('/etc/tls/ca.crt') }} - cert: {{ tls_cert_path | default('/etc/tls/server.crt') }} - key: {{ tls_privatekey_path | default('/etc/tls/server.key') }} {% endif %} -{% endif %} - -{% if dcs_exists|bool and dcs_type == 'etcd' %} -etcd3: + {% if dcs_exists|bool %} hosts: {% for etcd_hosts in patroni_etcd_hosts %}{{etcd_hosts.host}}:{{etcd_hosts.port}}{% if not loop.last %},{% endif %}{% endfor %} - + {% endif %} {% if tls_cert_generate | default(false) | bool %} protocol: https - cacert: {{ tls_ca_cert_path | default('/etc/tls/ca.crt') }} - cert: {{ tls_cert_path | default('/etc/tls/server.crt') }} - key: {{ tls_privatekey_path | default('/etc/tls/server.key') }} + cacert: {{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }} + cert: {{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }} + key: {{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }} {% endif %} - {% if patroni_etcd_username | default('') | length > 0 %} username: {{ patroni_etcd_username | default('') }} {% endif %} From d779a5918a2be3627904d453d0a0c860ee03d153 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Sat, 28 Dec 2024 11:24:27 +0000 Subject: [PATCH 27/36] update path to tls dir for etcd --- automation/roles/etcd/tasks/main.yml | 6 +++--- automation/roles/etcd/templates/etcd.conf.j2 | 12 ++++++------ automation/roles/patroni/templates/patroni.yml.j2 | 6 +++--- automation/roles/tls_certificate/copy/tasks/main.yml | 6 +++--- .../roles/tls_certificate/generate/tasks/main.yml | 6 +++--- .../roles/vip-manager/templates/vip-manager.yml.j2 | 6 +++--- automation/vars/main.yml | 4 ++-- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/automation/roles/etcd/tasks/main.yml b/automation/roles/etcd/tasks/main.yml index 3d1807e46..80ceae29f 100644 --- a/automation/roles/etcd/tasks/main.yml +++ b/automation/roles/etcd/tasks/main.yml @@ -138,9 +138,9 @@ /usr/local/bin/etcdctl endpoint health --endpoints={{ patroni_etcd_protocol | default('http', true) }}://{{ inventory_hostname }}:2379 {% if tls_cert_generate | default(false) | bool %} - --cacert={{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }} - --cert={{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }} - --key={{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }} + --cacert={{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }} + --cert={{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }} + --key={{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }} {% endif %} environment: ETCDCTL_API: "3" diff --git a/automation/roles/etcd/templates/etcd.conf.j2 b/automation/roles/etcd/templates/etcd.conf.j2 index 737b179c7..b1f4e2bfa 100644 --- a/automation/roles/etcd/templates/etcd.conf.j2 +++ b/automation/roles/etcd/templates/etcd.conf.j2 @@ -12,12 +12,12 @@ ETCD_HEARTBEAT_INTERVAL="1000" ETCD_INITIAL_ELECTION_TICK_ADVANCE="false" ETCD_AUTO_COMPACTION_RETENTION="1" {% if tls_cert_generate | default(false) | bool %} -ETCD_CERT_FILE="{{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }}" -ETCD_KEY_FILE="{{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }}" -ETCD_TRUSTED_CA_FILE="{{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }}" -ETCD_PEER_CERT_FILE="{{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }}" -ETCD_PEER_KEY_FILE="{{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }}" -ETCD_PEER_TRUSTED_CA_FILE="{{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }}" +ETCD_CERT_FILE="{{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }}" +ETCD_KEY_FILE="{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }}" +ETCD_TRUSTED_CA_FILE="{{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }}" +ETCD_PEER_CERT_FILE="{{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }}" +ETCD_PEER_KEY_FILE="{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }}" +ETCD_PEER_TRUSTED_CA_FILE="{{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }}" ETCD_PEER_CLIENT_CERT_AUTH="true" ETCD_CLIENT_CERT_AUTH="true" ETCD_TLS_MIN_VERSION="TLS1.2" diff --git a/automation/roles/patroni/templates/patroni.yml.j2 b/automation/roles/patroni/templates/patroni.yml.j2 index 337d79ea3..79106ba51 100644 --- a/automation/roles/patroni/templates/patroni.yml.j2 +++ b/automation/roles/patroni/templates/patroni.yml.j2 @@ -45,9 +45,9 @@ etcd3: {% endif %} {% if tls_cert_generate | default(false) | bool %} protocol: https - cacert: {{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }} - cert: {{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }} - key: {{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }} + cacert: {{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }} + cert: {{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }} + key: {{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }} {% endif %} {% if patroni_etcd_username | default('') | length > 0 %} username: {{ patroni_etcd_username | default('') }} diff --git a/automation/roles/tls_certificate/copy/tasks/main.yml b/automation/roles/tls_certificate/copy/tasks/main.yml index e0081a764..f76c31d53 100644 --- a/automation/roles/tls_certificate/copy/tasks/main.yml +++ b/automation/roles/tls_certificate/copy/tasks/main.yml @@ -27,9 +27,9 @@ group: "etcd" mode: "{{ item.mode }}" loop: - - { index: 0, path: "{{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }}", mode: "0400" } - - { index: 1, path: "{{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }}", mode: "0644" } - - { index: 2, path: "{{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }}", mode: "0644" } + - { index: 0, path: "{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }}", mode: "0400" } + - { index: 1, path: "{{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }}", mode: "0644" } + - { index: 2, path: "{{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }}", mode: "0644" } when: copy_for == 'etcd' - block: diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml index 2f20b82aa..a7e3d65c2 100644 --- a/automation/roles/tls_certificate/generate/tasks/main.yml +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -17,9 +17,9 @@ - "{{ tls_cert_path | default('/etc/tls/server.crt') }}" - "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}" - "{{ tls_ca_privatekey_path | default('/etc/tls/ca.key') }}" - - "{{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }}" - - "{{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }}" - - "{{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }}" + - "{{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }}" + - "{{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }}" + - "{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }}" - "/etc/tls/server.key" - "/etc/tls/server.crt" - "/etc/tls/ca.crt" diff --git a/automation/roles/vip-manager/templates/vip-manager.yml.j2 b/automation/roles/vip-manager/templates/vip-manager.yml.j2 index 93388e57c..89632c4ae 100644 --- a/automation/roles/vip-manager/templates/vip-manager.yml.j2 +++ b/automation/roles/vip-manager/templates/vip-manager.yml.j2 @@ -66,10 +66,10 @@ etcd-password: {{ patroni_etcd_password | default("") }} {% endif %} {% if tls_cert_generate | default(false) | bool %} # when etcd-ca-file is specified, TLS connections to the etcd endpoints will be used. -etcd-ca-file: {{ tls_etcd_ca_cert_path | default('/etc/etcd/ca.crt') }} +etcd-ca-file: {{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }} # when etcd-cert-file and etcd-key-file are specified, we will authenticate at the etcd endpoints using this certificate and key. -etcd-cert-file: {{ tls_etcd_cert_path | default('/etc/etcd/server.crt') }} -etcd-key-file: {{ tls_etcd_privatekey_path | default('/etc/etcd/server.key') }} +etcd-cert-file: {{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }} +etcd-key-file: {{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }} {% endif %} {% endif %} diff --git a/automation/vars/main.yml b/automation/vars/main.yml index af6e06335..0027e0604 100644 --- a/automation/vars/main.yml +++ b/automation/vars/main.yml @@ -182,8 +182,8 @@ tls_privatekey_path: "{{ postgresql_home_dir }}/tls/server.key" tls_ca_cert_path: "{{ postgresql_home_dir }}/tls/ca.crt" tls_owner: "postgres" tls_etcd_cert_path: "/etc/etcd/tls/server.crt" -tls_etcd_ca_cert_path: "/etc/etcd/ca.crt" -tls_etcd_privatekey_path: "/etc/etcd/server.key" +tls_etcd_ca_cert_path: "/etc/etcd/tls/ca.crt" +tls_etcd_privatekey_path: "/etc/etcd/tls/server.key" # PostgreSQL variables postgresql_version: 17 From aa6bb8ced44ea049249c1f9f4afb4cc8a2787dbb Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Sat, 28 Dec 2024 11:41:38 +0000 Subject: [PATCH 28/36] update defaults for postgres tls path --- automation/roles/tls_certificate/copy/tasks/main.yml | 6 +++--- .../roles/tls_certificate/generate/tasks/main.yml | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/automation/roles/tls_certificate/copy/tasks/main.yml b/automation/roles/tls_certificate/copy/tasks/main.yml index f76c31d53..16eee83e8 100644 --- a/automation/roles/tls_certificate/copy/tasks/main.yml +++ b/automation/roles/tls_certificate/copy/tasks/main.yml @@ -49,7 +49,7 @@ group: "{{ tls_owner }}" mode: "{{ item.mode }}" loop: - - { index: 0, path: "{{ tls_privatekey_path | default('/etc/tls/server.key') }}", mode: "0400" } - - { index: 1, path: "{{ tls_cert_path | default('/etc/tls/server.crt') }}", mode: "0644" } - - { index: 2, path: "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}", mode: "0644" } + - { index: 0, path: "{{ tls_privatekey_path | default(postgresql_home_dir + '/tls/server.key') }}", mode: "0400" } + - { index: 1, path: "{{ tls_cert_path | default(postgresql_home_dir + '/tls/server.crt') }}", mode: "0644" } + - { index: 2, path: "{{ tls_ca_cert_path | default(postgresql_home_dir + '/tls/ca.crt') }}", mode: "0644" } when: copy_for == 'pg' diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml index a7e3d65c2..071ba2aa9 100644 --- a/automation/roles/tls_certificate/generate/tasks/main.yml +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -8,21 +8,21 @@ delay: 5 retries: 3 -- name: "Clean up existing certificates" +- name: Clean up existing certificates (if any) ansible.builtin.file: path: "{{ item }}" state: absent loop: - - "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" - - "{{ tls_cert_path | default('/etc/tls/server.crt') }}" - - "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}" - - "{{ tls_ca_privatekey_path | default('/etc/tls/ca.key') }}" + - "{{ tls_privatekey_path | default(postgresql_home_dir + '/tls/server.key') }}" + - "{{ tls_cert_path | default(postgresql_home_dir + '/tls/server.crt') }}" + - "{{ tls_ca_cert_path | default(postgresql_home_dir + '/tls/ca.crt') }}" - "{{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }}" - "{{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }}" - "{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }}" - "/etc/tls/server.key" - "/etc/tls/server.crt" - "/etc/tls/ca.crt" + - "etc/tls/ca.key" - ansible.builtin.set_fact: all_san_entries: [] From d8c6067b6e8a8916aa0dd19f665d3781dee02c0f Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Sat, 28 Dec 2024 11:46:49 +0000 Subject: [PATCH 29/36] fix typo in tls path --- automation/roles/tls_certificate/generate/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml index 071ba2aa9..324c05619 100644 --- a/automation/roles/tls_certificate/generate/tasks/main.yml +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -22,7 +22,7 @@ - "/etc/tls/server.key" - "/etc/tls/server.crt" - "/etc/tls/ca.crt" - - "etc/tls/ca.key" + - "/etc/tls/ca.key" - ansible.builtin.set_fact: all_san_entries: [] From 7d354d3263f95b72fb73dc5cb3c48124a2fee879 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Sat, 28 Dec 2024 12:14:26 +0000 Subject: [PATCH 30/36] Update patroni.yml.j2 --- automation/roles/patroni/templates/patroni.yml.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/automation/roles/patroni/templates/patroni.yml.j2 b/automation/roles/patroni/templates/patroni.yml.j2 index 79106ba51..c06b1304f 100644 --- a/automation/roles/patroni/templates/patroni.yml.j2 +++ b/automation/roles/patroni/templates/patroni.yml.j2 @@ -43,12 +43,14 @@ etcd3: {% if dcs_exists|bool %} hosts: {% for etcd_hosts in patroni_etcd_hosts %}{{etcd_hosts.host}}:{{etcd_hosts.port}}{% if not loop.last %},{% endif %}{% endfor %} {% endif %} + {% if tls_cert_generate | default(false) | bool %} protocol: https cacert: {{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }} cert: {{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }} key: {{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }} {% endif %} + {% if patroni_etcd_username | default('') | length > 0 %} username: {{ patroni_etcd_username | default('') }} {% endif %} From e191f9c1ecedbbd5311dcb5d4f124215bedf18ce Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Sat, 28 Dec 2024 12:37:38 +0000 Subject: [PATCH 31/36] patroni.yml: use postgres tls path --- automation/roles/patroni/templates/patroni.yml.j2 | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/automation/roles/patroni/templates/patroni.yml.j2 b/automation/roles/patroni/templates/patroni.yml.j2 index c06b1304f..d90145179 100644 --- a/automation/roles/patroni/templates/patroni.yml.j2 +++ b/automation/roles/patroni/templates/patroni.yml.j2 @@ -46,11 +46,10 @@ etcd3: {% if tls_cert_generate | default(false) | bool %} protocol: https - cacert: {{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }} - cert: {{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }} - key: {{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }} + cacert: {{ tls_ca_cert_path | default(postgresql_home_dir + '/tls/ca.crt') }} + cert: {{ tls_cert_path | default(postgresql_home_dir + '/tls/server.crt') }} + key: {{ tls_privatekey_path | default(postgresql_home_dir + '/tls/server.key') }} {% endif %} - {% if patroni_etcd_username | default('') | length > 0 %} username: {{ patroni_etcd_username | default('') }} {% endif %} From 7b0077a2914bb9ffd85aa6b48ee1582fb3bc1fac Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Sat, 28 Dec 2024 15:52:30 +0000 Subject: [PATCH 32/36] tls for confd --- .../roles/confd/templates/confd.toml.j2 | 16 +++++---- .../roles/patroni/templates/patroni.yml.j2 | 6 ++-- .../roles/tls_certificate/copy/tasks/main.yml | 24 ++++++------- .../tls_certificate/generate/tasks/main.yml | 35 +++++++++---------- automation/vars/main.yml | 6 ++-- 5 files changed, 45 insertions(+), 42 deletions(-) diff --git a/automation/roles/confd/templates/confd.toml.j2 b/automation/roles/confd/templates/confd.toml.j2 index dcd8e39f9..0e91e852f 100644 --- a/automation/roles/confd/templates/confd.toml.j2 +++ b/automation/roles/confd/templates/confd.toml.j2 @@ -1,22 +1,26 @@ backend = "etcdv3" -interval = 10 -watch = true nodes = [ -{% if not dcs_exists|bool and dcs_type == 'etcd' %} +{% if not dcs_exists|bool %} {% for host in groups['etcd_cluster'] %} "{{ patroni_etcd_protocol | default('http', true) }}://{{ hostvars[host]['inventory_hostname'] }}:2379", {% endfor %} {% endif %} -{% if dcs_exists|bool and dcs_type == 'etcd' %} +{% if dcs_exists|bool %} {% for etcd_hosts in patroni_etcd_hosts %} "{{ patroni_etcd_protocol | default('http', true) }}://{{etcd_hosts.host}}:{{etcd_hosts.port}}", {% endfor %} {% endif %} ] -{% if dcs_exists|bool and dcs_type == 'etcd' %} +{% if tls_cert_generate | default(false) | bool %} +scheme = "https" +client_cakeys = "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}" +client_cert = "{{ tls_cert_path | default('/etc/tls/server.crt') }}" +client_key = "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" +{% endif %} {% if patroni_etcd_username | default('') | length > 0 %} basic_auth = true username = "{{ patroni_etcd_username | default('') }}" password = "{{ patroni_etcd_password | default('') }}" {% endif %} -{% endif %} \ No newline at end of file +watch = true +interval = 10 diff --git a/automation/roles/patroni/templates/patroni.yml.j2 b/automation/roles/patroni/templates/patroni.yml.j2 index d90145179..d519fc806 100644 --- a/automation/roles/patroni/templates/patroni.yml.j2 +++ b/automation/roles/patroni/templates/patroni.yml.j2 @@ -46,9 +46,9 @@ etcd3: {% if tls_cert_generate | default(false) | bool %} protocol: https - cacert: {{ tls_ca_cert_path | default(postgresql_home_dir + '/tls/ca.crt') }} - cert: {{ tls_cert_path | default(postgresql_home_dir + '/tls/server.crt') }} - key: {{ tls_privatekey_path | default(postgresql_home_dir + '/tls/server.key') }} + cacert: {{ tls_ca_cert_path | default('/etc/tls/ca.crt') }} + cert: {{ tls_cert_path | default('/etc/tls/server.crt') }} + key: {{ tls_privatekey_path | default('/etc/tls/server.key') }} {% endif %} {% if patroni_etcd_username | default('') | length > 0 %} username: {{ patroni_etcd_username | default('') }} diff --git a/automation/roles/tls_certificate/copy/tasks/main.yml b/automation/roles/tls_certificate/copy/tasks/main.yml index 16eee83e8..9960d5723 100644 --- a/automation/roles/tls_certificate/copy/tasks/main.yml +++ b/automation/roles/tls_certificate/copy/tasks/main.yml @@ -6,14 +6,14 @@ delegate_to: "{{ groups.master[0] }}" register: tls_files loop: - - "/etc/tls/server.key" - - "/etc/tls/server.crt" - - "/etc/tls/ca.crt" + - "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" + - "{{ tls_cert_path | default('/etc/tls/server.crt') }}" + - "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}" - block: - - name: Create directory {{ tls_etcd_privatekey_path | dirname }} + - name: Create directory {{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') | dirname }} ansible.builtin.file: - dest: "{{ tls_etcd_privatekey_path | dirname }}" + dest: "{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') | dirname }}" state: directory owner: "etcd" group: "etcd" @@ -33,12 +33,12 @@ when: copy_for == 'etcd' - block: - - name: Create directory {{ tls_privatekey_path | dirname }} + - name: Create directory {{ tls_privatekey_path | default('/etc/tls/server.key') | dirname }} ansible.builtin.file: - dest: "{{ tls_privatekey_path | dirname }}" + dest: "{{ tls_privatekey_path | default('/etc/tls/server.key') | dirname }}" state: directory - owner: "{{ tls_owner }}" - group: "{{ tls_owner }}" + owner: "root" + group: "root" mode: "0755" - name: Copy PostgreSQL TLS certificate, key and CA to all nodes @@ -49,7 +49,7 @@ group: "{{ tls_owner }}" mode: "{{ item.mode }}" loop: - - { index: 0, path: "{{ tls_privatekey_path | default(postgresql_home_dir + '/tls/server.key') }}", mode: "0400" } - - { index: 1, path: "{{ tls_cert_path | default(postgresql_home_dir + '/tls/server.crt') }}", mode: "0644" } - - { index: 2, path: "{{ tls_ca_cert_path | default(postgresql_home_dir + '/tls/ca.crt') }}", mode: "0644" } + - { index: 0, path: "{{ tls_privatekey_path | default('/etc/tls/server.key') }}", mode: "0400" } + - { index: 1, path: "{{ tls_cert_path | default('/etc/tls/server.crt') }}", mode: "0644" } + - { index: 2, path: "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}", mode: "0644" } when: copy_for == 'pg' diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml index 324c05619..b81d2bee0 100644 --- a/automation/roles/tls_certificate/generate/tasks/main.yml +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -13,16 +13,13 @@ path: "{{ item }}" state: absent loop: - - "{{ tls_privatekey_path | default(postgresql_home_dir + '/tls/server.key') }}" - - "{{ tls_cert_path | default(postgresql_home_dir + '/tls/server.crt') }}" - - "{{ tls_ca_cert_path | default(postgresql_home_dir + '/tls/ca.crt') }}" + - "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" + - "{{ tls_cert_path | default('/etc/tls/server.crt') }}" + - "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}" + - "{{ tls_ca_key_path | default('/etc/tls/ca.key') }}" - "{{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }}" - "{{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }}" - "{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }}" - - "/etc/tls/server.key" - - "/etc/tls/server.crt" - - "/etc/tls/ca.crt" - - "/etc/tls/ca.key" - ansible.builtin.set_fact: all_san_entries: [] @@ -50,19 +47,21 @@ ######## Generate CA ######## - name: "Ensure TLS directory exist" ansible.builtin.file: - path: "/etc/tls" + dest: "{{ tls_privatekey_path | default('/etc/tls/server.key') | dirname }}" state: directory - mode: "0700" + owner: "root" + group: "root" + mode: "0755" - name: "Generate CA private key" community.crypto.openssl_privatekey: - path: "/etc/tls/ca.key" + path: "{{ tls_ca_key_path | default('/etc/tls/ca.key') }}" size: "{{ tls_privatekey_size | default(4096) }}" type: "{{ tls_privatekey_type | default('RSA') }}" - name: "Create CSR for CA certificate" community.crypto.openssl_csr_pipe: - privatekey_path: "/etc/tls/ca.key" + privatekey_path: "{{ tls_ca_key_path | default('/etc/tls/ca.key') }}" common_name: PostgreSQL CA use_common_name_for_san: false basic_constraints: @@ -75,22 +74,22 @@ - name: "Create self-signed CA certificate from CSR" community.crypto.x509_certificate: - path: "/etc/tls/ca.crt" + path: "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}" csr_content: "{{ ca_csr.csr }}" - privatekey_path: "/etc/tls/ca.key" + privatekey_path: "{{ tls_ca_key_path | default('/etc/tls/ca.key') }}" provider: "{{ tls_cert_provider | default('selfsigned') }}" entrust_not_after: "+{{ tls_cert_valid_days | default(3650) }}d" ######## Generate Server cert/key ######## - name: "Create server private key" community.crypto.openssl_privatekey: - path: "/etc/tls/server.key" + path: "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" size: "{{ tls_privatekey_size | default(4096) }}" type: "{{ tls_privatekey_type | default('RSA') }}" - name: "Create server CSR" community.crypto.openssl_csr_pipe: - privatekey_path: "/etc/tls/server.key" + privatekey_path: "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" common_name: "{{ patroni_cluster_name }}" key_usage: - digitalSignature @@ -110,15 +109,15 @@ community.crypto.x509_certificate_pipe: csr_content: "{{ csr.csr }}" provider: ownca - ownca_path: "/etc/tls/ca.crt" - ownca_privatekey_path: "/etc/tls/ca.key" + ownca_path: "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}" + ownca_privatekey_path: "{{ tls_ca_key_path | default('/etc/tls/ca.key') }}" ownca_not_after: +{{ tls_cert_valid_days | default(3650) }}d ownca_not_before: "-1d" register: certificate - name: "Write server certificate" ansible.builtin.copy: - dest: "/etc/tls/server.crt" + dest: "{{ tls_cert_path | default('/etc/tls/server.crt') }}" content: "{{ certificate.certificate }}" delegate_to: "{{ groups.master[0] }}" run_once: true diff --git a/automation/vars/main.yml b/automation/vars/main.yml index 0027e0604..ad1b812b7 100644 --- a/automation/vars/main.yml +++ b/automation/vars/main.yml @@ -177,9 +177,9 @@ consul_services: # TLS certificate (for PostgreSQL, PgBouncer and etcd) tls_cert_generate: true tls_cert_valid_days: 3650 -tls_cert_path: "{{ postgresql_home_dir }}/tls/server.crt" -tls_privatekey_path: "{{ postgresql_home_dir }}/tls/server.key" -tls_ca_cert_path: "{{ postgresql_home_dir }}/tls/ca.crt" +tls_cert_path: "/etc/tls/server.crt" +tls_privatekey_path: "/etc/tls/server.key" +tls_ca_cert_path: "/etc/tls/ca.crt" tls_owner: "postgres" tls_etcd_cert_path: "/etc/etcd/tls/server.crt" tls_etcd_ca_cert_path: "/etc/etcd/tls/ca.crt" From da7c6e6c78f64bc28cff5cce8ade44712f07ea56 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Sat, 28 Dec 2024 16:11:29 +0000 Subject: [PATCH 33/36] update tls dir path for vip-manager --- automation/roles/tls_certificate/copy/tasks/main.yml | 8 ++++---- automation/roles/tls_certificate/generate/tasks/main.yml | 2 +- automation/roles/vip-manager/templates/vip-manager.yml.j2 | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/automation/roles/tls_certificate/copy/tasks/main.yml b/automation/roles/tls_certificate/copy/tasks/main.yml index 9960d5723..6ada9d23d 100644 --- a/automation/roles/tls_certificate/copy/tasks/main.yml +++ b/automation/roles/tls_certificate/copy/tasks/main.yml @@ -13,7 +13,7 @@ - block: - name: Create directory {{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') | dirname }} ansible.builtin.file: - dest: "{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') | dirname }}" + path: "{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') | dirname }}" state: directory owner: "etcd" group: "etcd" @@ -35,10 +35,10 @@ - block: - name: Create directory {{ tls_privatekey_path | default('/etc/tls/server.key') | dirname }} ansible.builtin.file: - dest: "{{ tls_privatekey_path | default('/etc/tls/server.key') | dirname }}" + path: "{{ tls_privatekey_path | default('/etc/tls/server.key') | dirname }}" state: directory - owner: "root" - group: "root" + owner: "{{ tls_owner }}" + group: "{{ tls_owner }}" mode: "0755" - name: Copy PostgreSQL TLS certificate, key and CA to all nodes diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml index b81d2bee0..406d78727 100644 --- a/automation/roles/tls_certificate/generate/tasks/main.yml +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -47,7 +47,7 @@ ######## Generate CA ######## - name: "Ensure TLS directory exist" ansible.builtin.file: - dest: "{{ tls_privatekey_path | default('/etc/tls/server.key') | dirname }}" + path: "{{ tls_privatekey_path | default('/etc/tls/server.key') | dirname }}" state: directory owner: "root" group: "root" diff --git a/automation/roles/vip-manager/templates/vip-manager.yml.j2 b/automation/roles/vip-manager/templates/vip-manager.yml.j2 index 89632c4ae..0cc1929cc 100644 --- a/automation/roles/vip-manager/templates/vip-manager.yml.j2 +++ b/automation/roles/vip-manager/templates/vip-manager.yml.j2 @@ -66,10 +66,10 @@ etcd-password: {{ patroni_etcd_password | default("") }} {% endif %} {% if tls_cert_generate | default(false) | bool %} # when etcd-ca-file is specified, TLS connections to the etcd endpoints will be used. -etcd-ca-file: {{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }} +etcd-ca-file: {{ tls_ca_cert_path | default('/etc/tls/ca.crt') }} # when etcd-cert-file and etcd-key-file are specified, we will authenticate at the etcd endpoints using this certificate and key. -etcd-cert-file: {{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }} -etcd-key-file: {{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }} +etcd-cert-file: {{ tls_cert_path | default('/etc/tls/server.crt') }} +etcd-key-file: {{ tls_privatekey_path | default('/etc/tls/server.key') }} {% endif %} {% endif %} From 9ac40685f061d0bd160f9352ef8df1e756caf6e9 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Mon, 30 Dec 2024 15:40:55 +0000 Subject: [PATCH 34/36] Generate subjectAltName entries for all hosts --- .../tls_certificate/generate/tasks/main.yml | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml index 406d78727..786fb39c6 100644 --- a/automation/roles/tls_certificate/generate/tasks/main.yml +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -21,24 +21,18 @@ - "{{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }}" - "{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }}" -- ansible.builtin.set_fact: - all_san_entries: [] - -- name: "Gather host-specific network information" - ansible.builtin.set_fact: - san_entry: >- - DNS:{{ ansible_hostname }},DNS:{{ ansible_fqdn }},IP:{{ inventory_hostname }} - - block: - - name: "Aggregate all subjectAltName entries" - ansible.builtin.set_fact: - all_san_entries: "{{ all_san_entries + [hostvars[item].san_entry] }}" - with_items: "{{ ansible_play_hosts }}" - - - name: "Join subjectAltName entries into a single string" + - name: "Generate subjectAltName entries for all hosts" ansible.builtin.set_fact: - subject_alt_name: "{{ all_san_entries | join(',') + ',DNS:localhost,IP:127.0.0.1' }}" - when: ansible_play_hosts | length > 1 + subject_alt_name: >- + {{ + ( + ansible_play_hosts | map('extract', hostvars, 'ansible_hostname') | map('regex_replace', '^', 'DNS:') | list + + ansible_play_hosts | map('extract', hostvars, 'ansible_fqdn') | map('regex_replace', '^', 'DNS:') | list + + ansible_play_hosts | map('extract', hostvars, 'inventory_hostname') | map('regex_replace', '^', 'IP:') | list + + ['DNS:localhost', 'IP:127.0.0.1'] + ) | unique | join(',') + }} - name: "Display Certificate subjectAltName future value" ansible.builtin.debug: From c12effb0a014c1b2aac4e34f318e8aae509a8b1a Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Mon, 30 Dec 2024 16:22:41 +0000 Subject: [PATCH 35/36] remove "copy_for" variable and extra tasks --- automation/add_pgnode.yml | 2 - automation/deploy_pgcluster.yml | 2 - automation/roles/etcd/tasks/main.yml | 5 +- .../roles/tls_certificate/copy/tasks/main.yml | 60 ++++++------------- 4 files changed, 22 insertions(+), 47 deletions(-) diff --git a/automation/add_pgnode.yml b/automation/add_pgnode.yml index a1ceae9f8..9dd7c15f1 100644 --- a/automation/add_pgnode.yml +++ b/automation/add_pgnode.yml @@ -236,8 +236,6 @@ when: pg_probackup_install|bool - role: tls_certificate/copy - vars: - copy_for: "pg" when: tls_cert_generate|bool - role: pgbouncer diff --git a/automation/deploy_pgcluster.yml b/automation/deploy_pgcluster.yml index 4625428fa..75bd8908f 100644 --- a/automation/deploy_pgcluster.yml +++ b/automation/deploy_pgcluster.yml @@ -361,8 +361,6 @@ - role: tls_certificate/copy when: tls_cert_generate|bool - vars: - copy_for: "pg" - role: pgbouncer when: pgbouncer_install|bool diff --git a/automation/roles/etcd/tasks/main.yml b/automation/roles/etcd/tasks/main.yml index 80ceae29f..ddb0a7187 100644 --- a/automation/roles/etcd/tasks/main.yml +++ b/automation/roles/etcd/tasks/main.yml @@ -90,7 +90,10 @@ ansible.builtin.include_role: name: ../roles/tls_certificate/copy vars: - copy_for: "etcd" + copy_tls_cert_path: "{{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }}" + copy_tls_ca_cert_path: "{{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }}" + copy_tls_privatekey_path: "{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }}" + copy_tls_owner: "etcd" when: tls_cert_generate|bool tags: etcd, etcd_conf diff --git a/automation/roles/tls_certificate/copy/tasks/main.yml b/automation/roles/tls_certificate/copy/tasks/main.yml index 6ada9d23d..f52c9c68f 100644 --- a/automation/roles/tls_certificate/copy/tasks/main.yml +++ b/automation/roles/tls_certificate/copy/tasks/main.yml @@ -10,46 +10,22 @@ - "{{ tls_cert_path | default('/etc/tls/server.crt') }}" - "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}" -- block: - - name: Create directory {{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') | dirname }} - ansible.builtin.file: - path: "{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') | dirname }}" - state: directory - owner: "etcd" - group: "etcd" - mode: "0755" +- name: Create directory {{ copy_tls_privatekey_path | default(tls_privatekey_path | default('/etc/tls/server.key')) | dirname }} + ansible.builtin.file: + path: "{{ copy_tls_privatekey_path | default(tls_privatekey_path | default('/etc/tls/server.key')) | dirname }}" + state: directory + owner: "{{ copy_tls_owner | default(tls_owner | default('postgres')) }}" + group: "{{ copy_tls_owner | default(tls_owner | default('postgres')) }}" + mode: "0755" - - name: Copy etcd TLS certificate, key and CA to all nodes from memory - ansible.builtin.copy: - content: "{{ tls_files.results[item.index].content | b64decode }}" - dest: "{{ item.path }}" - owner: "etcd" - group: "etcd" - mode: "{{ item.mode }}" - loop: - - { index: 0, path: "{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }}", mode: "0400" } - - { index: 1, path: "{{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }}", mode: "0644" } - - { index: 2, path: "{{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }}", mode: "0644" } - when: copy_for == 'etcd' - -- block: - - name: Create directory {{ tls_privatekey_path | default('/etc/tls/server.key') | dirname }} - ansible.builtin.file: - path: "{{ tls_privatekey_path | default('/etc/tls/server.key') | dirname }}" - state: directory - owner: "{{ tls_owner }}" - group: "{{ tls_owner }}" - mode: "0755" - - - name: Copy PostgreSQL TLS certificate, key and CA to all nodes - ansible.builtin.copy: - content: "{{ tls_files.results[item.index].content | b64decode }}" - dest: "{{ item.path }}" - owner: "{{ tls_owner }}" - group: "{{ tls_owner }}" - mode: "{{ item.mode }}" - loop: - - { index: 0, path: "{{ tls_privatekey_path | default('/etc/tls/server.key') }}", mode: "0400" } - - { index: 1, path: "{{ tls_cert_path | default('/etc/tls/server.crt') }}", mode: "0644" } - - { index: 2, path: "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}", mode: "0644" } - when: copy_for == 'pg' +- name: Copy PostgreSQL TLS certificate, key and CA to all nodes + ansible.builtin.copy: + content: "{{ tls_files.results[item.index].content | b64decode }}" + dest: "{{ item.path }}" + owner: "{{ copy_tls_owner | default(tls_owner | default('postgres')) }}" + group: "{{ copy_tls_owner | default(tls_owner | default('postgres')) }}" + mode: "{{ item.mode }}" + loop: + - { index: 1, path: "{{ copy_tls_cert_path | default(tls_cert_path | default('/etc/tls/server.crt')) }}", mode: "0644" } + - { index: 2, path: "{{ copy_tls_ca_cert_path | default(tls_ca_cert_path | default('/etc/tls/ca.crt')) }}", mode: "0644" } + - { index: 0, path: "{{ copy_tls_privatekey_path | default(tls_privatekey_path | default('/etc/tls/server.key')) }}", mode: "0400" } From ec00506b68e215f35578cf5c85589372ee784049 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Mon, 30 Dec 2024 16:44:21 +0000 Subject: [PATCH 36/36] Add tls tags --- automation/roles/tls_certificate/copy/tasks/main.yml | 3 +++ automation/roles/tls_certificate/generate/tasks/main.yml | 7 +++++-- automation/tags.md | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/automation/roles/tls_certificate/copy/tasks/main.yml b/automation/roles/tls_certificate/copy/tasks/main.yml index f52c9c68f..251431bfe 100644 --- a/automation/roles/tls_certificate/copy/tasks/main.yml +++ b/automation/roles/tls_certificate/copy/tasks/main.yml @@ -9,6 +9,7 @@ - "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" - "{{ tls_cert_path | default('/etc/tls/server.crt') }}" - "{{ tls_ca_cert_path | default('/etc/tls/ca.crt') }}" + tags: tls, tls_cert_copy - name: Create directory {{ copy_tls_privatekey_path | default(tls_privatekey_path | default('/etc/tls/server.key')) | dirname }} ansible.builtin.file: @@ -17,6 +18,7 @@ owner: "{{ copy_tls_owner | default(tls_owner | default('postgres')) }}" group: "{{ copy_tls_owner | default(tls_owner | default('postgres')) }}" mode: "0755" + tags: tls, tls_cert_copy - name: Copy PostgreSQL TLS certificate, key and CA to all nodes ansible.builtin.copy: @@ -29,3 +31,4 @@ - { index: 1, path: "{{ copy_tls_cert_path | default(tls_cert_path | default('/etc/tls/server.crt')) }}", mode: "0644" } - { index: 2, path: "{{ copy_tls_ca_cert_path | default(tls_ca_cert_path | default('/etc/tls/ca.crt')) }}", mode: "0644" } - { index: 0, path: "{{ copy_tls_privatekey_path | default(tls_privatekey_path | default('/etc/tls/server.key')) }}", mode: "0400" } + tags: tls, tls_cert_copy diff --git a/automation/roles/tls_certificate/generate/tasks/main.yml b/automation/roles/tls_certificate/generate/tasks/main.yml index 786fb39c6..d8b9037ca 100644 --- a/automation/roles/tls_certificate/generate/tasks/main.yml +++ b/automation/roles/tls_certificate/generate/tasks/main.yml @@ -7,6 +7,7 @@ until: pack_status is success delay: 5 retries: 3 + tags: tls, tls_cert_generate - name: Clean up existing certificates (if any) ansible.builtin.file: @@ -20,6 +21,7 @@ - "{{ tls_etcd_cert_path | default('/etc/etcd/tls/server.crt') }}" - "{{ tls_etcd_ca_cert_path | default('/etc/etcd/tls/ca.crt') }}" - "{{ tls_etcd_privatekey_path | default('/etc/etcd/tls/server.key') }}" + tags: tls, tls_cert_generate - block: - name: "Generate subjectAltName entries for all hosts" @@ -38,7 +40,7 @@ ansible.builtin.debug: var: subject_alt_name -######## Generate CA ######## + ######## Generate CA ######## - name: "Ensure TLS directory exist" ansible.builtin.file: path: "{{ tls_privatekey_path | default('/etc/tls/server.key') | dirname }}" @@ -74,7 +76,7 @@ provider: "{{ tls_cert_provider | default('selfsigned') }}" entrust_not_after: "+{{ tls_cert_valid_days | default(3650) }}d" -######## Generate Server cert/key ######## + ######## Generate Server cert/key ######## - name: "Create server private key" community.crypto.openssl_privatekey: path: "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" @@ -115,3 +117,4 @@ content: "{{ certificate.certificate }}" delegate_to: "{{ groups.master[0] }}" run_once: true + tags: tls, tls_cert_generate diff --git a/automation/tags.md b/automation/tags.md index fabf2cfec..ed65267ab 100644 --- a/automation/tags.md +++ b/automation/tags.md @@ -108,3 +108,6 @@ - ssh_public_keys - mount, zpool - perf, flamegraph +- tls + - tls_cert_generate + - tls_cert_copy