Ansible apt Module: Install, Remove & Manage Packages on Debian/Ubuntu
By Luca Berton · Published 2024-01-01 · Category: installation
Complete guide to Ansible apt module (ansible.builtin.apt). Install, remove, upgrade packages on Debian and Ubuntu.
The ansible.builtin.apt module manages packages on Debian, Ubuntu, Linux Mint, and other APT-based distributions. It handles installation, removal, upgrades, cache management, and repository configuration.
Install a Package
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
See also: Install Docker in Debian-like systems - Ansible module apt_key, apt_repository and apt
Install Multiple Packages
- name: Install web stack
ansible.builtin.apt:
name:
- nginx
- postgresql
- redis-server
- python3-pip
state: present
Remove a Package
# Remove package (keep config files)
- name: Remove nginx
ansible.builtin.apt:
name: nginx
state: absent
# Purge package (remove config files too)
- name: Purge nginx completely
ansible.builtin.apt:
name: nginx
purge: true
state: absent
See also: Install Google Chrome in Debian like systems - Ansible module apt_key, apt_repository and apt
Update Cache (apt update)
# Update cache before installing
- name: Install with fresh cache
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
cache_valid_time: 3600 # Skip update if <1 hour old
# Just update cache
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
Best practice: Always use cache_valid_time with update_cache to avoid running apt update on every task.
Upgrade All Packages
# Safe upgrade (apt upgrade)
- name: Upgrade all packages
ansible.builtin.apt:
upgrade: safe
update_cache: true
# Full upgrade (apt full-upgrade / apt dist-upgrade)
- name: Full upgrade
ansible.builtin.apt:
upgrade: full
update_cache: true
# Dist upgrade
- name: Distribution upgrade
ansible.builtin.apt:
upgrade: dist
See also: Install Microsoft Edge on Debian with Ansible
Pin a Specific Version
- name: Install specific version
ansible.builtin.apt:
name: nginx=1.24.0-2ubuntu1
state: present
# Find available versions: apt-cache policy nginx
Install from .deb File
- name: Download package
ansible.builtin.get_url:
url: https://example.com/app_1.2.3_amd64.deb
dest: /tmp/app.deb
- name: Install .deb package
ansible.builtin.apt:
deb: /tmp/app.deb
Add a Repository
- name: Add signing key
ansible.builtin.apt_key:
url: https://packages.grafana.com/gpg.key
state: present
- name: Add Grafana repository
ansible.builtin.apt_repository:
repo: "deb https://packages.grafana.com/oss/deb stable main"
state: present
filename: grafana
- name: Install Grafana
ansible.builtin.apt:
name: grafana
state: present
update_cache: true
Modern Approach (signed-by)
- name: Add key to keyrings
ansible.builtin.get_url:
url: https://packages.grafana.com/gpg.key
dest: /usr/share/keyrings/grafana.asc
- name: Add repository with signed-by
ansible.builtin.apt_repository:
repo: "deb [signed-by=/usr/share/keyrings/grafana.asc] https://packages.grafana.com/oss/deb stable main"
state: present
Autoremove Unused Dependencies
- name: Remove unnecessary packages
ansible.builtin.apt:
autoremove: true
# Autoremove and autoclean
- name: Clean up
ansible.builtin.apt:
autoclean: true
autoremove: true
Install Latest Version
# Ensure latest version (upgrade if newer available)
- name: Install latest nginx
ansible.builtin.apt:
name: nginx
state: latest
update_cache: true
cache_valid_time: 3600
⚠️ state: latest runs upgrades on every play — use state: present in production to avoid unexpected upgrades.
Key Parameters
| Parameter | Default | Description |
|-----------|---------|-------------|
| name | — | Package name(s) |
| state | present | present, absent, latest, fixed |
| update_cache | false | Run apt update first |
| cache_valid_time | 0 | Skip cache update if recent (seconds) |
| upgrade | — | safe, full, dist |
| purge | false | Remove config files with absent |
| deb | — | Path to .deb file |
| autoremove | false | Remove unused dependencies |
| force_apt_get | false | Use apt-get instead of aptitude |
| install_recommends | true | Install recommended packages |
apt vs package Module
# ansible.builtin.apt — Debian/Ubuntu only, full APT features
- ansible.builtin.apt:
name: nginx
state: present
update_cache: true
# ansible.builtin.package — cross-platform, limited features
- ansible.builtin.package:
name: nginx
state: present
Use apt when you need APT-specific features (cache, repos, purge). Use package for cross-platform playbooks.
Practical Examples
Bootstrap a Server
- name: Bootstrap Ubuntu server
hosts: new_servers
become: true
tasks:
- name: Update cache and upgrade
ansible.builtin.apt:
update_cache: true
upgrade: safe
- name: Install base packages
ansible.builtin.apt:
name:
- curl
- wget
- git
- vim
- htop
- unzip
- jq
- ca-certificates
- gnupg
- lsb-release
state: present
- name: Remove unwanted packages
ansible.builtin.apt:
name:
- telnet
- rsh-client
state: absent
purge: true
- name: Autoremove
ansible.builtin.apt:
autoremove: true
Conditional Install by OS Version
- name: Install Python
ansible.builtin.apt:
name: "{{ python_pkg }}"
state: present
vars:
python_pkg: "{{ (ansible_distribution_version is version('22.04', '>=')) | ternary('python3.11', 'python3.10') }}"
Hold/Unhold Package Version
- name: Hold kernel version
ansible.builtin.dpkg_selections:
name: linux-image-generic
selection: hold
- name: Unhold later
ansible.builtin.dpkg_selections:
name: linux-image-generic
selection: install
FAQ
What's the difference between state present and latest?
present installs the package if missing but doesn't upgrade it. latest always checks for newer versions and upgrades. Use present in production for stability; use latest only when you explicitly want automatic upgrades.
How do I avoid running apt update every time?
Use cache_valid_time: update_cache: true with cache_valid_time: 3600 skips the update if the cache was refreshed within the last hour (3600 seconds).
Why does apt fail with "could not get lock"?
Another process (unattended-upgrades, another apt instance) holds the lock. Either wait, disable unattended-upgrades during deployment, or add a pre-task that waits for the lock to release.
How do I install a package from a specific repository?
Add the repository first with apt_repository, then install with apt. Use default_release parameter to specify the release if needed: default_release: bullseye-backports.
Conclusion
The apt module is essential for managing Debian/Ubuntu servers. Use update_cache with cache_valid_time to avoid unnecessary updates, state: present for stability, and combine with apt_repository and apt_key for third-party packages. For cross-platform playbooks, consider the package module instead.
Related Articles
• How to Install Ansible on Ubuntu 24.04 • Ansible copy Module Guide • Ansible service Module GuideSee also
• How to Install Multiple Packages in Ansible (One Task)Category: installation