Ansible: adding custom apt repository with ‘signed-by’ gpg key

The centralized system keyring for apt was deprecated starting in Ubuntu 21, and is being replaced with an explicit path to the local gpg key in the ‘signed-by’ attribute.

I have written more extensive articles on this subject [here,here], but from an Ansible perspective, this means ensuring the gpg key is downloaded to ‘/usr/share/keyrings’ with the proper permissions and adding the ‘signed-by’ attribute to the repo definition.

Here is an example of creating the custom apt repo for Google (supplies gcloud and kubectl packages).

# save gpg key locally
- name: get google key, save in /usr/share/keyrings for newer apt deb syntax
  get_url:
    url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
    dest: /usr/share/keyrings/google.gpg
    mode: ugo+rw

# add custom apt repo with 'signed-by' referring to gpg key
- name: add google apt repository
  apt_repository:
    repo: "deb [arch=amd64, signed-by=/usr/share/keyrings/google.gpg] https://packages.cloud.google.com/apt cloud-sdk main"
    state: present
    filename: google-cloud-sdk
    update_cache: yes
    mode: 0644
    validate_certs: no

Notice we are saving the gpg key to ‘/usr/share/keyrings/google.gpg’ instead of the deprecated method of adding to the centralized keyring with “apt-key add”.

As another example, here is a custom Helm3 repo where the gpg key is not binary, but is instead ASCII-armored.

# save ASCII-armored gpg key locally
- name: get helm3 key, save in /usr/share/keyrings for newer apt deb syntax
  get_url:
    url: https://baltocdn.com/helm/signing.asc
    dest: /usr/share/keyrings/helm3.asc
    mode: ugo+rw

# add custom apt repo with 'signed-by' referring to gpg key
- name: add helm3 apt repository
  apt_repository:
    repo: deb [arch=amd64, signed-by=/usr/share/keyrings/helm3.asc] https://baltocdn.com/helm/stable/debian/ all main
    state: present
    filename: helm3
    update_cache: yes
    mode: 0644
    validate_certs: false

Full examples of these Ansible files can be found on github at gcloud-apt/tasks/main.yaml and helm3-apt/tasks/main.yaml.

This article was tested using Ansible 2.12.0, older versions of Ansible may not understand the square bracketed attributes being used in the ‘apt_repository’ module.

REFERENCES

ansible, apt_repo module

ansible, get_url module