Atuin cheatsheet: Ctrl-R search keys, filter and search modes, non-interactive flags, sync and …
Ansible Cheatsheet Ansible Cheatsheet

Summary
Ansible is what I grab the moment a server count goes above one. These notes are the stuff I actually type: inventory patterns, the module table I scan for every task, and the Vault commands I keep mixing up. I usually run these playbooks from a Jenkins stage against hosts provisioned by CloudFormation.
Inventory
# inventory.ini (INI format)
[web]
web1.example.com
web2.example.com ansible_host=10.0.1.12
[db]
db1.example.com ansible_user=postgres
[prod:children]
web
db
[prod:vars]
ansible_user=deploy
env_name=prod
# inventory.yaml (YAML format)
all:
children:
web:
hosts:
web1.example.com:
web2.example.com: { ansible_host: 10.0.1.12 }
db:
hosts:
db1.example.com:
vars: { ansible_user: postgres }
Per-host/per-group variable files auto-load from group_vars/all.yaml, group_vars/<group>.yaml (or a group_vars/<group>/ directory, vault files included), and host_vars/<host>.yaml next to the inventory or playbook.
Expand your knowledge with Atuin Cheatsheet
ansible-inventory -i inventory.yaml --graph # visualise groups
Ad-hoc Commands
ansible all -i inventory.yaml -m ping # connectivity check
ansible web -a 'uptime' # default module: command
ansible db -b -m service -a 'name=postgresql state=restarted' # -b = become (sudo)
ansible all -b -m apt -a 'name=htop state=present update_cache=yes'
ansible 'web1*' -m shell -a 'ss -tlnp | grep 443' # shell when you need pipes
ansible all --limit 'prod:!db' -m ping # pattern: prod except db
Useful flags: -f 20 (forks), -K (ask sudo password), -u deploy (remote user), --one-line.
Deepen your understanding in Docker Cheatsheet
Playbook Anatomy
Docs: Ansible playbooks, Ansible docs
Explore this further in AWS CloudFormation Cheatsheet
---
- name: Configure web tier
hosts: web
become: true
vars_files:
- vars/common.yaml
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
tags: [packages]
- name: Deploy config
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart nginx
tags: [config]
handlers:
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
ansible-playbook -i inventory.yaml site.yaml
ansible-playbook site.yaml --limit web --tags config --check --diff
ansible-playbook site.yaml --syntax-check --list-tasks --list-hosts
Common Modules
| Module | Purpose | Key params |
|---|---|---|
apt / yum / dnf | Package management (package = distro-agnostic) | name, state, update_cache |
copy | Push static file/content | src, dest, mode, content |
template | Render Jinja2 to remote | src (.j2), dest, validate |
file | Files, dirs, links, perms | path, state (touch/directory/link/absent), mode, owner |
service / systemd | Manage services | name, state, enabled, daemon_reload |
user | Manage users | name, groups, shell, state |
lineinfile | Edit single line idempotently | path, regexp, line, state |
git | Clone/update repos | repo, dest, version |
uri | HTTP calls / health checks | url, method, status_code, body_format |
command | Run command (no shell) | cmd, creates, chdir |
shell | Run through /bin/sh | needed for pipes, redirects, $VAR |
command vs shell: prefer command (safer, no shell injection); use shell only when you need pipes/globs/env expansion. Neither is idempotent by default; guard with creates:, changed_when:, or better, find a real module.
Discover related concepts in AWS CloudFormation Cheatsheet
Variables & Precedence
Low → high (abridged to the ones that matter day-to-day): role defaults/main.yaml → group_vars/all → group_vars/<group> → host_vars/<host> → play vars:/vars_files: → task vars: → set_fact/registered vars → extra vars -e key=value (always wins).
Uncover more details in Bash Basics Cheatsheet
- name: Register output for later
ansible.builtin.command: git rev-parse --short HEAD
register: git_sha
changed_when: false
# use later as: {{ git_sha.stdout }}
Facts
Docs: Discovering variables: facts and magic variables, Ansible docs
ansible web1 -m setup # everything
ansible web1 -m setup -a 'filter=ansible_mem*' # filtered
Common ones: ansible_hostname, ansible_distribution, ansible_default_ipv4.address, ansible_processor_vcpus, ansible_memtotal_mb. Set gather_facts: false on plays that don’t need them; big speedup on large inventories.
Journey deeper into this topic with AWS CloudFormation Cheatsheet
Loops & Conditionals
Docs: Loops, Ansible docs
- name: Install packages
ansible.builtin.apt:
name: "{{ item }}"
state: present
loop: [nginx, certbot, jq]
- name: Create users with attributes
ansible.builtin.user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
loop:
- { name: alice, groups: sudo }
- { name: bob, groups: docker }
- name: Only on Debian prod hosts # list items are AND-ed
ansible.builtin.apt:
name: unattended-upgrades
when:
- ansible_os_family == 'Debian'
- env_name == 'prod'
Retry pattern: until: result.status == 200 with retries: 10 and delay: 5 on a registered task.
Enrich your learning with Bash Basics Cheatsheet
Handlers & notify
Handlers run once at the end of the play, only if something notified them, in the order they are defined (not notification order).
tasks:
- name: Update nginx config
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Reload nginx
handlers:
- name: Reload nginx
ansible.builtin.service:
name: nginx
state: reloaded
Force handlers to fire mid-play with a ansible.builtin.meta: flush_handlers task.
Gain comprehensive insights from AWS CloudFormation Cheatsheet
Roles Layout
Docs: Roles, Ansible docs
roles/nginx/
├── defaults/main.yaml # overridable defaults (lowest precedence)
├── vars/main.yaml # role constants (high precedence)
├── tasks/main.yaml # entry point
├── handlers/main.yaml
├── templates/ + files/ # nginx.conf.j2, static assets
└── meta/main.yaml # dependencies, galaxy info
ansible-galaxy init roles/myrole # scaffold the layout above
ansible-galaxy install -r requirements.yaml # pull external roles/collections
Apply in a play with roles: [common, nginx], or role: nginx plus inline vars: to override defaults.
Master this concept through Bash CLI One-Liners Cheatsheet
Vault
Docs: Protecting sensitive data with Ansible Vault, Ansible docs
ansible-vault create group_vars/prod/vault.yaml # new encrypted file
ansible-vault edit group_vars/prod/vault.yaml
ansible-vault encrypt secrets.yaml
ansible-vault decrypt secrets.yaml
ansible-vault encrypt_string 's3cret' --name db_password # inline single value
ansible-playbook site.yaml --ask-vault-pass
ansible-playbook site.yaml --vault-password-file ~/.vault_pass # chmod 600, gitignore it
Convention: keep secrets in vault.yaml prefixed vault_, reference them from a plaintext vars.yaml (db_password: "{{ vault_db_password }}") so grep still finds variable names.
Delve into specifics at AWS CloudFormation Cheatsheet
Tags, Check Mode & Diff
Docs: Tags, Ansible docs
ansible-playbook site.yaml --tags 'config,certs'
ansible-playbook site.yaml --skip-tags packages
ansible-playbook site.yaml --check --diff # dry run + show file changes
--check predicts changes without applying; --diff shows template/lineinfile deltas. Tasks that must always/never run: tags: always / tags: never.
Deepen your understanding in Docker Cheatsheet
--check --diff against prod part of your review flow. A playbook that errors in check mode (usually a command task whose output later tasks depend on) is telling you where idempotency is broken. Fix it with check_mode: false on the task or a proper module.ansible.cfg Essentials
Docs: Ansible configuration settings, Ansible docs
1Deepen your understanding in Docker Cheatsheet
# ansible.cfg (project root wins over ~/.ansible.cfg)
[defaults]
inventory = inventory/inventory.yaml
remote_user = deploy
forks = 20
host_key_checking = False # convenient for cattle; understand the tradeoff
stdout_callback = yaml
[privilege_escalation]
become = True
[ssh_connection]
pipelining = True # big speedup
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
Jinja2 Templating Basics
# templates/nginx.conf.j2
worker_processes {{ ansible_processor_vcpus }};
events { worker_connections {{ nginx_worker_connections | default(1024) }}; }
{% for site in sites %}
server {
listen 80;
server_name {{ site.domain }};
{% if site.redirect_https | default(false) %}
return 301 https://{{ site.domain }}$request_uri;
{% endif %}
}
{% endfor %}
Filters I use constantly: default('x'), join(','), to_yaml / to_nice_json, regex_replace('a', 'b'), b64encode, ternary('yes', 'no'). Test any expression fast with ansible localhost -m debug -a "msg={{ expr }}".
Deepen your understanding in Docker Cheatsheet
Related Cheatsheets
- AWS CloudFormation: intrinsic functions, change sets, and drift detection to provision the infrastructure these playbooks configure
- Jenkins: wire
ansible-playbookinto declarative pipelines with credential binding, parameters, and parallel stages - Bash Basics: quoting, exit codes, and error handling for every
command/shelltask and dynamic-inventory script
Everything else is in the DevOps Tooling group, or start from the full cheatsheet library.
Similar Articles
Related Content
More from devops
A cost cheatsheet for running a product cheaply: free-tier hosting, serverless databases, auth, and …
Quick-reference tmux cheatsheet: sessions, windows, panes, copy mode, synchronize-panes, .tmux.conf …
You Might Also Like
Quick-reference Bash basics cheatsheet: variables, parameter expansion, conditionals, loops, arrays, …

