From 598b5c44a546c6fc82d88e0c2104aa4ebcacc547 Mon Sep 17 00:00:00 2001 From: ace Date: Wed, 8 Feb 2023 02:13:12 +0300 Subject: [PATCH] initial commit --- .gitignore | 1 + README.md | 5 + defaults/main.yaml | 58 ++++++++++ handlers/main.yaml | 9 ++ meta/main.yaml | 0 tasks/Debian/main.yaml | 37 +++++++ tasks/RedHat/cacert.yaml | 159 ++++++++++++++++++++++++++++ tasks/RedHat/main.yaml | 35 ++++++ tasks/config.yaml | 40 +++++++ tasks/main.yaml | 35 ++++++ tasks/user.yaml | 17 +++ templates/13-pg_hba.conf.j2 | 98 +++++++++++++++++ templates/13-postgresql.conf.j2 | 7 ++ templates/13-postgresql.ssl.conf.j2 | 3 + templates/14-pg_hba.conf.j2 | 98 +++++++++++++++++ templates/14-postgresql.conf.j2 | 7 ++ templates/14-postgresql.ssl.conf.j2 | 3 + templates/15-pg_hba.conf.j2 | 98 +++++++++++++++++ templates/15-postgresql.conf.j2 | 7 ++ templates/15-postgresql.ssl.conf.j2 | 3 + vars/Debian.yaml | 10 ++ vars/RedHat.yaml | 4 + vars/main.yaml | 3 + 23 files changed, 737 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 defaults/main.yaml create mode 100644 handlers/main.yaml create mode 100644 meta/main.yaml create mode 100644 tasks/Debian/main.yaml create mode 100644 tasks/RedHat/cacert.yaml create mode 100644 tasks/RedHat/main.yaml create mode 100644 tasks/config.yaml create mode 100644 tasks/main.yaml create mode 100644 tasks/user.yaml create mode 100644 templates/13-pg_hba.conf.j2 create mode 100644 templates/13-postgresql.conf.j2 create mode 100644 templates/13-postgresql.ssl.conf.j2 create mode 100644 templates/14-pg_hba.conf.j2 create mode 100644 templates/14-postgresql.conf.j2 create mode 100644 templates/14-postgresql.ssl.conf.j2 create mode 100644 templates/15-pg_hba.conf.j2 create mode 100644 templates/15-postgresql.conf.j2 create mode 100644 templates/15-postgresql.ssl.conf.j2 create mode 100644 vars/Debian.yaml create mode 100644 vars/RedHat.yaml create mode 100644 vars/main.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba6d390 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.galaxy_install_info diff --git a/README.md b/README.md new file mode 100644 index 0000000..694683b --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +Setup PostgreSQL for RHEL8 +Supported PostgreSQL versions: + - 13 + - 14 + - 15 diff --git a/defaults/main.yaml b/defaults/main.yaml new file mode 100644 index 0000000..8a283aa --- /dev/null +++ b/defaults/main.yaml @@ -0,0 +1,58 @@ +postgresql_version: "14.6" + +# Options +postgresql_superuser_password: "postgres" + +# SSL options +postgresql_ssl: yes +postgresql_ssl_path: "/var/lib/pgsql/{{ postgresql_major_version }}" +postgresql_self_signed_cert: yes +postgresql_self_signed_cert_name: "cert" + +## Backup options +postgresql_wal_g_install: no + +postgresql_password_encryption_algorithm: "scram-sha-256" +postgresql_default_parameters: + listen_addresses: '*' + max_connections: '1000' + superuser_reserved_connections: '5' + shared_buffers: '{{ (ansible_memory_mb.real.total * 0.25) | round | int }}MB' + huge_pages: 'try' + dynamic_shared_memory_type: 'posix' + max_worker_processes: '{{ ansible_processor_vcpus }}' + max_parallel_workers: '{{ ansible_processor_vcpus }}' + max_parallel_workers_per_gather: '{{ (ansible_processor_vcpus / 2) | round | int }}' + max_parallel_maintenance_workers: '{{ (ansible_processor_vcpus / 2) | round | int }}' + max_wal_size: '1GB' + min_wal_size: '80MB' + log_destination: 'stderr' + logging_collector: 'on' + log_directory: 'log' + log_filename: 'postgresql-%a.log' + log_rotation_age: '1d' + log_rotation_size: '0' + log_truncate_on_rotation: 'on' + log_line_prefix: '%m [%p] ' + log_timezone: 'Europe/Moscow' + datestyle: 'iso, mdy' + timezone: 'Europe/Moscow' + lc_messages: 'en_US.UTF-8' + lc_monetary: 'en_US.UTF-8' + lc_numeric: 'en_US.UTF-8' + lc_time: 'en_US.UTF-8' + default_text_search_config: 'pg_catalog.english' + password_encryption: '{{ postgresql_password_encryption_algorithm }}' + +postgresql_backup_parameters: + archive_command: "{{ postgresql_archive_command | default('cd .')}}" + restore_command: "{{ postgresql_restore_command | default('cd .') }}" + archive_mode: on + +postgresql_log_dir: "/var/log/postgresql" + +postgresql_supported_versions: + - 13 + - 14 + - 15 + diff --git a/handlers/main.yaml b/handlers/main.yaml new file mode 100644 index 0000000..03ec50e --- /dev/null +++ b/handlers/main.yaml @@ -0,0 +1,9 @@ +- block: + - name: Restart PostgreSQL + throttle: 1 + ansible.builtin.systemd: + state: restarted + daemon_reload: yes + name: "postgresql-{{ postgresql_major_version }}" + when: "not postgresql_setup.changed or not postgresql_enable_and_start.changed" + diff --git a/meta/main.yaml b/meta/main.yaml new file mode 100644 index 0000000..e69de29 diff --git a/tasks/Debian/main.yaml b/tasks/Debian/main.yaml new file mode 100644 index 0000000..09e55c8 --- /dev/null +++ b/tasks/Debian/main.yaml @@ -0,0 +1,37 @@ +- name: Add gpg package + apt: + name: gpg + +- name: Add gpg keys for postgresql + ansible.builtin.apt_key: + url: "{{ item.url }}" + keyring: "{{ item.keyring }}" + loop: "{{ postgresql_apt_key }}" + +- name: Add Hashicorp repository + apt_repository: + repo: "{{ item.repo }}" + state: present + filename: "{{ item.filename }}" + update_cache: yes + loop: "{{ postgresql_apt_repository }}" + +- name: Check if Patroni is installed + ansible.builtin.shell: dpkg-query -l {{ postgresql_package_name }} 2>&1 | grep {{ postgresql_version }} + ignore_errors: True + register: is_postgresql + changed_when: is_postgresql.rc != 0 + failed_when: False + +- name: Mask Patroni before install + ansible.builtin.systemd: + name: "{{ postgresql_package_name }}" + masked: yes + when: is_postgresql.rc != 0 + +- name: "Install {{ postgresql_package_name }} {{ postgresql_version }}" + apt: + name: "{{ postgresql_package }}" + update_cache: yes + register: postgresql_setup + when: is_postgresql.rc != 0 diff --git a/tasks/RedHat/cacert.yaml b/tasks/RedHat/cacert.yaml new file mode 100644 index 0000000..393a2e9 --- /dev/null +++ b/tasks/RedHat/cacert.yaml @@ -0,0 +1,159 @@ +- name: Check if ssl dir exist + file: + name: "{{ postgresql_ssl_path }}" + state: directory + owner: postgres + group: postgres + when: postgresql_ssl + +- name: Add predefined ssl cert for PostgreSQL + copy: + src: "{{ postgresql_cert_name }}" + dest: "{{ postgresql_ssl_path }}/{{ postgresql_cert_name }}" + owner: postgres + group: postgres + notify: Restart PostgreSQL + when: postgresql_cert is defined + +- name: Generate OpenSSL key and cert for PostgreSQL + when: "inventory_hostname == groups.postgresql|first" + block: + - name: Generate an OpenSSL private CA key with the default values (4096 bits, RSA) + community.crypto.openssl_privatekey: + path: "{{ postgresql_ssl_path }}/CA-{{ postgresql_self_signed_cert_name }}.key" + owner: postgres + group: postgres + when: postgresql_cert is not defined + register: postgresql_ca_key_gen + + - name: Generate an OpenSSL Certificate Signing Request + community.crypto.openssl_csr: + path: "{{ postgresql_ssl_path }}/CA-{{ postgresql_self_signed_cert_name }}.csr" + privatekey_path: "{{ postgresql_ssl_path }}/CA-{{ postgresql_self_signed_cert_name }}.key" + use_common_name_for_san: false + basic_constraints: + - 'CA:TRUE' + basic_constraints_critical: yes + key_usage: + - keyCertSign + key_usage_critical: true + common_name: "CA-{{ postgresql_self_signed_cert_name }}" + owner: postgres + group: postgres + register: postgresql_ca_csr + + - name: Generate a Self Signed OpenSSL CA certificate + community.crypto.x509_certificate: + path: "{{ postgresql_ssl_path }}/CA-{{ postgresql_self_signed_cert_name }}.crt" + csr_path: "{{ postgresql_ssl_path }}/CA-{{ postgresql_self_signed_cert_name }}.csr" + privatekey_path: "{{ postgresql_ssl_path }}/CA-{{ postgresql_self_signed_cert_name }}.key" + provider: selfsigned + owner: postgres + group: postgres + when: postgresql_cert is not defined + register: postgresql_ca_cert_gen + + - name: Generate an OpenSSL private client key with the default values (4096 bits, RSA) + community.crypto.openssl_privatekey: + path: "{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.key" + owner: postgres + group: postgres + when: postgresql_cert is not defined + register: postgresql_key_gen + + - name: Generate an OpenSSL Certificate Signing Request for client + community.crypto.openssl_csr: + path: "{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.csr" + privatekey_path: "{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.key" + common_name: "{{ postgresql_self_signed_cert_name }}" + subject_alt_name: "{{ groups.postgresql | map('regex_replace', '^', 'IP:') | list }}" + owner: postgres + group: postgres + register: postgresql_csr + + - name: Generate an OpenSSL certificate for client signed with your own CA certificate + community.crypto.x509_certificate: + path: "{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.crt" + csr_path: "{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.csr" + ownca_path: "{{ postgresql_ssl_path }}/CA-{{ postgresql_self_signed_cert_name }}.crt" + ownca_privatekey_path: "{{ postgresql_ssl_path }}/CA-{{ postgresql_self_signed_cert_name }}.key" + provider: ownca + owner: postgres + group: postgres + register: postgresql_cert + + - name: Get CA cert content + slurp: + src: "{{ postgresql_ssl_path }}/CA-{{ postgresql_self_signed_cert_name }}.crt" + register: postgresql_ca_cert_b64 + + - name: Get CA key content + slurp: + src: "{{ postgresql_ssl_path }}/CA-{{ postgresql_self_signed_cert_name }}.key" + register: postgresql_ca_key_b64 + + - name: Get client cert content + slurp: + src: "{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.crt" + register: postgresql_cert_b64 + + - name: Get client key content + slurp: + src: "{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.key" + register: postgresql_key_b64 + + - name: Set facts about key and cert + set_fact: + postgresql_ca_key: "{{ postgresql_ca_key_b64.content | b64decode }}" + postgresql_ca_cert: "{{ postgresql_ca_cert_b64.content | b64decode }}" + postgresql_key: "{{ postgresql_key_b64.content | b64decode }}" + postgresql_cert: "{{ postgresql_cert_b64.content | b64decode }}" + delegate_to: "{{ item }}" + delegate_facts: true + run_once: true + loop: "{{ groups.postgresql }}" + +- name: Put PostgreSQL CA OpenSSL key + copy: + content: "{{ postgresql_ca_key }}" + dest: "{{ postgresql_ssl_path }}/CA-{{ postgresql_self_signed_cert_name }}.key" + owner: postgres + group: postgres + mode: 0600 + notify: Restart PostgreSQL + +- name: Put PostgreSQL CA OpenSSL cert + copy: + content: "{{ postgresql_ca_cert }}" + dest: "{{ postgresql_ssl_path }}/CA-{{ postgresql_self_signed_cert_name }}.crt" + owner: postgres + group: postgres + notify: Restart PostgreSQL + +- name: Put PostgreSQL CA OpenSSL cert to PKI + copy: + content: "{{ postgresql_ca_cert }}" + dest: "/etc/pki/ca-trust/source/anchors/CA-{{ postgresql_self_signed_cert_name }}.crt" + register: ca_trust_anchors + notify: Restart PostgreSQL + +- name: Update CA trust + shell: update-ca-trust extract + when: ca_trust_anchors.changed + +- name: Put PostgreSQL OpenSSL key + copy: + content: "{{ postgresql_key }}" + dest: "{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.key" + owner: postgres + group: postgres + mode: 0600 + notify: Restart PostgreSQL + +- name: Put PostgreSQL OpenSSL cert + copy: + content: "{{ postgresql_cert }}" + dest: "{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.crt" + owner: postgres + group: postgres + notify: Restart PostgreSQL diff --git a/tasks/RedHat/main.yaml b/tasks/RedHat/main.yaml new file mode 100644 index 0000000..5d8795e --- /dev/null +++ b/tasks/RedHat/main.yaml @@ -0,0 +1,35 @@ +- name: Disable PostgreSQL module + shell: dnf module disable -y postgresql + register: disable_postgresql_module + changed_when: "'Nothing to do' not in disable_postgresql_module.stdout" + +- name: Add PostgreSQL repository + dnf: + name: "{{ postgresql_repo_package }}" + disable_gpg_check: yes + state: present + +- name: "Install {{ postgresql_package_name }} {{ postgresql_version }}" + dnf: + name: "{{ postgresql_package }}" + state: present + disable_gpg_check: yes + register: postgresql_setup + +- name: Manage TLS/SSL certificates + include_tasks: cacert.yaml + when: postgresql_ssl + +- name: PostgreSQL Initdb + shell: "/usr/pgsql-{{ postgresql_major_version }}/bin/postgresql-{{ postgresql_major_version }}-setup initdb" + register: initdb + changed_when: "'Data directory is not empty!' not in initdb.stdout" + failed_when: false + +- name: Include WAL-G role + ansible.builtin.include_role: + name: wal-g + vars: + wal_g_pg: yes + when: postgresql_wal_g_install + diff --git a/tasks/config.yaml b/tasks/config.yaml new file mode 100644 index 0000000..4b7ab21 --- /dev/null +++ b/tasks/config.yaml @@ -0,0 +1,40 @@ +--- +- name: Merge user options for PostgreSQL config + set_fact: + postgresql_combined_parameters: "{{ postgresql_default_parameters | combine(postgresql_custom_parameters|default({}), recursive=true) }}" + +- name: Merge backup options for PostgreSQL config + set_fact: + postgresql_combined_parameters: "{{ postgresql_combined_parameters | combine(postgresql_backup_parameters|default({}), recursive=true) }}" + when: + +- name: Propagate PostgreSQL configs + block: + - name: Template PostgreSQL pg_hba configuration + template: + src: "{{ postgresql_major_version }}-pg_hba.conf.j2" + dest: "/var/lib/pgsql/{{ postgresql_major_version }}/data/pg_hba.conf" + mode: 0600 + owner: postgres + group: postgres + register: pg_hba_config_file + notify: Restart PostgreSQL + - name: Template PostgreSQL configuration + template: + src: "{{ postgresql_major_version }}-postgresql.conf.j2" + dest: "/var/lib/pgsql/{{ postgresql_major_version }}/data/postgresql.conf" + mode: 0600 + owner: postgres + group: postgres + register: postgresql_config_file + notify: Restart PostgreSQL + - name: Template PostgreSQL SSL configuration + template: + src: "{{ postgresql_major_version }}-postgresql.ssl.conf.j2" + dest: "/var/lib/pgsql/{{ postgresql_major_version }}/data/postgresql.ssl.conf" + mode: 0600 + owner: postgres + group: postgres + register: postgresql_ssl_config_file + notify: Restart PostgreSQL + when: postgresql_ssl diff --git a/tasks/main.yaml b/tasks/main.yaml new file mode 100644 index 0000000..a77db19 --- /dev/null +++ b/tasks/main.yaml @@ -0,0 +1,35 @@ +- name: Make sure handlers are flushed immediately + meta: flush_handlers + +- name: Load a variable file based on the OS type + include_vars: "{{ lookup('first_found', params) }}" + vars: + params: + files: + - "{{ ansible_facts['distribution'] }}.yaml" + - "{{ ansible_facts['os_family'] }}.yaml" + paths: + - "vars" + tags: postgresql_vars + +- name: "Install PostgreSQL for {{ ansible_facts['os_family'] }}" + include_tasks: "{{ ansible_facts['os_family'] }}/main.yaml" + tags: postgresql_setup + +- name: "Configure PostgreSQL" + include_tasks: config.yaml + tags: postgresql_configuration + +- name: Enable and start PostgreSQL + systemd: + daemon_reload: true + name: "postgresql-{{ postgresql_major_version }}" + enabled: true + state: started + masked: no + register: postgresql_enable_and_start + tags: postgresql, postgresql_start + +- name: "Configure PostgreSQL" + include_tasks: user.yaml + tags: postgresql_postgres_user diff --git a/tasks/user.yaml b/tasks/user.yaml new file mode 100644 index 0000000..f59c36c --- /dev/null +++ b/tasks/user.yaml @@ -0,0 +1,17 @@ +- name: Ensure Python 3.9 and psycopg2 installed + dnf: + name: + - python39 + - python39-psycopg2 + state: present + +- name: Set initial PostgreSQL user + become: true + become_user: postgres + vars: + ansible_python_interpreter: '/usr/bin/env python3' + community.postgresql.postgresql_user: + db: "postgres" + name: "postgres" + password: "{{ postgresql_superuser_password }}" + state: present diff --git a/templates/13-pg_hba.conf.j2 b/templates/13-pg_hba.conf.j2 new file mode 100644 index 0000000..d037313 --- /dev/null +++ b/templates/13-pg_hba.conf.j2 @@ -0,0 +1,98 @@ +# PostgreSQL Client Authentication Configuration File +# =================================================== +# +# Refer to the "Client Authentication" section in the PostgreSQL +# documentation for a complete description of this file. A short +# synopsis follows. +# +# This file controls: which hosts are allowed to connect, how clients +# are authenticated, which PostgreSQL user names they can use, which +# databases they can access. Records take one of these forms: +# +# local DATABASE USER METHOD [OPTIONS] +# host DATABASE USER ADDRESS METHOD [OPTIONS] +# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# +# (The uppercase items must be replaced by actual values.) +# +# The first field is the connection type: +# - "local" is a Unix-domain socket +# - "host" is a TCP/IP socket (encrypted or not) +# - "hostssl" is a TCP/IP socket that is SSL-encrypted +# - "hostnossl" is a TCP/IP socket that is not SSL-encrypted +# - "hostgssenc" is a TCP/IP socket that is GSSAPI-encrypted +# - "hostnogssenc" is a TCP/IP socket that is not GSSAPI-encrypted +# +# DATABASE can be "all", "sameuser", "samerole", "replication", a +# database name, or a comma-separated list thereof. The "all" +# keyword does not match "replication". Access to replication +# must be enabled in a separate record (see example below). +# +# USER can be "all", a user name, a group name prefixed with "+", or a +# comma-separated list thereof. In both the DATABASE and USER fields +# you can also write a file name prefixed with "@" to include names +# from a separate file. +# +# ADDRESS specifies the set of hosts the record matches. It can be a +# host name, or it is made up of an IP address and a CIDR mask that is +# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that +# specifies the number of significant bits in the mask. A host name +# that starts with a dot (.) matches a suffix of the actual host name. +# Alternatively, you can write an IP address and netmask in separate +# columns to specify the set of hosts. Instead of a CIDR-address, you +# can write "samehost" to match any of the server's own IP addresses, +# or "samenet" to match any address in any subnet that the server is +# directly connected to. +# +# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", +# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert". +# Note that "password" sends passwords in clear text; "md5" or +# "scram-sha-256" are preferred since they send encrypted passwords. +# +# OPTIONS are a set of options for the authentication in the format +# NAME=VALUE. The available options depend on the different +# authentication methods -- refer to the "Client Authentication" +# section in the documentation for a list of which options are +# available for which authentication methods. +# +# Database and user names containing spaces, commas, quotes and other +# special characters must be quoted. Quoting one of the keywords +# "all", "sameuser", "samerole" or "replication" makes the name lose +# its special character, and just match a database or username with +# that name. +# +# This file is read on server startup and when the server receives a +# SIGHUP signal. If you edit the file on a running system, you have to +# SIGHUP the server for the changes to take effect, run "pg_ctl reload", +# or execute "SELECT pg_reload_conf()". +# +# Put your actual configuration here +# ---------------------------------- +# +# If you want to allow non-local connections, you need to add more +# "host" records. In that case you will also need to make PostgreSQL +# listen on a non-local interface via the listen_addresses +# configuration parameter, or via the -i or -h command line switches. + + + +# TYPE DATABASE USER ADDRESS METHOD + +local all all trust +# "local" is for Unix domain socket connections only +local all all peer +# IPv4 local connections: +host all all 127.0.0.1/32 scram-sha-256 +# IPv6 local connections: +host all all ::1/128 scram-sha-256 +# Allow replication connections from localhost, by a user with the +# replication privilege. +local replication all peer +host replication all 127.0.0.1/32 scram-sha-256 +host replication all ::1/128 scram-sha-256 +{% if postgresql_ssl|bool %} +hostssl all all 0.0.0.0/0 scram-sha-256 +{% endif %} diff --git a/templates/13-postgresql.conf.j2 b/templates/13-postgresql.conf.j2 new file mode 100644 index 0000000..2a3cff7 --- /dev/null +++ b/templates/13-postgresql.conf.j2 @@ -0,0 +1,7 @@ +{% for key, value in postgresql_combined_parameters.items() %} +{{ key }} = '{{ value }}' +{% endfor %} + +{% if postgresql_ssl | bool %} +include = 'postgresql.ssl.conf' +{% endif %} diff --git a/templates/13-postgresql.ssl.conf.j2 b/templates/13-postgresql.ssl.conf.j2 new file mode 100644 index 0000000..bc20078 --- /dev/null +++ b/templates/13-postgresql.ssl.conf.j2 @@ -0,0 +1,3 @@ +ssl = on +ssl_cert_file = '{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.crt' +ssl_key_file = '{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.key' diff --git a/templates/14-pg_hba.conf.j2 b/templates/14-pg_hba.conf.j2 new file mode 100644 index 0000000..d037313 --- /dev/null +++ b/templates/14-pg_hba.conf.j2 @@ -0,0 +1,98 @@ +# PostgreSQL Client Authentication Configuration File +# =================================================== +# +# Refer to the "Client Authentication" section in the PostgreSQL +# documentation for a complete description of this file. A short +# synopsis follows. +# +# This file controls: which hosts are allowed to connect, how clients +# are authenticated, which PostgreSQL user names they can use, which +# databases they can access. Records take one of these forms: +# +# local DATABASE USER METHOD [OPTIONS] +# host DATABASE USER ADDRESS METHOD [OPTIONS] +# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# +# (The uppercase items must be replaced by actual values.) +# +# The first field is the connection type: +# - "local" is a Unix-domain socket +# - "host" is a TCP/IP socket (encrypted or not) +# - "hostssl" is a TCP/IP socket that is SSL-encrypted +# - "hostnossl" is a TCP/IP socket that is not SSL-encrypted +# - "hostgssenc" is a TCP/IP socket that is GSSAPI-encrypted +# - "hostnogssenc" is a TCP/IP socket that is not GSSAPI-encrypted +# +# DATABASE can be "all", "sameuser", "samerole", "replication", a +# database name, or a comma-separated list thereof. The "all" +# keyword does not match "replication". Access to replication +# must be enabled in a separate record (see example below). +# +# USER can be "all", a user name, a group name prefixed with "+", or a +# comma-separated list thereof. In both the DATABASE and USER fields +# you can also write a file name prefixed with "@" to include names +# from a separate file. +# +# ADDRESS specifies the set of hosts the record matches. It can be a +# host name, or it is made up of an IP address and a CIDR mask that is +# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that +# specifies the number of significant bits in the mask. A host name +# that starts with a dot (.) matches a suffix of the actual host name. +# Alternatively, you can write an IP address and netmask in separate +# columns to specify the set of hosts. Instead of a CIDR-address, you +# can write "samehost" to match any of the server's own IP addresses, +# or "samenet" to match any address in any subnet that the server is +# directly connected to. +# +# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", +# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert". +# Note that "password" sends passwords in clear text; "md5" or +# "scram-sha-256" are preferred since they send encrypted passwords. +# +# OPTIONS are a set of options for the authentication in the format +# NAME=VALUE. The available options depend on the different +# authentication methods -- refer to the "Client Authentication" +# section in the documentation for a list of which options are +# available for which authentication methods. +# +# Database and user names containing spaces, commas, quotes and other +# special characters must be quoted. Quoting one of the keywords +# "all", "sameuser", "samerole" or "replication" makes the name lose +# its special character, and just match a database or username with +# that name. +# +# This file is read on server startup and when the server receives a +# SIGHUP signal. If you edit the file on a running system, you have to +# SIGHUP the server for the changes to take effect, run "pg_ctl reload", +# or execute "SELECT pg_reload_conf()". +# +# Put your actual configuration here +# ---------------------------------- +# +# If you want to allow non-local connections, you need to add more +# "host" records. In that case you will also need to make PostgreSQL +# listen on a non-local interface via the listen_addresses +# configuration parameter, or via the -i or -h command line switches. + + + +# TYPE DATABASE USER ADDRESS METHOD + +local all all trust +# "local" is for Unix domain socket connections only +local all all peer +# IPv4 local connections: +host all all 127.0.0.1/32 scram-sha-256 +# IPv6 local connections: +host all all ::1/128 scram-sha-256 +# Allow replication connections from localhost, by a user with the +# replication privilege. +local replication all peer +host replication all 127.0.0.1/32 scram-sha-256 +host replication all ::1/128 scram-sha-256 +{% if postgresql_ssl|bool %} +hostssl all all 0.0.0.0/0 scram-sha-256 +{% endif %} diff --git a/templates/14-postgresql.conf.j2 b/templates/14-postgresql.conf.j2 new file mode 100644 index 0000000..2a3cff7 --- /dev/null +++ b/templates/14-postgresql.conf.j2 @@ -0,0 +1,7 @@ +{% for key, value in postgresql_combined_parameters.items() %} +{{ key }} = '{{ value }}' +{% endfor %} + +{% if postgresql_ssl | bool %} +include = 'postgresql.ssl.conf' +{% endif %} diff --git a/templates/14-postgresql.ssl.conf.j2 b/templates/14-postgresql.ssl.conf.j2 new file mode 100644 index 0000000..bc20078 --- /dev/null +++ b/templates/14-postgresql.ssl.conf.j2 @@ -0,0 +1,3 @@ +ssl = on +ssl_cert_file = '{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.crt' +ssl_key_file = '{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.key' diff --git a/templates/15-pg_hba.conf.j2 b/templates/15-pg_hba.conf.j2 new file mode 100644 index 0000000..d037313 --- /dev/null +++ b/templates/15-pg_hba.conf.j2 @@ -0,0 +1,98 @@ +# PostgreSQL Client Authentication Configuration File +# =================================================== +# +# Refer to the "Client Authentication" section in the PostgreSQL +# documentation for a complete description of this file. A short +# synopsis follows. +# +# This file controls: which hosts are allowed to connect, how clients +# are authenticated, which PostgreSQL user names they can use, which +# databases they can access. Records take one of these forms: +# +# local DATABASE USER METHOD [OPTIONS] +# host DATABASE USER ADDRESS METHOD [OPTIONS] +# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# +# (The uppercase items must be replaced by actual values.) +# +# The first field is the connection type: +# - "local" is a Unix-domain socket +# - "host" is a TCP/IP socket (encrypted or not) +# - "hostssl" is a TCP/IP socket that is SSL-encrypted +# - "hostnossl" is a TCP/IP socket that is not SSL-encrypted +# - "hostgssenc" is a TCP/IP socket that is GSSAPI-encrypted +# - "hostnogssenc" is a TCP/IP socket that is not GSSAPI-encrypted +# +# DATABASE can be "all", "sameuser", "samerole", "replication", a +# database name, or a comma-separated list thereof. The "all" +# keyword does not match "replication". Access to replication +# must be enabled in a separate record (see example below). +# +# USER can be "all", a user name, a group name prefixed with "+", or a +# comma-separated list thereof. In both the DATABASE and USER fields +# you can also write a file name prefixed with "@" to include names +# from a separate file. +# +# ADDRESS specifies the set of hosts the record matches. It can be a +# host name, or it is made up of an IP address and a CIDR mask that is +# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that +# specifies the number of significant bits in the mask. A host name +# that starts with a dot (.) matches a suffix of the actual host name. +# Alternatively, you can write an IP address and netmask in separate +# columns to specify the set of hosts. Instead of a CIDR-address, you +# can write "samehost" to match any of the server's own IP addresses, +# or "samenet" to match any address in any subnet that the server is +# directly connected to. +# +# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", +# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert". +# Note that "password" sends passwords in clear text; "md5" or +# "scram-sha-256" are preferred since they send encrypted passwords. +# +# OPTIONS are a set of options for the authentication in the format +# NAME=VALUE. The available options depend on the different +# authentication methods -- refer to the "Client Authentication" +# section in the documentation for a list of which options are +# available for which authentication methods. +# +# Database and user names containing spaces, commas, quotes and other +# special characters must be quoted. Quoting one of the keywords +# "all", "sameuser", "samerole" or "replication" makes the name lose +# its special character, and just match a database or username with +# that name. +# +# This file is read on server startup and when the server receives a +# SIGHUP signal. If you edit the file on a running system, you have to +# SIGHUP the server for the changes to take effect, run "pg_ctl reload", +# or execute "SELECT pg_reload_conf()". +# +# Put your actual configuration here +# ---------------------------------- +# +# If you want to allow non-local connections, you need to add more +# "host" records. In that case you will also need to make PostgreSQL +# listen on a non-local interface via the listen_addresses +# configuration parameter, or via the -i or -h command line switches. + + + +# TYPE DATABASE USER ADDRESS METHOD + +local all all trust +# "local" is for Unix domain socket connections only +local all all peer +# IPv4 local connections: +host all all 127.0.0.1/32 scram-sha-256 +# IPv6 local connections: +host all all ::1/128 scram-sha-256 +# Allow replication connections from localhost, by a user with the +# replication privilege. +local replication all peer +host replication all 127.0.0.1/32 scram-sha-256 +host replication all ::1/128 scram-sha-256 +{% if postgresql_ssl|bool %} +hostssl all all 0.0.0.0/0 scram-sha-256 +{% endif %} diff --git a/templates/15-postgresql.conf.j2 b/templates/15-postgresql.conf.j2 new file mode 100644 index 0000000..2a3cff7 --- /dev/null +++ b/templates/15-postgresql.conf.j2 @@ -0,0 +1,7 @@ +{% for key, value in postgresql_combined_parameters.items() %} +{{ key }} = '{{ value }}' +{% endfor %} + +{% if postgresql_ssl | bool %} +include = 'postgresql.ssl.conf' +{% endif %} diff --git a/templates/15-postgresql.ssl.conf.j2 b/templates/15-postgresql.ssl.conf.j2 new file mode 100644 index 0000000..bc20078 --- /dev/null +++ b/templates/15-postgresql.ssl.conf.j2 @@ -0,0 +1,3 @@ +ssl = on +ssl_cert_file = '{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.crt' +ssl_key_file = '{{ postgresql_ssl_path }}/{{ postgresql_self_signed_cert_name }}.key' diff --git a/vars/Debian.yaml b/vars/Debian.yaml new file mode 100644 index 0000000..a64927a --- /dev/null +++ b/vars/Debian.yaml @@ -0,0 +1,10 @@ +postgresql_apt_key: + - name: org.postgresql.gpg + url: "https://www.postgresql.org/media/keys/ACCC4CF8.asc" + keyring: /etc/apt/trusted.gpg.d/org.postgresql.gpg +postgresql_apt_repository: + - repo: deb http://apt.postgresql.org/pub/repos/apt {{ ansible_distribution_release }}-pgdg main + filename: postgresql + +postgresql_package: "{{ postgresql_package_name }}-{{ postgresql_major_version }}={{ postgresql_version }}" +postgresql_home_dir: "/var/lib/postgresql" diff --git a/vars/RedHat.yaml b/vars/RedHat.yaml new file mode 100644 index 0000000..464ffbf --- /dev/null +++ b/vars/RedHat.yaml @@ -0,0 +1,4 @@ +postgresql_repo_package: "https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm" + +postgresql_package: "{{ postgresql_package_name }}{{ postgresql_major_version }}-server-{{ postgresql_version }}" +postgresql_home_dir: "/var/lib/pgsql" diff --git a/vars/main.yaml b/vars/main.yaml new file mode 100644 index 0000000..fefb5e4 --- /dev/null +++ b/vars/main.yaml @@ -0,0 +1,3 @@ +postgresql_package_name: "postgresql" +postgresql_major_version: "{{ postgresql_version | split('.') | first }}" +postgresql_minor_version: "{{ postgresql_version | split('.') | last }}"