Overview
I use Ansible1 a lot, both at work and for the sudo.is
infrastructure2, see
my infra
repo.
Install
Use pipx
:
$ pipx install --include-deps ansible
To install additonal Python dependencies, use inject
:
$ pipx inject ansible $dependency
Upgrading existing Ansible:
$ pipx upgrade --include-injected ansible
Ansible is using the deprecated IPAddress.is_private
function in netaddr
to
check if an IP address is private or public3.
{{ [ansible_default_ipv4.address] | ansible.utils.ipaddr("private") }}
This will now result in:
TASK [role: task] ***************************
An exception occurred during task execution.
fatal: [sudo.is]: FAILED! => {
"changed": false
}
MSG:
AttributeError: 'IPNetwork' object has no attribute 'is_private'
Until utils.ipaddr
is fixed in the base ansible_collections
is fixed, older
version of netaddr
where IPAddress.is_private
needs to be used.
$ pipx inject ansible netaddr==0.10.0
This has been fixed in ansible-collections/ansible.utils
4,
but has not been released yet.
If the target host has version 2.32.3 of python3-requests
, you may get this error
on community.docker
tasks:
TASK [docker ] ******************************
fatal: [sudo.is]: FAILED! => {
"changed": false
}
MSG:
Error connecting: Error while fetching server API version: Not supported URL scheme http+docker
That is because requests=2.32.0
is not compatible with the /var/run/docker.sock
unix
socket5. Version 3.10.2 and up of community.docker
has
a workaround to this issue6 (using a new
and different API in reqests
).
$ ansible-galaxy collection install community.docker --force
The --force
flag is needed since the collection is already installed, and will install
the newer version.
Configuration
Re-use SSH connections
For faster ssh connections, enable pipelining
and use the ControlPersis
features of ssh
to re-use SSH connections instead of always reconnecting:
[defaults]
forks = 20
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o PreferredAuthentications=publickey
control_path = /tmp/ansible-ssh-%%h-%%p-%%r
pipelining = true
This will re-use connections for 60s and then close them.
Output formats
Ansible calls output formats "callbacks"7:
debug
: indents Ansible's output and data structures, this is a good and sane default to use.
The output format/callback can be set in the ansible.cfg
config files:
[defaults]
stdout_callback = debug
The output format can also be set via an environment variable:
ANSIBLE_STDOUT_CALLBACK="debug"
Since environment variables take precedence over the config file, this will use
the output format debug
regardless of config file values.
ansible_managed
By default, the ansible_managed
variable will render to "Ansible managed"
, but
it can provide more useful information, such as the path of the template in a Git
repo.
[defaults]
ansible_managed = ansible_managed:{{{{ lookup('pipe', 'git rev-parse --show-toplevel')|basename }}}}/roles/{{{{ role_name }}}}/{{{{ template_path }}}}{{{{ lookup('pipe', 'git log -1 ' + template_fullpath|quote) | default(false, true) | ternary("", ",UNCOMITTED") }}}}
This will include the path to the source template, as well as the short commit hash that the file is templated from.
Default to showing diff
To make Ansible show diffs by default:
[diff]
always = true
Makes --diff
the default for ansible-playbook
and friends.
Convergence
Prevent ansible from printing every ok
task with:
ANSIBLE_DISPLAY_SKIPPED_HOSTS="false"
ANSIBLE_DISPLAY_OK_HOSTS="false"
This will only print failed
or changed
tasks to stdout
, makes it
easy to parse the output into a convergence report.
References
git.sudo.is/ben/infra
- Ansible for sudo.is
(mirrored to GitHub: benediktkr/infra
)
Ansible Callback-Plugins, includes GIFs of the output in action.