19. Best practices¶
keep it simple
if something feels complicated, then we are probably doing it the wrong way
think about, what you would like to achieve and don’t think about, what you’ve done so far...
version pinning
- yum ->
name: 'docker-{{ docker_version }}' - apt ->
name: 'ntp={{ ntp_version }}' - application deployment with SCM e.g git -> use tags as
version: - use
versionin requirements.yml for Ansible galaxy
- yum ->
keep your inventory file and variables in a git repo (or other version control). this is an excellent way to track changes to your inventory and variables.
If you write the same tasks in multiple playbooks, create a role.
use the prefix
<rolename>_in role variablesroles have defaults variables, that can be overwritten by
group_varsallis for global variables.create a
README.mdfor every role and describe the usage and variables -> maybe use theansible-galaxy init testcommand and take that readmeshare your roles for other projects (internal via
SCM/HTTPor external via Ansible Galaxy)try to avoid tasks with the command or shell module -> Ansible modules are designed to be safely repeatable -> Idempotency!
- Use the file module rather than command with rm, mkdir, rmdir etc
- Other modules that replace shell commands include synchronize, unarchive, git, hg, svn
- if you use command/shell module, have a look at the
createsparameter (only run, if the file is not in place) - command vs shell -> https://blog.confirm.ch/ansible-modules-shell-vs-command/
use
verbositywith the Debug module for messages
- debug:
msg: "This only displays with ansible-playbook -vv+"
verbosity: 2
create tests with tags and modules like
wait_fordon’t use the short forms of tasks / lists / dictionaries in YAML ->
git diff, human readablewith git -> use tags instead of branches as version for SCM checkouts
useful tags of tasks
- configuration
- packages
- installation
- service
- scm
- deployment
- critical
- notification
- debug
if your group_vars / host_vars file is to big -> use folders with sub-files
only parameterize variables you also need in a template or role
use fixed versions for role dependencies
there are ways to automate the role installation via
SCMoransible-galaxy- a task with
local_actionin a playbook - git submodule
- a task with
create a “layer of indirection” for ansible vault variables. See Ansible Docs
You can learn something, if you check out other roles / examples from the Ansible example repo, Ansible Galaxy or the Debops Project
you can use
force: noto transfer a file only, if the destination does not exist (initial configuration). it’s available in some modules likecopy / templatehave a look at the callback plugins
# actionable callback plugin, to only see changed/failed tasks
ANSIBLE_STDOUT_CALLBACK=actionable ansible-playbook playbooks/config_backup.yml -l backup1.pvt.confirm.ch --tags iscsi
# profile_tasks, adds time information to tasks
ANSIBLE_STDOUT_CALLBACK=profile_tasks ansible-playbook playbooks/config_backup.yml -l backup1.pvt.confirm.ch --tags iscsi
# profile_roles, adds timing information to roles
ANSIBLE_STDOUT_CALLBACK=profile_roles ansible-playbook playbooks/config_backup.yml -l backup1.pvt.confirm.ch --tags iscsi
# yaml - yaml-ized Ansible screen output (since Ansible v2.5)
ANSIBLE_STDOUT_CALLBACK=yaml ansible-playbook playbooks/config_backup.yml -l backup1.pvt.confirm.ch --tags iscsi
- decide, if you permanently set the
becomevalue in the configuration, or per playbook or per task. But be aware of the file owner/group-ship. - have a look at ssh key signing
- have a look at ansible-console
- make sure, the control machine(s) uses the same Ansible version. Maybe you can achieve this with Python Virtualenvs.
- have a look at meta “module” (flush_handlers, refresh_inventory, reset_connection, ...)
ansible-console
# run a command
ls -lh
whoami
# run a module
package name=tree state=latest
- use validation for configuration changes (if possible)
validate: '/usr/sbin/apache2ctl -f %s -t'
validate: '/usr/sbin/sshd -t -f %s'
validate: 'visudo -cf %s'
validate: 'grep ntp %s'
19.1. Tuning¶
- Ansible Perfomance Tuning
- Check out the callback plugins Profile_tasks and Profile_roles
- Ansible Strategies
19.2. Styling¶
- use spaces around jinja2 variable names ->
{{ var }}and not{{var}} - All yaml files should use 2 space indents and end with
.yml - choose your quoting style (single
path: '/etc/some.conf'/ doublepath: "/etc/some.conf") - decide to quote not needed stuff like
path: /etc/some.conf
19.3. Useful commands¶
# save facts from all hosts
ansible -m setup --tree /tmp/setup all
ls -l /tmp/setup
# show all variables
ansible -m debug -a "msg='{{ vars }}'" localhost,
19.4. Useful snippets¶
# fileglob
- name: Copy each file over that matches the given pattern
copy:
src: "{{ item }}"
dest: "/etc/ssl/ca"
owner: "root"
mode: 0600
with_fileglob:
- "/playbooks/files/fooapp/*.pem"
{% if inventory_hostname in groups['dbservers'] %}
-A INPUT -p tcp --dport 3306 -j ACCEPT
{% endif %}
19.5. Useful modules¶
Have a look at this modules.
- http://docs.ansible.com/ansible/latest/add_host_module.html
- http://docs.ansible.com/ansible/latest/fetch_module.html
- http://docs.ansible.com/ansible/latest/file_module.html
- http://docs.ansible.com/ansible/latest/stat_module.html
- http://docs.ansible.com/ansible/latest/unarchive_module.html
- http://docs.ansible.com/ansible/latest/copy_module.html
- http://docs.ansible.com/ansible/latest/template_module.html
- http://docs.ansible.com/ansible/latest/filesystem_module.html
- http://docs.ansible.com/ansible/latest/lvg_module.html
- http://docs.ansible.com/ansible/latest/lvol_module.html
- http://docs.ansible.com/ansible/latest/mount_module.html
- http://docs.ansible.com/ansible/latest/get_url_module.html
- http://docs.ansible.com/ansible/latest/git_module.html
- http://docs.ansible.com/ansible/latest/group_by_module.html
- http://docs.ansible.com/ansible/latest/java_cert_module.html
- http://docs.ansible.com/ansible/latest/mail_module.html
- http://docs.ansible.com/ansible/latest/jira_module.html
- http://docs.ansible.com/ansible/latest/lineinfile_module.html
- http://docs.ansible.com/ansible/latest/replace_module.html
- http://docs.ansible.com/ansible/latest/cron_module.html
- http://docs.ansible.com/ansible/latest/include_vars_module.html
- http://docs.ansible.com/ansible/latest/set_fact_module.html
- http://docs.ansible.com/ansible/latest/sysctl_module.html
- http://docs.ansible.com/ansible/latest/pause_module.html
- http://docs.ansible.com/ansible/latest/wait_for_connection_module.html
- http://docs.ansible.com/ansible/latest/wait_for_module.html
- http://docs.ansible.com/ansible/latest/assemble_module.html
- http://docs.ansible.com/ansible/latest/raw_module.html
- http://docs.ansible.com/ansible/latest/script_module.html
- http://docs.ansible.com/ansible/latest/shell_module.html
- http://docs.ansible.com/ansible/latest/command_module.html
- http://docs.ansible.com/ansible/latest/user_module.html
- http://docs.ansible.com/ansible/latest/group_module.html
- http://docs.ansible.com/ansible/latest/apt_module.html
- http://docs.ansible.com/ansible/latest/service_module.html
- http://docs.ansible.com/ansible/latest/package_module.html
- http://docs.ansible.com/ansible/latest/yum_module.html
- http://docs.ansible.com/ansible/latest/yum_repository_module.html
- http://docs.ansible.com/ansible/latest/pip_module.html