In short, you need to put the GPG key with the correct extension into a separate directory that is not searched by default, and point your repository configuration at that specific file.
For more info on why you need a separate directory, see this answer to “Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead”.
Warning: apt
will not accept ASCII GPG keys saved with .gpg extension.
You can verify whether you have the old ASCII GPG format(.asc) or the newer binary GPG format(.gpg) 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 can either use the .asc extension, or you can optionally de-armor it via gpg --dearmor elastic.gpg
into the new binary format and use the .gpg extension.
The de-armor step is annoying for ansible automation, so I suggest you just use whatever format upstream provides as is.
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 GPG key onto the system, and then use apt_repository
like before to add the repo, with the addition of specifying the keyring.
Using the binary GPG format with .gpg
- name: Add Example GPG key
ansible.builtin.get_url:
url: https://example.com/example.gpg
dest: /etc/apt/keyrings/example.gpg
mode: '0644'
force: true
Or using the .asc extension if upstream still hasn’t switched over yet
- 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
Then you can define your repository via apt_repository module like before.
- 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'
Keep in mind that apt_repository uses the old .list
format instead of the new DEB822 compliant .sources
format.
If you want/need to use the newer DEB822 format and you happen to be running Ansible 2.15 or newer, you should use the deb822_repository module.
If you are stuck using older Ansible core, you can template it yourself similarly to this:
tasks/main.yaml
- name: Add Elastic repo
notify: apt update force
ansible.builtin.template:
src: repo.j2
dest: /etc/apt/sources.list.d/elastic-8.x.sources
mode: '0644'
vars:
repo_name: Example PPA
repo_uris: https://example.com/packages/8.x/apt
repo_suites: stable
repo_components: main
repo_signed_by: /etc/apt/keyrings/example.gpg
templates/repo.j2
X-Repolib-Name: {{ repo_name }}
Types: deb
URIs: {{ repo_uris }}
Suites: {{ repo_suites }}
{% if repo_components is defined %}
Components: {{ repo_components }}
{% endif %}
Signed-By: {{ repo_signed_by }}