How can I manage keyring files in trusted.gpg.d with ansible playbook since apt-key is deprecated?

Viewed 3398

Before apt-key was deprecated, I was using Ansible playbooks to add and update keys in my servers. At the moment, apt-key no longer updates the keys. In few searches, I found that I need to use gpg now. However, I have many servers and I don't want to do this manually for each one of them. Is there a way to manage my keyrings with gpg with Ansible?

Here are my Ansible tasks, with deprecated apt-key:

- apt_key:
  url: "https://packages.treasuredata.com/GPG-KEY-td-agent"
  state: present

- apt_repository:
  repo: "deb http://packages.treasuredata.com/3/ubuntu/{{ ansible_distribution_release }}/ {{ ansible_distribution_release }} contrib"
  state: present
  filename: "treasure-data" # Name of the pre-compiled fluentd-agent

I tried apt-key update but it is not working for me. If a key already exists but it is expired, it doesn't update it anymore.

2 Answers

In short, you need to put the GPG keys in a modern format into a separate folder that is not searched by default, and point your repository configuration at it.

For reasoning why a separate folder, see: https://stackoverflow.com/a/71384057/8962143

You can verify whether you have the old ASCII GPG format or the newer binary GPG format via file:

# file elastic-old.gpg
elastic-old.gpg: PGP public key block Public-Key (old)

# file elastic.gpg    
elastic.gpg: PGP/GPG key public ring (v4) created Mon Sep 16 17:07:54 2013 RSA (Encrypt or Sign) 2048 bits MPI=0xd70ed6cd267c5b3e...

If your key is the old format, you will need to de-armor it via gpg --dearmor elastic.gpg into the new binary format.

On Ubuntu 22.04, there's a folder you're expected to use that is not preloaded - /etc/apt/keyrings - or you can create your own directory and use that.

As for the Ansible part, you can use get_url or file to push the modern-format GPG key onto the system, and then use apt_repository like before to add the repo, with the addition of specifying the keyring.

- name: Add Example GPG key
  ansible.builtin.get_url:
    url: https://example.com/example.gpg
    dest: /etc/apt/keyrings/example.asc
    mode: '0644'
    force: true

- name: Add Example repo
  ansible.builtin.apt_repository:
    filename: example-repo
    repo: 'deb [signed-by=/etc/apt/keyrings/example.gpg] https://example.com/packages/8.x/apt stable main'

To expand a bit on @geerlingguy's comment regarding using the .asc extension, this is how I ended up adding the repository for Telegraf. Take note of the use of influxdb.asc in both the get_url and apt_repository tasks.

- name: Install InfluxDB key
  get_url:
    url:  https://repos.influxdata.com/influxdb.key
    dest: /etc/apt/trusted.gpg.d/influxdb.asc

- name:  Add InfluxDB repository
  apt_repository:
    repo:  "deb [signed-by=/etc/apt/trusted.gpg.d/influxdb.asc] https://repos.influxdata.com/debian stable main"
    state: present
    update_cache: yes

- name:  Install telegraf
  package:
    name:  telegraf
    state: present

You can completely bypass the gpg --dearmor step with this method.

Related