Search code examples
ansiblerepositoryaptpostgresql-13

Ansible "apt cache update failed" during postgresql repo install


I'm trying to install postgresql on my remote host using Ansible. I have 2 solutions, but both work only half as I expect them to work/turn out.

1. Solution one (using Ansible apt_repository module);

- name: Get Postgres latest repository release
  become: yes
  apt_repository:
    repo: deb https://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main
    state: present
    filename: pgdg.list

This option first looks like it's successful on execution, but eventually gives an error (apt cache update failed):

repository failed to fetch: apt cache update failed


2. Solution two (use shell module)

- name: Get Postgres latest repository release
  become: yes
  shell: sh -c 'echo "deb  http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'

This accomplishes exactly the same (correct me if I'm wrong) and later gives some other exception (No package matching):enter image description here

So I'm not getting any further with my playbook, any tips?

My play to install postgresql-13 (or 14):

- name: Install Postgres dependencies (if not installed)
  become: yes
  apt:
    name: 
    - postgresql-{{ postgres_version }}
    - postgresql-doc-{{ postgres_version }}
    - postgresql-contrib
    - zabbix-sql-scripts
  when:
    - "not 'postgresql-13' in ansible_facts.packages"
    - "not 'postgresql-doc-13' in ansible_facts.packages"
    - "not 'postgresql-contrib' in ansible_facts.packages"
    - "not 'zabbix-sql-scripts' in ansible_facts.packages"

Repository keys are provided in another play and performs without errors.

This is executed on a host with Ubuntu 20.04LTS, Ansible version 2.9.6, Python version 3.8.10

I have searched for both individual problems but did not find a specific answer that solved my problem.

If if perform the same as Ansible manually, it all installs fine (commands used):

sudo sh -c ‘echo “deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main” > /etc/apt/sources.list.d/pgdg.list’

wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

sudo apt-get update

sudo apt-get -y install postgresql-13 postgresql-doc-13

Edit: Seemed I also had a quote (") missing at the start of my repo link (before deb https://...).

I had: repo: deb https://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main"

Should be: "repo: deb https://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main"


Solution

  • Basically, it must be said that an Ansible module, such as apt_repository is generally preferable to the shell module.

    However, you have a few mistakes in your approach.

    As you can see, apt_repository automatically updates the package sources, i.e. the repository key must already exist. You can add the repository key with the apt_key module, but you need to have the gpg package installed, which you should ensure first.

    From this follows:

    1. install gpg
      - name: Ensure gpg is installed
        apt:
          name: gpg
      
    2. add repository key
      - name: Add repository signing key
        apt_key:
          url: "https://www.postgresql.org/media/keys/ACCC4CF8.asc"
          state: present
      
    3. add repository source
      - name: Add postgresql repository
        apt_repository:
          repo: "deb https://apt.postgresql.org/pub/repos/apt/ {{ ansible_distribution_release }}-pgdg main"
          state: present
          filename: pgdg
      

    When using apt_repository one of your problems was that you left $(lsb_release -cs) unchanged, but this only works via the shell, instead you have to use the variable ansible_distribution_release when using Ansible. Also, the filename parameter does not need an extension (.list), as the documentation tells you: "The .list extension will be automatically added." Your specification creates the file pgdg.list.list.

    Again, as a whole playbook:

    - name: Database Server
      hosts: databaseserver
      become: yes
    
      tasks:
        - name: Ensure gpg is installed
          apt:
            name: gpg
    
        - name: Add repository signing key
          apt_key:
            url: "https://www.postgresql.org/media/keys/ACCC4CF8.asc"
            state: present
    
        - name: Add postgresql repository
          apt_repository:
            repo: "deb https://apt.postgresql.org/pub/repos/apt/ {{ ansible_distribution_release }}-pgdg main"
            state: present
            filename: pgdg
    

    Now you should be able to install the desired packages, if they are provided by the included repository.