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 }}
apt_key
now usesgpg
under the hood. What is your version of Ansible? If that is an old version, have you considered upgrading Ansible? – Pratapt_key
that it uses the binaryapt-key
. Actually most of Ansible modules do not uses any system OS commands, but rather Python utilities, since Ansible is all about Python. See: Ansible works by connecting to your nodes and pushing out small programs, called "Ansible modules" to them. These programs are written to be resource models of the desired state of the system. Ansible then executes these modules (over SSH by default), and removes them when finished.. – Pratapt_key
is not meant to be used anymore... – Shea