A cheat sheet for Ansible, the automation tool.
Let's create the largest and most comprehensive cheat sheet for Ansible. If you have a tip or trick that you think should be included, please contribute.
In “The Ansible Workshop,” you will deep dive into the world of Ansible, the amazing automation tool that converts complex IT tasks into a set of easy, simple-to-repeat steps. This guide is your roadmap to mastering Ansible, whether you are a novice just starting to use Ansible or an intermediate user who has already used Ansible and is looking for additional information and tricks to enhance your skills.
You can get it on Amazon
DevOpsLinks - The Ultimate DevOps Newsletter. Curated DevOps news, tutorials, tools, jobs, podcasts, and more. Delivered to your inbox every week.
If you’re seeking a cozy sweatshirt to wear during your extended coding sessions or a mug to exhibit your passion for programming, you can find it all here
If you would like to sponsor this project, please contact me at aymen at faun dot dev.
Let’s create the largest and most comprehensive list of Ansible tools and resources. If you have a tool or resource that you think should be included, please contribute.
# Ubuntu/Debian
sudo apt update
sudo apt install ansible
# On Red Hat-based systems (Fedora, CentOS)
sudo yum install ansible
Or use pip:
pip install ansible
Or use pipx:
pipx install ansible
Use Homebrew:
brew install ansible
Ansible can be run from inside a Windows Subsystem for Linux (WSL) instance. First, ensure that WSL is installed, then install Ansible in the Linux distribution of your choice, following the Linux installation steps.
Default Ansible configuration settings can be overridden using environment variables. The same variables can be used to override settings in the ansible.cfg
file in ini format. Typically, environment variables are in capital letters, while the corresponding configuration settings are in lowercase.
Environment Variable | ansible.cfg Variable | ansible.cfg Section | Description |
---|---|---|---|
ANSIBLE_CONFIG |
N/A | N/A | Specifies the path to the Ansible configuration file. |
ANSIBLE_DEBUG |
debug |
[defaults] |
Enables or disables debug output. Set to True for verbose debug information. |
ANSIBLE_INVENTORY |
inventory |
[defaults] |
Path to the inventory file or script. |
ANSIBLE_NOCOLOR |
nocolor |
[defaults] |
Disables colored output in Ansible. |
ANSIBLE_FORCE_COLOR |
force_color |
[defaults] |
Forces colored output even when not in a TTY. |
ANSIBLE_HOST_KEY_CHECKING |
host_key_checking |
[defaults] |
Enables or disables SSH host key checking. |
ANSIBLE_REMOTE_USER |
remote_user |
[defaults] |
Default remote user for SSH connections. |
ANSIBLE_PRIVATE_KEY_FILE |
private_key_file |
[defaults] |
Specifies the private key file for SSH. |
ANSIBLE_TIMEOUT |
timeout |
[defaults] |
Connection timeout duration in seconds. |
ANSIBLE_ROLES_PATH |
roles_path |
[defaults] |
Specifies the path to Ansible roles. |
ANSIBLE_LIBRARY |
library |
[defaults] |
Path to custom module directories. |
ANSIBLE_RETRY_FILES_ENABLED |
retry_files_enabled |
[defaults] |
Enables or disables the creation of retry files. |
ANSIBLE_VAULT_PASSWORD_FILE |
vault_password_file |
[defaults] |
Path to the Ansible vault password file. |
ANSIBLE_VAULT_IDENTITY_LIST |
vault_identity_list |
[defaults] |
List of vault identities for decryption. |
ANSIBLE_STDOUT_CALLBACK |
stdout_callback |
[defaults] |
Sets the default callback plugin for output formatting. |
ANSIBLE_CALLBACK_WHITELIST |
callback_whitelist |
[defaults] |
List of callback plugins allowed to execute. |
ANSIBLE_FORKS |
forks |
[defaults] |
Number of parallel processes to use. |
ANSIBLE_ASK_VAULT_PASS |
ask_vault_pass |
[defaults] |
Determines whether Ansible prompts for the vault password by default. |
ANSIBLE_TRANSPORT |
transport |
[defaults] |
Specifies the connection type (e.g., SSH, WinRM). |
ANSIBLE_GATHERING |
gathering |
[defaults] |
Configures the default fact gathering behavior. |
ANSIBLE_GATHER_SUBSET |
gather_subset |
[defaults] |
Specifies a subset of facts to gather. |
ANSIBLE_SSH_ARGS |
ssh_args |
[ssh_connection] |
Extra arguments to pass to the SSH command. |
ANSIBLE_SSH_RETRIES |
retries |
[ssh_connection] |
Specifies the number of attempts Ansible will make to connect via SSH before giving up. |
ANSIBLE_BECOME |
become |
[privilege_escalation] |
Enables or disables privilege escalation. The default is False . |
ANSIBLE_BECOME_METHOD |
become_method |
[privilege_escalation] |
The method used for privilege escalation, the default is sudo . |
ANSIBLE_BECOME_USER |
become_user |
[privilege_escalation] |
The user to become on privilege escalation, the default is root . |
ANSIBLE_BECOME_ASK_PASS |
become_ask_pass |
[privilege_escalation] |
Prompts for a password for privilege escalation, the default is False . |
ANSIBLE_GALAXY_SERVER |
server |
[galaxy] |
Specifies the default Galaxy server from which roles are installed. |
ANSIBLE_INVENTORY_ENABLED |
inventory_enabled |
[inventory] |
Specifies the enabled inventory plugins. The default is [‘host_list’, ‘script’, ‘auto’, ‘yaml’, ‘ini’, ‘toml’] . |
For more detailed information on these configurations, consult the official Ansible documentation.
[web]
192.168.1.2 ansible_ssh_user=ubuntu
[db]
192.168.1.3 ansible_ssh_user=root
all:
hosts:
192.168.1.2:
ansible_ssh_user: ubuntu
192.168.1.3:
ansible_ssh_user: root
Replace the IP addresses and ansible_ssh_user
with your server details.
Variable | Description |
---|---|
ansible_connection |
The type of connection to the host. The default is ‘smart’. It supports SSH (smart , ssh , paramiko ) and other types. |
ansible_host |
The hostname or IP to connect to, if different from the alias. |
ansible_port |
The connection port number. The default is 22 for SSH. |
ansible_user |
The username for connecting to the host. |
ansible_password |
The password for authentication (use vault for security). |
ansible_ssh_private_key_file |
The private key file for SSH, useful for multiple keys. |
ansible_ssh_common_args |
The common arguments appended to sftp, scp, ssh commands. |
ansible_sftp_extra_args |
The extra arguments for the sftp command line. |
ansible_scp_extra_args |
The extra arguments for the scp command line. |
ansible_ssh_extra_args |
The extra arguments for the ssh command line. |
ansible_ssh_pipelining |
Whether to use SSH pipelining, overrides ansible.cfg setting. |
ansible_ssh_executable |
Overrides the default system ssh, added in version 2.2. |
ansible_become |
Forces privilege escalation, equivalent to ansible_sudo or ansible_su . |
ansible_become_method |
Sets the privilege escalation method. |
ansible_become_user |
Sets the user for privilege escalation. |
ansible_become_password |
Sets the privilege escalation password (use vault for security). |
ansible_become_exe |
Sets the executable for the escalation method. |
ansible_become_flags |
Flags for the selected escalation method, can be set in ansible.cfg. |
ansible_shell_type |
The shell type of the target system. The default is Bourne (sh) compatible. |
ansible_python_interpreter |
The Python interpreter path on the target host. |
ansible_*_interpreter |
The generic interpreter setting, works like ansible_python_interpreter . New in version 2.1. |
ansible_shell_executable |
The shell executable Ansible uses on the target, overrides ansible.cfg. |
This table provides a summary of the host-specific variables in Ansible. For detailed information and examples, refer to the official Ansible documentation.
To ensure that Ansible can communicate with your managed nodes, use the ping
module:
ansible all -m ping -i inventory
---
- name: Playbook Name
hosts: all
become: yes
become_user: root
become_method: sudo
vars:
my_var: 123
vars_files:
- vars.yml
tasks:
- name: Task Name
command: echo "Hello World!"
Keyword | Description |
---|---|
name |
The name of the playbook or task. |
hosts |
The hosts or host groups to run the playbook on. |
become |
Whether to run tasks with privilege escalation. |
become_user |
The user to become when using privilege escalation. |
become_method |
The method to use for privilege escalation (e.g., sudo). |
remote_user |
The user to connect as on the remote host. |
vars |
The variables to be used in the playbook. |
vars_files |
The files containing variables to be used in the playbook. |
tasks |
The list of tasks to be executed. |
handlers |
The list of handlers to be executed upon notification. |
pre_tasks |
The list of tasks to be executed before roles. |
post_tasks |
The list of tasks to be executed after the main tasks. |
roles |
The list of roles to be included and executed. |
serial |
The number of hosts to process in each playbook run. |
max_fail_percentage |
The maximum failure percentage allowed to continue the playbook. |
any_errors_fatal |
Whether any error is enough to stop the playbook. |
ignore_errors |
Whether to ignore errors on a task. |
gather_facts |
Whether to gather facts at the beginning of the playbook. |
no_log |
Whether to disable logging for a task. |
force_handlers |
Whether to run handlers even if a task fails. |
tags |
The tags associated with tasks or roles for selective running. |
check_mode |
Whether to run the playbook in check mode (dry run). |
diff |
Whether to show differences in tasks where supported. |
connection |
The connection type to use (e.g., ssh , local , winrm ). |
timeout |
The connection timeout duration in seconds. |
gather_subset |
The subset of facts to gather (Possible values: all , min , hardware , network , virtual , ohai , and facter ). |
For detailed information and examples, refer to the official Ansible documentation.
Ad-hoc:
ansible all -m command -a "uptime"
Playbook:
---
- name: Run a Command
hosts: all
tasks:
- name: Run a Command
command: uptime
Ad-hoc:
ansible all -m shell -a "echo $TERM"
Playbook:
---
- name: Run a Shell Command
hosts: all
tasks:
- name: Run a Shell Command
shell: echo $TERM
Ad-hoc:
ansible all -m raw -a "echo $TERM"
Playbook:
---
- name: Run a Raw Command
hosts: all
tasks:
- name: Run a Raw Command
raw: echo $TERM
Ad-hoc:
ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts"
Playbook:
---
- name: Copy a File
hosts: all
tasks:
- name: Copy a File
copy:
src: /etc/hosts
dest: /tmp/hosts
Ad-hoc:
ansible all -m apt -a "name=nginx state=present"
Playbook:
---
- name: Install a Package
hosts: all
tasks:
- name: Install a Package
apt:
name: nginx
state: present
Ad-hoc:
ansible all -m service -a "name=nginx state=restarted"
Playbook:
---
- name: Restart a Service
hosts: all
tasks:
- name: Restart a Service
service:
name: nginx
state: restarted
Ad-hoc:
ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts owner=root group=root mode=0644"
Playbook:
---
- name: Copy a File with Permissions
hosts: all
tasks:
- name: Copy a File with Permissions
copy:
src: /etc/hosts
dest: /tmp/hosts
owner: root
group: root
mode: 0644
Ad-hoc:
ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts owner=root group=root mode=0644 seuser=system_u serole=object_r"
Playbook:
---
- name: Copy a File with Permissions and Context
hosts: all
tasks:
- name: Copy a File with Permissions and Context
copy:
src: /etc/hosts
dest: /tmp/hosts
owner: root
group: root
mode: 0644
seuser: system_u
serole: object_r
ansible-playbook playbook.yml
ansible-playbook playbook.yml -i inventory
ansible-playbook playbook.yml -i inventory --limit "web"
ansible-playbook playbook.yml --limit "web"
ansible-playbook playbook.yml --tags "install,configure"
ansible-playbook playbook.yml --skip-tags "configure"
ansible-playbook playbook.yml --extra-vars "my_var=123"
ansible-playbook playbook.yml --vault-password-file ~/.vault_pass.txt
ansible-playbook playbook.yml --ask-vault-pass
ansible-playbook playbook.yml --ask-become-pass
ansible-playbook playbook.yml --ask-pass
ansible-playbook playbook.yml --check
ansible-playbook playbook.yml --diff
ansible-playbook playbook.yml -v
ansible-playbook playbook.yml -vv
ansible-playbook playbook.yml -vvv
ansible-playbook playbook.yml -vvvv
ansible-playbook playbook.yml -vvvvv
ansible-playbook playbook.yml --forks 50
ansible-playbook playbook.yml --timeout 30
---
- name: Using Jinja2
hosts: localhost
vars:
my_var: 123
tasks:
- name: Using Jinja2
debug:
msg: ""
---
- name: Using Jinja2 with Filters
hosts: localhost
vars:
my_var: 123
tasks:
- name: Using Jinja2 with Filters
debug:
msg: ""
---
- name: Jinja2 Template
hosts: localhost
vars:
my_var: 123
tasks:
- name: Jinja2 Template
template:
src: template.j2
dest: /tmp/template.txt
---
- name: Jinja2 Template with Variables
hosts: localhost
vars:
my_var: 123
tasks:
- name: Jinja2 Template with Variables
template:
src: template.j2
dest: /tmp/template.txt
The “template.j2” file:
Hello World! This is my_var:
---
- name: Templates with Loops
hosts: localhost
vars:
my_list:
- 123
- 456
- 789
tasks:
- name: Templates with Loops
template:
src: template.j2
dest: /tmp/template.txt
The “template.j2” file:
---
- name: Templates with Conditionals
hosts: localhost
vars:
my_var: 123
tasks:
- name: Templates with Conditionals
template:
src: template.j2
dest: /tmp/template.txt
The “template.j2” file:
---
- name: Templates with Filters
hosts: localhost
vars:
my_var: 123
tasks:
- name: Templates with Filters
template:
src: template.j2
dest: /tmp/template.txt
The “template.j2” file:
Hello, World! This is my_var:
Pattern | Description |
---|---|
all |
All hosts in the inventory. |
* |
Same as all . |
group1 |
All hosts in the group group1 . |
group1:group2 |
All hosts in the groups group1 and group2 . |
group1:&group2 |
All hosts in both group1 and group2 . |
group1:!group2 |
All hosts in group1 that are not in group2 . |
group1:&group2:!group3 |
All hosts in both group1 and group2 that are not in group3 . |
group1:group2:&group3 |
All hosts in both group1 and group2 that are also in group3 . |
group1:group2:!group3:&group4 |
All hosts in both group1 and group2 that are not in group3 and are also in group4 . |
ansible-playbook playbook.yml --syntax-check
ansible all -m ping
ansible all -m ping -c ssh
ansible all -m ping -c winrm
ansible all -m ping -c local
ansible all -m ping -v
ansible all -m ping -vv
ansible all -m ping -vvv
ansible all -m ping -vvvv
ansible all -m ping -vvvvv
ANSIBLE_DEBUG=1 ansible all -m ping
---
- name: Capture Output
hosts: all
tasks:
- name: Capture Output
command: echo "Hello World!"
register: output
- debug:
var: output
---
- name: Capture Output and Show Only Specific Fields
hosts: all
tasks:
- name: Capture Output and Show Only Specific Fields
command: echo "Hello World!"
register: output
- debug:
var: output.stdout
---
- name: Capture Output and Show Only Specific Fields with Jinja2
hosts: all
tasks:
- name: Capture Output and Show Only Specific Fields with Jinja2
command: echo "Hello World!"
register: output
- debug:
msg: ""
ansible all -m setup
ansible all -m setup -a "filter=ansible_eth*"
ansible all -m setup -a "filter=ansible_eth*" --tree /tmp/facts
---
- name: Setting a Variable
hosts: localhost
vars:
my_var: 123
tasks:
- name: Setting a Variable
debug:
var: my_var
- name: Setting a Variable (debug)
debug:
msg: ""
---
- name: Setting a Variable with Multiple Lines
hosts: localhost
vars:
my_var: >
Hello
World!
tasks:
- name: Setting a Variable with Multiple Lines
debug:
var: my_var
- name: Setting a Variable with Multiple Lines (debug)
debug:
msg: ""
---
- name: Setting a Variable with Multiple Lines and Indentation
hosts: localhost
vars:
my_var: |
Hello
World!
This is indented.
tasks:
- name: Setting a Variable with Multiple Lines and Indentation
debug:
var: my_var
- name: Setting a Variable with Multiple Lines and Indentation (debug)
debug:
msg: ""
---
- name: When
hosts: localhost
vars:
my_var: 123
tasks:
- name: When
debug:
msg: "Hello World!"
when: my_var == 123
---
- name: When with Multiple Conditions
hosts: localhost
vars:
my_var: 123
tasks:
- name: When with Multiple Conditions
debug:
msg: "Hello World!"
when:
- my_var == 123
- my_var != 456
---
- name: Looping Over a List
hosts: localhost
vars:
my_list:
- 123
- 456
- 789
tasks:
- name: Looping Over a List
debug:
msg: ""
loop: ""
---
- name: Looping Over a Dictionary
hosts: localhost
vars:
my_dict:
key1: 123
key2: 456
key3: 789
tasks:
- name: Looping Over a Dictionary
debug:
msg: ": "
loop: ""
---
- name: Looping Over a Dictionary with Nested Items
hosts: localhost
vars:
my_dict:
key1:
- 123
- 456
- 789
key2:
- 123
- 456
- 789
key3:
- 123
- 456
- 789
tasks:
- name: Looping Over a Dictionary with Nested Items
debug:
msg: "Key: , Values: "
with_dict: ""
---
- name: Looping Over a List with with_items
hosts: localhost
vars:
my_list:
- 123
- 456
- 789
tasks:
- name: Looping Over a List with with_items
debug:
msg: ""
with_items: ""
---
- name: Using Handlers
hosts: localhost
tasks:
- name: Using Handlers
debug:
msg: "Hello World!"
notify: My Handler
handlers:
- name: My Handler
debug:
msg: "This is my handler."
---
- name: Using Handlers with Multiple Tasks
hosts: localhost
tasks:
- name: Using Handlers with Multiple Tasks
debug:
msg: "Hello World!"
notify: My Handler
- name: Using Handlers with Multiple Tasks
debug:
msg: "Hello World!"
notify: My Handler
handlers:
- name: My Handler
debug:
msg: "This is my handler."
---
- name: Using Handlers with Multiple Tasks and Different Handlers
hosts: localhost
tasks:
- name: Using Handlers with Multiple Tasks and Different Handlers
debug:
msg: "Hello World!"
notify: My Handler 1
- name: Using Handlers with Multiple Tasks and Different Handlers
debug:
msg: "Hello World!"
notify: My Handler 2
handlers:
- name: My Handler 1
debug:
msg: "This is my handler 1."
- name: My Handler 2
debug:
msg: "This is my handler 2."
---
- name: Using ignore_errors to Continue Execution Even After Failures
hosts: localhost
tasks:
- name: Using ignore_errors to Continue Execution Even After Failures
command: /bin/false
ignore_errors: yes
- name: Using ignore_errors to Continue Execution Even After Failures
debug:
msg: "Hello World!"
---
- name: Using changed_when to Control When a Task Is Considered Changed
hosts: localhost
tasks:
- name: Using changed_when to Control When a Task Is Considered Changed
command: /bin/false
register: output
changed_when: output.rc != 2
- name: Using changed_when to Control When a Task Is Considered Changed
debug:
msg: "Hello World!"
---
- name: Example playbook with failed_when
hosts: localhost
tasks:
- name: Example playbook with failed_when (will fail)
command: /bin/false
register: output
# The normal exit code for /bin/false is 1
failed_when: output.rc == 2
- name: Example playbook with failed_when
debug:
msg: "Hello World!"
---
- name: Failing a Playbook with fail
hosts: localhost
tasks:
- name: Failing a Playbook with fail
fail:
msg: "This task will always fail."
ansible-vault edit file.yml
ansible-vault rekey file.yml
ansible-vault view file.yml
ansible-vault encrypt file.yml
ansible-vault encrypt file.yml --vault-password-file ~/.vault_pass.txt
ansible-vault decrypt file.yml
ansible-vault encrypt_string "Hello World!" --name "my_var"
ansible-vault encrypt_string "Hello World!" --name "my_var" --vault-password-file ~/.vault_pass.txt
---
- name: Running a Task Asynchronously
hosts: localhost
tasks:
- name: Running a Task Asynchronously
command: /bin/bash -c "for i in `seq 1 5`; do echo $i; sleep 1; done"
async: 60
poll: 0
---
- name: Rolling Update with Timeout
hosts: localhost
tasks:
- name: Start the application update (async)
command: /bin/bash -c "for i in `seq 1 5`; do echo $i; sleep 1; done"
async: 60
poll: 0
register: update_result
- name: Wait for the update to complete
async_status:
jid: ""
register: job_result
until: job_result.finished
retries: 60 # Check the status every 10 seconds (60 times)
- name: Check if the update was successful
debug:
msg: "Update successful"
when: job_result.finished
ansible-galaxy init my_role
---
- name: Using a Role
hosts: localhost
roles:
- my_role
---
- name: Using a Role with Variables
hosts: localhost
roles:
- role: my_role
vars:
my_var: 123
---
- name: Using a Role with Multiple Variables
hosts: localhost
roles:
- role: my_role
vars:
my_var1: 123
my_var2: 456
---
- name: Using a Role with Tags
hosts: localhost
roles:
- role: my_role
tags:
- install
- configure
ansible-galaxy search nginx
ansible-galaxy install nginx
ansible-galaxy install elastic.elasticsearch,7.15.0
ansible-galaxy collection install community.general
ansible-galaxy collection install community.general:8.1.0
ansible-galaxy collection install community.general-8.1.0.tar.gz
ansible-galaxy collection install community.general-8.1.0/