3. Best Practices¶
3.1. General¶
Version control Ansible content
Use single source of truth
Automation should be all or nothing (completely remove manual changes to servers!)
Use the run command modules as a last resort (
command
module is safer thanshell
)shell
can evaluate variables,command
cannot
3.2. Readability¶
Complexity kills (simplify, optimize for readability, think declarative)
Try to use one file if lines are less than 100 (do not start with several files)
If you have more lines, then split
Try to use roles as much as possible, but keep them independent and reusable
YAML is not a programming language
If it's too complex (i.e. struggling with escaping quotes), you're doing something wrong
Vertical reading is easier (split long lines)
Prefer more explicit yaml values)
Be explicit (more verbose) i.e. always define
state
Try other callback plugins i.e.
yaml
(for human readable error messages)Keep plays and playbooks focused
Multiple simple ones are better than having a huge file full of conditionals
Separate provisioning from deployment and configuration tasks
3.3. Performance¶
Profile with
callback
plugin to see which roles and playbooks takes too much timeCI is useless if slow
Disable
gather_facts
if not needed (save few seconds per server)Check
forks
config - by default its 5, update accordingly to number of your serverspackage
- pass a list to name instead of a loop (to execute one command)copy
- only for single files or small dirs, else usesynchronize
modulelineinfile
try to switch to template instead of looping on one file (or useblockinfile
3.4. Inventory¶
Give inventory nodes human-meaningful names rather than IPs or DNS hostnames
If you change inventory file frequently (one or two times a month) use dynamic inventory files
If it's a static environment (new servers are added rarely) use static inventory
Dynamic inventory files are quite easy
3.5. Variables¶
Use descriptive unique human-meaningful variable names
Prefer flat variables over nested
3.6. Templates¶
Ansible uses Jinja2
Jinja2 is powerful. Don't have to use all of it
Templates should be simple
Avoid variable substitution
Avoid setting variables in template
As few Conditionals as possible (do not nest)
Avoid conditional logic based on hostnames
Simple control structures/iterations
Design for your usecase (do not generalize)
Avoid complex iteration conditions
Label template output files as being generated by Ansible (warn not to edit manually)
Consider using
ansible_managed**
variable with the comment filter (it will put date and some other info)
{{ ansible_managed | comment }}
3.7. Roles¶
Keep roles purpose and function focus
Used a
roles/
subdirectory for roles developed for organizational clarity in a single projectFollow the Ansible Galaxy pattern for roles that are to be shared beyond a single project
Start your roles with
ansible-galaxy init
(it will generate directory structure)Remove unneeded directories and stub files (after
ansible-galaxy init
)ansible-galaxy
can point to your internal private repoUse
ansible-galaxy
to install your roles -- even private onesManage your roles in your applications repo
As a part of build process, "push" role to artifact repository
Use
ansible-galaxy
to install role from artifact repository
3.8. Scaling¶
Coordination across a distributed organization
Controlling access to credentials
Track, audit and report Ansible usage
Provide self-service or delegation
Integrate Ansible with enterprise systems
Try Ansible Tower