Contents
- 1 Ansible CLI: Commands and Practical Examples
- 1.1 Prerequisites
- 1.2 Ad-hoc commands with ansible
- 1.3 Running playbooks with ansible-playbook
- 1.4 Inventory inspection with ansible-inventory
- 1.5 Module docs with ansible-doc
- 1.6 Configuration with ansible-config
- 1.7 Secrets with ansible-vault
- 1.8 Roles and collections with ansible-galaxy
- 1.9 Practical examples
- 1.10 SSH and performance tips
- 1.11 Troubleshooting
- 1.12 CLI cheatsheet
- 1.13 Summary
Ansible CLI: Commands and Practical Examples
The Ansible command line makes it easy to run one-off tasks, inspect inventories, validate playbooks, and execute automation at scale. This page is a hands-on reference with copy-paste examples.
Prerequisites
# Ubuntu/Debian
sudo apt update
sudo apt install -y ansible
# Verify
ansible --version
Create a simple inventory you can reuse:
# hosts.ini
[web]
192.168.0.101 ansible_user=ansible
192.168.0.102 ansible_user=ansible
[db]
192.168.0.103 ansible_user=ansible
Ad-hoc commands with ansible
Run a single module against hosts without a playbook. Useful for quick checks and one-off changes.
Ping all hosts
ansible all -i hosts.ini -m ping
Run a shell command
command is safest. shell runs through a shell and is needed for pipes, redirects, and expansions.
# Using 'command' (no shell features)
ansible web -i hosts.ini -m command -a "uptime"
# Using 'shell' for pipes
ansible web -i hosts.ini -m shell -a "df -h | grep /var"
Manage packages
Use the generic package module where possible. It maps to apt, dnf, yum, etc.
ansible web -i hosts.ini -m package -a "name=apache2 state=present" --become
ansible db -i hosts.ini -m package -a "name=mysql-server state=present" --become
Manage services
ansible web -i hosts.ini -m service -a "name=apache2 state=started enabled=true" --become
Copy files and templates
# Copy a static file
ansible web -i hosts.ini -m copy -a "src=./index.html dest=/var/www/html/index.html mode=0644" --become
# Use the template module for Jinja2 templates
ansible web -i hosts.ini -m template -a "src=./vhost.conf.j2 dest=/etc/apache2/sites-available/000-default.conf" --become
ansible all -i hosts.ini -m user -a "name=deploy groups=sudo state=present" --become
ansible all -i hosts.ini -m authorized_key -a "user=deploy state=present key={{ lookup('file','~/.ssh/id_ed25519.pub') }}"
Common CLI flags
-i hosts.inichoose inventory file-l weblimit to group or host-u ansibleSSH user (or set in inventory)--becomeuse sudo on remote-kask for SSH password,-Kask for sudo password-f 20set forks for parallelism-v,-vvvincrease verbosity
Running playbooks with ansible-playbook
Minimal playbook
# site.yml
---
- name: Baseline setup
hosts: all
become: true
tasks:
- name: Ensure latest updates
apt:
update_cache: yes
upgrade: dist
Run it:
ansible-playbook -i hosts.ini site.yml
Tags, check mode, and limit
# Only run tasks tagged 'web'
ansible-playbook -i hosts.ini site.yml --tags web
# Dry run to see changes without applying
ansible-playbook -i hosts.ini site.yml --check
# Limit to a single host
ansible-playbook -i hosts.ini site.yml -l 192.168.0.101
Syntax check and diff
ansible-playbook site.yml --syntax-check
ansible-playbook -i hosts.ini site.yml --diff
Variables and extra vars
ansible-playbook -i hosts.ini site.yml -e "env=prod app_port=8080"
Serial rolling updates
# deploy.yml
- hosts: web
serial: 2
tasks:
- name: Restart app in batches of 2 hosts
service:
name: myapp
state: restarted
ansible-playbook -i hosts.ini deploy.yml
Inventory inspection with ansible-inventory
# Show inventory as Ansible sees it
ansible-inventory -i hosts.ini --list
# Graph view of groups and hosts
ansible-inventory -i hosts.ini --graph
Module docs with ansible-doc
# Search for modules that manage services
ansible-doc -l | grep service
# Read the 'apt' module docs
ansible-doc apt
Configuration with ansible-config
# Show current config values and where they come from
ansible-config dump --only-changed
# View effective config file path
ansible-config view
Secrets with ansible-vault
Encrypt sensitive variables and files.
# Create an encrypted vars file
ansible-vault create group_vars/all/vault.yml
# Edit later
ansible-vault edit group_vars/all/vault.yml
# Run a playbook using a password prompt
ansible-playbook -i hosts.ini site.yml --ask-vault-pass
Example usage inside a playbook:
vars_files:
- group_vars/all/vault.yml
Roles and collections with ansible-galaxy
# Install a role
ansible-galaxy role install geerlingguy.apache
# Install a collection
ansible-galaxy collection install community.mysql
Use them in a playbook:
- hosts: web
become: true
roles:
- geerlingguy.apache
Practical examples
1) Baseline hardening snippet
# harden.yml
- hosts: all
become: true
tasks:
- name: Ensure unattended upgrades
package:
name: unattended-upgrades
state: present
- name: Disable root SSH login
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PermitRootLogin'
line: 'PermitRootLogin no'
create: yes
notify: Restart ssh
handlers:
- name: Restart ssh
service:
name: ssh
state: restarted
ansible-playbook -i hosts.ini harden.yml
2) LAMP stack quick playbook
# lamp.yml
- hosts: web
become: true
vars:
php_packages:
- php
- php-mysql
- libapache2-mod-php
tasks:
- package: { name: apache2, state: present }
- package: { name: mysql-server, state: present }
- package:
name: "{{ php_packages }}"
state: present
- service: { name: apache2, state: started, enabled: true }
- service: { name: mysql, state: started, enabled: true }
- copy:
dest: /var/www/html/info.php
content: "<?php phpinfo(); ?>"
ansible-playbook -i hosts.ini lamp.yml
3) Fact gathering and conditional tasks
# facts.yml
- hosts: all
gather_facts: yes
tasks:
- name: Print OS details
debug:
msg: "{{ ansible_distribution }} {{ ansible_distribution_version }}"
- name: Run only on Ubuntu 22.04
debug:
msg: "Hello Jammy"
when: ansible_distribution == "Ubuntu" and ansible_distribution_major_version == "22"
SSH and performance tips
- Create
~/.ssh/configentries for hosts and set ControlPersist to reuse connections.
# ~/.ssh/config
Host web1
HostName 192.168.0.101
User ansible
ControlMaster auto
ControlPath ~/.ssh/cm-%r@%h:%p
ControlPersist 60s
- Increase forks for large runs:
ansible-playbook -f 20 ... - Use
-lto limit blast radius during testing.
Troubleshooting
SSH permission denied
Check key distribution and user in inventory. Try -u ansible -k if using passwords.
Python not found on target
Install Python on minimal hosts. For Debian/Ubuntu: sudo apt install -y python3.
Module not found
Install the required collection or role. Use ansible-doc to confirm module name.
Playbook logic errors
Use --check, --diff, and -vvv for verbose output. Break changes into tagged tasks.
CLI cheatsheet
| Task | Command |
|---|---|
| Ping all | ansible all -i hosts.ini -m ping |
| Run playbook | ansible-playbook -i hosts.ini site.yml |
| Dry run | ansible-playbook site.yml --check |
| Limit hosts | ansible-playbook site.yml -l web |
| Syntax check | ansible-playbook site.yml --syntax-check |
| Inventory graph | ansible-inventory -i hosts.ini --graph |
| Module docs | ansible-doc apt |
| Vault edit | ansible-vault edit group_vars/all/vault.yml |
| Install role | ansible-galaxy role install geerlingguy.apache |
Summary
The Ansible CLI gives you fast checks with ad-hoc commands, reliable deployments with playbooks, and strong guard rails with check mode and tags. Keep inventories tidy, use roles and collections for reuse, protect secrets with Vault, and validate changes with syntax checks and diffs before you run.