diff --git a/defaults/main.yml b/defaults/main.yml index bc80982..3bfc0fd 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,6 +1,6 @@ --- postgres_repository_enabled: False -postgres_version: 12 +postgres_version: 14 postgres_repository_filename: "Postgresql-{{ postgres_version | regex_replace('\\.') }}" postgres_user: postgres postgres_group: postgres @@ -20,7 +20,7 @@ postgres_connection_addresses: postgres_socket_directories: - /var/run/postgresql -postgres_password_encryption: md5 +postgres_password_encryption: scram-sha-256 postgres_tls_enabled: False postgres_tls_cert_filename: "mycert.pem" @@ -81,13 +81,13 @@ postgres_hba_entries: users: - all address: "127.0.0.1/32" - auth_method: md5 + auth_method: "{{ postgres_password_encryption }}" - contype: host databases: - all users: - all address: "::1/128" - auth_method: md5 + auth_method: "{{ postgres_password_encryption }}" postgres_hba_entries_extra: [] diff --git a/molecule/centos7/tests/test_default.py b/molecule/centos7/tests/test_default.py index f48b2b8..e672871 100644 --- a/molecule/centos7/tests/test_default.py +++ b/molecule/centos7/tests/test_default.py @@ -8,16 +8,21 @@ testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( def test_postgres_is_installed(host): - postgres = host.package("postgresql12-server") + postgres = host.package("postgresql14-server") assert postgres.is_installed def test_postgres_running_and_enabled(host): - postgres = host.service("postgresql-12") + postgres = host.service("postgresql-14") assert postgres.is_running assert postgres.is_enabled +def test_postgres_auth(host): + login = host.run("PGPASSWORD=secure psql -U pgdemo -h localhost -c 'select 1' -q demo") + assert login.succeeded + + def test_postgres_socket(host): # Verify the socket is listening for HTTP traffic assert host.socket("tcp://127.0.0.1:5432").is_listening diff --git a/molecule/rocky8/tests/test_default.py b/molecule/rocky8/tests/test_default.py index 5f358cd..e672871 100644 --- a/molecule/rocky8/tests/test_default.py +++ b/molecule/rocky8/tests/test_default.py @@ -8,16 +8,21 @@ testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( def test_postgres_is_installed(host): - postgres = host.package("postgresql10-server") + postgres = host.package("postgresql14-server") assert postgres.is_installed def test_postgres_running_and_enabled(host): - postgres = host.service("postgresql-10") + postgres = host.service("postgresql-14") assert postgres.is_running assert postgres.is_enabled +def test_postgres_auth(host): + login = host.run("PGPASSWORD=secure psql -U pgdemo -h localhost -c 'select 1' -q demo") + assert login.succeeded + + def test_postgres_socket(host): # Verify the socket is listening for HTTP traffic assert host.socket("tcp://127.0.0.1:5432").is_listening diff --git a/tasks/config.yml b/tasks/config.yml index 245961f..873415d 100644 --- a/tasks/config.yml +++ b/tasks/config.yml @@ -24,7 +24,7 @@ users: "{{ item.users | default(['all']) | join(',') }}" address: "{{ item.address | default('all') }}" databases: "{{ item.databases | default(['all']) | join(',') }}" - method: "{{ item.auth_method | default('md5') }}" + method: "{{ item.auth_method | default(postgres_password_encryption) }}" state: "{{ item.state | default('present') }}" loop: "{{ postgres_hba_entries + postgres_hba_entries_extra }}" loop_control: diff --git a/tasks/main.yml b/tasks/main.yml index ed9d4e5..fde0d29 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,5 +1,17 @@ --- - import_tasks: prepare.yml + +- include_tasks: "{{ task_files }}" + vars: + task_files: "{{ lookup('first_found', params, errors='ignore') }}" + params: + files: + - "prepare_{{ ansible_os_family | lower }}_{{ ansible_distribution_major_version }}.yml" + - "prepare_{{ ansible_os_family | lower }}.yml" + paths: + - "tasks" + when: task_files + - import_tasks: install.yml - import_tasks: config.yml - import_tasks: tls.yml diff --git a/tasks/post_tasks.yml b/tasks/post_tasks.yml index a3bfc7d..27f269d 100644 --- a/tasks/post_tasks.yml +++ b/tasks/post_tasks.yml @@ -23,9 +23,11 @@ become_user: "{{ postgres_user }}" - name: Ensure PostgreSQL users are present + environment: + PGOPTIONS: "-c password_encryption={{ postgres_password_encryption }}" postgresql_user: name: "{{ item.name }}" - password: "{{ 'md5' + (item.password + item.name) | hash('md5') }}" + password: "{{ item.password | default(omit) }}" encrypted: "{{ item.encrypted | default('yes') }}" priv: "{{ item.priv | default(omit) }}" role_attr_flags: "{{ item.role_attr_flags | default(omit) }}" diff --git a/tasks/prepare.yml b/tasks/prepare.yml index d8798bd..ef726dd 100644 --- a/tasks/prepare.yml +++ b/tasks/prepare.yml @@ -1,24 +1,10 @@ --- -- name: Load helper variables - include_vars: "main.yml" - -- block: - - name: Add PostgreSQL repository - yum_repository: - name: "postgresql-{{ __postgres_version }}" - file: "{{ postgres_repository_filename }}" - description: "PostgreSQL {{ __postgres_version }} yum repository" - baseurl: "https://download.postgresql.org/pub/repos/yum/{{ __postgres_version }}/redhat/rhel-{{ ansible_distribution_major_version }}-{{ ansible_architecture }}" - gpgcheck: yes - enabled: yes - gpgkey: "https://download.postgresql.org/pub/repos/yum/RPM-GPG-KEY-PGDG-{{ __postgres_version }}" - - - name: Install dependencies - package: - name: "{{ item }}" - state: present - loop: - - python2-psycopg2 - become: True - become_user: root - when: postgres_repository_enabled | bool +- name: Add PostgreSQL repository + yum_repository: + name: "postgresql-{{ __postgres_version }}" + file: "{{ postgres_repository_filename }}" + description: "PostgreSQL {{ __postgres_version }} yum repository" + baseurl: "https://download.postgresql.org/pub/repos/yum/{{ __postgres_version }}/redhat/rhel-{{ ansible_distribution_major_version }}-{{ ansible_architecture }}" + gpgcheck: yes + enabled: yes + gpgkey: "https://download.postgresql.org/pub/repos/yum/RPM-GPG-KEY-PGDG-{{ __postgres_version }}" diff --git a/tasks/prepare_redhat_7.yml b/tasks/prepare_redhat_7.yml new file mode 100644 index 0000000..9a2b9c7 --- /dev/null +++ b/tasks/prepare_redhat_7.yml @@ -0,0 +1,10 @@ +--- +- name: Install RH7 dependencies + package: + name: "{{ item }}" + state: present + loop: + - python2-psycopg2 + become: True + become_user: root + when: postgres_repository_enabled | bool diff --git a/tasks/prepare_redhat_8.yml b/tasks/prepare_redhat_8.yml new file mode 100644 index 0000000..44bbd19 --- /dev/null +++ b/tasks/prepare_redhat_8.yml @@ -0,0 +1,24 @@ +--- +- block: + - name: Disable default Postgres module + copy: + dest: /etc/dnf/modules.d/postgresql.module + content: | + [postgresql] + name=postgresql + stream= + profiles= + state=disabled + mode: 644 + owner: root + group: root + + - name: Install RH8 dependencies + package: + name: "{{ item }}" + state: present + loop: + - python3-psycopg2 + become: True + become_user: root + when: postgres_repository_enabled | bool diff --git a/templates/postgresql/data/postgresql.conf.j2 b/templates/postgresql/data/postgresql.conf.j2 index 8baf404..13ac7fe 100644 --- a/templates/postgresql/data/postgresql.conf.j2 +++ b/templates/postgresql/data/postgresql.conf.j2 @@ -2,23 +2,6 @@ # ----------------------------- # PostgreSQL configuration file # ----------------------------- -# -# This file consists of lines of the form: -# -# name = value -# -# (The "=" is optional.) Whitespace may be used. Comments are introduced with -# "#" anywhere on a line. The complete list of parameter names and allowed -# values can be found in the PostgreSQL documentation. - - -#------------------------------------------------------------------------------ -# FILE LOCATIONS -#------------------------------------------------------------------------------ - -# The default values of these variables are driven from the -D command-line -# option or PGDATA environment variable, represented here as ConfigDir. - #------------------------------------------------------------------------------ # CONNECTIONS AND AUTHENTICATION @@ -29,262 +12,75 @@ listen_addresses = '{{ postgres_connection_addresses | join(",") }}' port = {{ postgres_connection_port }} max_connections = 100 -#superuser_reserved_connections = 3 unix_socket_directories = '{{ postgres_socket_directories | join(",") }}' -#unix_socket_group = '' -#unix_socket_permissions = 0777 -#bonjour = off -#bonjour_name = '' -# - Security and Authentication - +# - Authentication - + +authentication_timeout = 1min +password_encryption = {{ postgres_password_encryption }} + +# - SSL - -#authentication_timeout = 1min {% if postgres_tls_enabled %} ssl = on +ssl_cert_file = '{{ __postgres_tls_cert_path }}' +ssl_key_file = '{{ __postgres_tls_key_path }}' {% else %} ssl = off {% endif %} -{% if postgres_tls_enabled %} -#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' -#ssl_prefer_server_ciphers = on -#ssl_ecdh_curve = 'prime256v1' -#ssl_dh_params_file = '' -ssl_cert_file = '{{ __postgres_tls_cert_path }}' -ssl_key_file = '{{ __postgres_tls_key_path }}' -#ssl_ca_file = '' -#ssl_crl_file = '' -{% endif %} -password_encryption = {{ postgres_password_encryption }} -#db_user_namespace = off -#row_security = on - -# GSSAPI using Kerberos -#krb_server_keyfile = '' -#krb_caseins_users = off - -# - TCP Keepalives - -# see "man 7 tcp" for details - -#tcp_keepalives_idle = 0 -#tcp_keepalives_interval = 0 -#tcp_keepalives_count = 0 - #------------------------------------------------------------------------------ # RESOURCE USAGE (except WAL) #------------------------------------------------------------------------------ + +# - Memory - + shared_buffers = 128MB dynamic_shared_memory_type = posix -# - Disk - - -# - Kernel Resource Usage - - -# - Cost-Based Vacuum Delay - - -# - Background Writer - - -# - Asynchronous Behavior - - - -#------------------------------------------------------------------------------ -# WRITE AHEAD LOG -#------------------------------------------------------------------------------ - -# - Settings - - # - Checkpoints - -# - Archiving - +max_wal_size = 1GB +min_wal_size = 80MB #------------------------------------------------------------------------------ -# REPLICATION -#------------------------------------------------------------------------------ - -# - Sending Server(s) - - -# Set these on the master and on any standby that will send replication data. - -# - Master Server - - -# These settings are ignored on a standby server. - -# - Standby Servers - - -# These settings are ignored on a master server. - -# - Subscribers - - -# These settings are ignored on a publisher. - - -#------------------------------------------------------------------------------ -# QUERY TUNING -#------------------------------------------------------------------------------ - -# - Planner Method Configuration - - -# - Planner Cost Constants - - -# - Genetic Query Optimizer - - -# - Other Planner Options - - - -#------------------------------------------------------------------------------ -# ERROR REPORTING AND LOGGING +# REPORTING AND LOGGING #------------------------------------------------------------------------------ # - Where to Log - log_destination = '{{ postgres_log_destination | join(",") }}' -# This is used when logging to stderr: {% if "stderr" in postgres_log_destination or "csvlog" in postgres_log_destination %} logging_collector = on {% else %} logging_collector = off {% endif %} -# These are only used if logging_collector is on: log_directory = '{{ postgres_log_directory }}' log_filename = '{{ postgres_log_filename }}' -#log_file_mode = 0600 -log_truncate_on_rotation = on log_rotation_age = {{ postgres_log_rotation_age }} log_rotation_size = {{ postgres_log_rotation_size }} - - -# These are relevant when logging to syslog: -#syslog_facility = 'LOCAL0' -#syslog_ident = 'postgres' -#syslog_sequence_numbers = on -#syslog_split_messages = on - -# - When to Log - -#client_min_messages = notice -#log_min_messages = warning -#log_min_error_statement = error -#log_min_duration_statement = -1 +log_truncate_on_rotation = on # - What to Log - -#debug_print_parse = off -#debug_print_rewritten = off -#debug_print_plan = off -#debug_pretty_print = on -#log_checkpoints = off -#log_connections = off -#log_disconnections = off -#log_duration = off -#log_error_verbosity = default # terse, default, or verbose messages -#log_hostname = off + log_line_prefix = '%m [%p] ' -#log_lock_waits = off -#log_statement = 'none' -#log_replication_commands = off -#log_temp_files = -1 -log_timezone = 'Europe/Berlin' - - -# - Process Title - - -#cluster_name = '' -#update_process_title = on - - -#------------------------------------------------------------------------------ -# RUNTIME STATISTICS -#------------------------------------------------------------------------------ - -# - Query/Index Statistics Collector - - -# - Statistics Monitoring - - - -#------------------------------------------------------------------------------ -# AUTOVACUUM PARAMETERS -#------------------------------------------------------------------------------ +log_timezone = 'Etc/UTC' #------------------------------------------------------------------------------ # CLIENT CONNECTION DEFAULTS #------------------------------------------------------------------------------ -# - Statement Behavior - - # - Locale and Formatting - datestyle = 'iso, mdy' -#intervalstyle = 'postgres' -timezone = 'Europe/Berlin' -#timezone_abbreviations = 'Default' -#extra_float_digits = 0 -#client_encoding = sql_ascii +timezone = 'Etc/UTC' -# These settings are initialized by initdb, but they can be changed. lc_messages = 'en_US.UTF-8' -lc_monetary = 'en_US.UTF-8' -lc_numeric = 'en_US.UTF-8' -lc_time = 'en_US.UTF-8' +lc_monetary = 'en_US.UTF-8' # locale for monetary formatting +lc_numeric = 'en_US.UTF-8' # locale for number formatting +lc_time = 'en_US.UTF-8' # locale for time formatting -# default configuration for text search default_text_search_config = 'pg_catalog.english' - -# - Other Defaults - - -#dynamic_library_path = '$libdir' -#local_preload_libraries = '' -#session_preload_libraries = '' - - -#------------------------------------------------------------------------------ -# LOCK MANAGEMENT -#------------------------------------------------------------------------------ - - -#------------------------------------------------------------------------------ -# VERSION/PLATFORM COMPATIBILITY -#------------------------------------------------------------------------------ - -# - Previous PostgreSQL Versions - - -#array_nulls = on -#backslash_quote = safe_encoding -#default_with_oids = off -#escape_string_warning = on -#lo_compat_privileges = off -#operator_precedence_warning = off -#quote_all_identifiers = off -#standard_conforming_strings = on -#synchronize_seqscans = on - -# - Other Platforms and Clients - - -#transform_null_equals = off - - -#------------------------------------------------------------------------------ -# ERROR HANDLING -#------------------------------------------------------------------------------ - -#exit_on_error = off # terminate session on any error? -#restart_after_crash = on # reinitialize after backend crash? - - -#------------------------------------------------------------------------------ -# CONFIG FILE INCLUDES -#------------------------------------------------------------------------------ - -# These options allow settings to be loaded from files other than the -# default postgresql.conf. - -#include_dir = 'conf.d' -#include_if_exists = 'exists.conf' -#include = 'special.conf' - - -#------------------------------------------------------------------------------ -# CUSTOMIZED OPTIONS -#------------------------------------------------------------------------------ - -# Add settings for extensions here