Ansible¶
Introduction¶
- 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
External Links¶
Further documentation¶
Commands¶
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-playbook --list-tags playbook.yml # list tags 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/
Configuration¶
Minimal setup¶
inventory
:
hostname.example.com
playbook.yml
:
- hosts: all
remote_user: root
tasks:
- 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
ansible.cfg¶
Example ansible.cfg
file to configure ansible
[defaults]
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.
inventory¶
Example inventory file
vagrant1 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 ansible_ssh_user=vagrant ansible_ssh_private_key_file=/path_to_VM/.vagrant/machines/default/virtualbox/private_key
[server] # group
vagrant1
[web]
vagrant1
[webserver:children] # group of groups
web
server
Ansible also supports the concept of a dynamic inventory, i.e. an executable script that returns the hosts in JSON format.
Callbacks¶
Ansible offers various callback plugins.
ansible-doc -t callback -l # show list of callback plugins
ansible-doc -t callback <name> # show documentation of given callback
Default callback¶
The normal ansible output is generated by the ansible.builtin.default
callback, which can be customized with env variables.
export ANSIBLE_DISPLAY_OK_HOSTS=no # hide unchanged tasks
export ANSIBLE_DISPLAY_SKIPPED_HOSTS=no # hide skipped tasks
Runtime profiling¶
Some callbacks can be used to measure the runtime performance.
- 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
Enable the callbacks you need in the [default]
section of your ansible.cfg
.
[default]
callbacks_enabled = profile_tasks, profile_roles
Enabling the verbose debug output may shed some light on what exactly Ansible is doing that takes so much time.
export ANSIBLE_DEBUG=1
Playbook Debugger¶
Ansible can enter an interactive debugger shell if a playbook has an error.
export ANSIBLE_ENABLE_TASK_DEBUGGER=True
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
Retry files¶
Ansible can generate a .retry
file with the hostnames that failed (or where offline) during a playbook run. You can then limit the next run to only those hosts.
export ANSIBLE_RETRY_FILES_ENABLED=1
ansible-playbook playbooks/play.yml
ansible-playbook playbooks/play.yml --limit @playbooks/play.retry
Force handlers¶
By default, if a task fails, ansible stops the further execution and skips running all handlers, even if they were notified earlier in the playbook by succeeding tasks. As explained under handlers and failure use the --force-handlers
command-line option or force_handlers: True
to change this behaviour.
Illustrating playbook:
- hosts: localhost
force_handlers: True
handlers:
- name: handler1
debug:
msg: forced handler
- name: handler2
debug:
msg: skipped handler
tasks:
- name: successful task
debug:
msg: successful
changed_when: True # otherwise `debug` reports no change and handlers are not triggered
notify: handler1
- name: failed task
fail:
msg: failed
changed_when: True
notify: handler2
- name: skipped task
debug:
msg: skipped