• push-based config management, also supports pull
  • copies a generated script to the managed host via ssh and then executes it
  • simple for small setups, powerful enough for complex situations
  • connects to several hosts in parallel (but largest scale only via pull mode)
  • master node only requires ansible, no other server (HTTP etc)
  • managed nodes need no client, only ssh and python
  • written in python, uses yaml playbooks and Jinja2 templates
  • extensible with modules

Further documentation


ansible all -m ping                         # test all hosts by invoking ping module
ansible some-host -m setup                  # display all gathered facts (system info)
ansible some-host -a uptime                 # run a given command
ansible some-host -s -a "tail some-file"    # run a given command with sudo
ansible some-host -s -m apt -a name=htop    # install given package using the apt module
ansible-playbook some-playbook.yml          # run a given playbook
ansible-playbook -C -D some-playbook.yml    # run in dry-run mode (--check) and show diff
ansible-playbook --step playbook.yml        # prompt before running each task
ansible-playbook --limit ahost playbook.yml # run playbook only on given host
ansible-playbook --syntax-check file.yml    # check the syntax of a given playbook
ansible-playbook --list-hosts playbook.yml  # list hosts affected by a given playbook
ansible-playbook --list-tasks playbook.yml  # list tasks defined in a given playbook
ansible -i someinv all --list-hosts         # list all hosts in given inventory
ansible-inventory -i someinv --list         # list hostnames, groups and variables of inventory
ansible-inventory -i someinv --graph        # show ascii graph of host groups
ansible-config dump                         # show ansible config paramaters and non-default values
ansible-doc -l                              # list ansible commands with a short description
ansible-doc some-module                     # read documentation of a given module
ansible <command> -vvvv                     # run command with verbose output for debugging
export ANSIBLE_KEEP_REMOTE_FILES=1          # don't delete remote script files in ~/.ansible/


Minimal setup



- hosts: all
  remote_user: root
  - name: install htop
    apt: name=htop state=present

Command to run playbook

ansible-playbook -i inventory playbook.yml

Typical folder structure

├── ansible.cfg
├── handlers/
├── host_vars/
├── group_vars/
├── inventory
├── roles/
│   └── webserver/
│       ├── defaults/
│       ├── files/
│       ├── handlers/
│       ├── tasks/
│       ├── templates/
│       └── vars/
└── playbook.yml

Variable precedence

-e arg > role > play > host > group > defaults


Example ansible.cfg file to configure ansible

hostfile = hosts
sudo_flags = -HE
retry_files_enabled = False
gathering = smart
hash_behaviour = merge

where the hash_behaviour setting enables merging of hash variables for instance from host_vars and group_vars.

In some cases you may want to add force_handlers = true to trigger handlers even if a failure occured on that host.


Example inventory file

vagrant1 ansible_ssh_host= ansible_ssh_port=2222 ansible_ssh_user=vagrant ansible_ssh_private_key_file=/path_to_VM/.vagrant/machines/default/virtualbox/private_key

[server]                # group


[webserver:children]    # group of groups

Ansible also supports the concept of a dynamic inventory, i.e. an executable script that returns the hosts in JSON format.

Runtime profiling

Ansible offers built-in callbacks to measure the runtime permformance.

  • profile_tasks: show runtime of each tasks and summary with the list of slowest tasks
  • profile_roles: show summary with runtime of the roles
  • timer: show total playbook runtime

Whitelist the callbacks you need in the [default] section of your ansible.cfg.


callback_whitelist = profile_tasks, profile_roles

Enabling the verbose debug output may shed some light on what exactly Ansible is doing that takes so much time.


Playbook Debugger

Ansible can enter an interactive debugger shell if a playbook has an error.


Debugger commands:

p host                      # print host
p result                    # print task result
p task                      # print task name
p task.args                 # print task arguments
p task_vars                 # print task variables
p task_vars['some_key']     # print given task variable
task_vars['some_key'] = 1   # update value of task variable (similarly args)
u                           # update task after modification
r                           # redo task
c                           # continue
q                           # quit