Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-62395

postgresql role: The postgresql_cert_name variable doesn't work with existing certificates

    • rhel-sst-system-roles
    • 0
    • QE ack, Dev ack
    • False
    • Hide

      None

      Show
      None
    • Yes
    • None
    • Bug Fix
    • Hide
      .The `postgresql` RHEL system role no longer fails to set the paths to a TLS certificate and private key

      The `postgresql_cert_name` variable of the `postgresql` RHEL system role defines the base path to the TLS certificate and private key without suffix on the managed node. Before this update, the role did not define internal variables for the certificate and private key. As a consequence, if you set `postgresql_cert_name`, the Ansible task failed with the following error message:

      ----
      The task includes an option with an undefined variable. The error was: '__pg_server_crt' is undefined. '__pg_server_crt' is undefined
      ----

      With this update, the role correctly defines these internal variables, and the task sets the paths to the certificate and private key in the PostgreSQL configuration files.
      Show
      .The `postgresql` RHEL system role no longer fails to set the paths to a TLS certificate and private key The `postgresql_cert_name` variable of the `postgresql` RHEL system role defines the base path to the TLS certificate and private key without suffix on the managed node. Before this update, the role did not define internal variables for the certificate and private key. As a consequence, if you set `postgresql_cert_name`, the Ansible task failed with the following error message: ---- The task includes an option with an undefined variable. The error was: '__pg_server_crt' is undefined. '__pg_server_crt' is undefined ---- With this update, the role correctly defines these internal variables, and the task sets the paths to the certificate and private key in the PostgreSQL configuration files.
    • Done
    • None

      Steps to reproduce:

      1. Create the following playbook:
      ---
      - name: Installing and configuring PostgreSQL
        hosts: rhel9.example.com
        tasks:
          - name: Create
            ansible.builtin.file:
              path: /etc/postgresql/
              state: directory
              mode: 755
          - name: Copy CA certificate
            ansible.builtin.copy:
              src: "~/{{ inventory_hostname }}.crt"
              dest: "/etc/postgresql/server.crt"
              owner: postgres
          - name: Copy private key
            ansible.builtin.copy:
              src: "~/{{ inventory_hostname }}.key"
              dest: "/etc/postgresql/server.key"
              mode: 0600
              owner: postgres
          - name: PostgreSQL with an existing private key and certificate
            ansible.builtin.include_role:
              name: rhel-system-roles.postgresql
            vars:
              postgresql_version: "16"
              postgresql_ssl_enable: true
              postgresql_cert_name: "/etc/postgresql/server"
      

       

      2. Run the playbook:

      $ ansible-playbook --verbose ~/playbook.yml

      Actual results:

      TASK [rhel-system-roles.postgresql : Install certificate file] ****************************************************************************************************************************************************
      fatal: [rhel9.example.com]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: '__pg_server_crt' is undefined. '__pg_server_crt' is undefined\n\nThe error appears to be in '/usr/share/ansible/roles/rhel-system-roles.postgresql/tasks/certificate.yml': line 56, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  block:\n    - name: Install certificate file\n      ^ here\n"}

       

      Expected results:
      The playbook should succeed.

       

      Workaround/Fix:
      Add the following "vars" block to /usr/share/ansible/roles/rhel-system-roles.postgresql/tasks/certificate.yml:

      - name: Install user provided TLS certificates for postgresql
        when:
          - __postgresql_cert.stat.exists
          - __postgresql_key.stat.exists
          - postgresql_certificates | length < 1
        vars:
          __pg_server_crt: "{{ __postgresql_data_dir }}/server.crt"
          __pg_server_key: "{{ __postgresql_data_dir }}/server.key"
        ...

       

      Additional information:

      When you fix this, please also update the postgresql_cert_name variable description in the readme (it cost me a some time to figure out how it works because the description misses some important details):

      1. It should mention that the key/cert files must exist on the managed node (or be copied by the playbook). They are not copied automatically (which would be a nice enhancement and improvement of the user experience)
      2. The value must be an absolute path.
      3. The role changes the owner of the key/cert files to "postgres".
      4. The role creates symbolic links /var/lib/pgsql/data/server.key|.crt that link to the key/crt path you specify in postgresql_cert_name. Therefore, you can't directly copy the files to /var/lib/pgsql/data/server.key|.crt (because then the role fails when it tries to create the symlinks)

       

       

              rmeggins@redhat.com Richard Megginson
              mmuehlfe@redhat.com Marc Muehlfeld
              Richard Megginson Richard Megginson
              David Jez David Jez
              Marc Muehlfeld Marc Muehlfeld
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

                Created:
                Updated: