Raymii.org
Quis custodiet ipsos custodes?Home | About | All pages | Cluster Status | RSS Feed
Ansible - Add an apt-repository on Debian and Ubuntu
Published: 15-05-2016 | Last update: 14-12-2018 | Author: Remy van Elst | Text only version of this article
❗ This post is over five years old. It may no longer be up to date. Opinions may have changed.
Table of Contents
This is a guide that shows you how to add an apt repository to Debian and Ubuntu using Ansible. It includes both the old way, when the apt modules only worked on Ubuntu, and the new way, now that the apt-modules also support Debian, plus some other tricks.
Recently I removed all Google Ads from this site due to their invasive tracking, as well as Google Analytics. Please, if you found this content useful, consider a small donation using any of the options below:
I'm developing an open source monitoring app called Leaf Node Monitoring, for windows, linux & android. Go check it out!
Consider sponsoring me on Github. It means the world to me if you show your appreciation and you'll help pay the server costs.
You can also sponsor me by getting a Digital Ocean VPS. With this referral link you'll get $200 credit for 60 days. Spend $25 after your credit expires and I'll get $25!
- 14-12-2018: updated ansible syntax to 2.5
- 15-05-2016: initial article
Introduction
Ansible allows you to add apt repositories and apt repository signing keys
easily using the two modules apt_repository
and apt_key
. You can use this
when you need to install packages from an external location, for example,
nginx
or goaccess
. Both of these packages are in the repositories, but not
the latest version.
Using Ansible you can add the repository and the signing key, and then install the package from the new repo. This guide will show you a few ways to do that in playbooks.
The new way
The easy way is to first add the repository key, then add the repository and finally install the package. Here's an example for nginx:
# always try to use HTTPS. I'm not sure why the nginx folks don't provide it.
- name: add nginx apt-key
apt_key:
url: http://nginx.org/keys/nginx_signing.key
state: present
- name: add nginx apt repository
apt_repository:
repo: 'deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx'
state: present
filename: nginx
update_cache: yes
- name: install nginx
apt:
name: nginx
state: present
update_cache: yes
This is a three line playbook which will download and install the repository
key, add the repository to a seperate file in /etc/apt/sources.list.d/
and
install the package while also doing an apt-get update
to refresh the apt
cache with the new repository.
This is the recommended way to add a repo and install packages from there. Read on to find out the workarounds in ye olden days.
The old way
In the past the apt_key
module and behaved wonky on Debian installations, but
not on Ubuntu. The apt_key
module also did not support downloading keys from
external locations and was tailored more to PPA's, which are nonexistent on
Debian. Here's the same NGINX example, using the older way, which still works by
the way.
- name: 'add nginx repository'
template:
src: nginx.list.j2
dest: /etc/apt/sources.list.d/nginx.list
- name: make sure folder /var/keys exists
file:
path: /var/keys
state: directory
owner: root
- name: 'get nginx package signing key'
get_url:
url: http://nginx.org/keys/nginx_signing.key
dest: /var/keys/nginx_signing.key
register: result
- name: add nginx apt-key
command: apt-key add '/var/keys/nginx_signing.key'
when: result.changed
- name: install nginx
apt:
name: nginx
state: latest
update_cache: yes
The nginx repository template contains the following:
# {{ ansible_managed }}
deb http://nginx.org/packages/mainline/{{ ansible_lsb.id|lower }}
/ {{ ansible_lsb.codename|lower }} nginx
deb-src http://nginx.org/packages/mainline/{{ ansible_lsb.id|lower }}
/ {{ ansible_lsb.codename|lower }} nginx
This is quite a nice trick, because it works on both Debian and Ubuntu, all versions. On the latest Ubuntu 16.04 the resulting repository line is this:
deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx
But on an onder Debian installation, the result is this:
deb http://nginx.org/packages/mainline/debian/ wheezy nginx
You do need to make sure the upstream repository also follows this structure. In the nginx case, it does.
First a directory is created for the keyfile. The apt-key is downloaded manually
to there, the result is registered. If the key already exists or is the same, we
don't do anything. If the key isn't there or has changed, we execute the apt-
key add
command manually to add the repository signing key. If that's all done,
we update the apt-cache and install nginx.
That's quite a bit more steps and ways to break stuff, plus, less idempotent due
to the manual command. My playbook was so old, it still used the action: apt
instead of just apt:
.
This is not the recommended way, but it still works just fine. If you add repositories this way, no problem, but you might want to consider rewriting the playbooks to the newer way.
More documentation
The official documentation for the two modules can be found on the Ansible docs site: apt_repository and apt_key.
You can also check out my other Ansible articles.
Tags: ansible , apt , deb , nginx , packages , python , repo , tutorials