A guide on how to write effective and fault tolerant Ansible code.
Ansible code convention:
- Descriptions are not capitalized
- name: ensuring something- The indentation is 2 (two) spaces, for vim you can use vim-ansible-yaml
- Use dict notation, not in-line, this prevents errors later on, example:
bad: this=command
good:
  this: command- When a module does require '=' parameters, use the following:
moduleX:
  args:
    var: 'something'- When a module does call something using '=' parameters, use the following:
moduleX: >
  var='something'- Playbooks should be used for role assignments.
- Use tagging to call a role:
 
roles:
  - { role: myrole, tags: ['myrole', 'optional_alias_myrole'] }- Roles should be used for functional blocks.
- All templates must contain a {{ ansible_managed }}header.
- Ensure ansible_managedheader is statically set inansible.cfgor it breaks idempotency.
- Every role has a self documenting defaults/main.ymlfile that contains all set-able variables.
- All variables in the role scope must be named role_variablewith the option of spaces being replaced by_hyphens.
- The use of dict style variable settings role.variableis discouraged as it complicates overriding.
- Every variable on a new line for readability.
- Role must be a complete basic implementation without requiring further variables.
- Role must be idempotent, meaning: including the role must result in OK, not changed or error when nothing has been changed on the target host.
- Try to stow everything in main.yml, only use include when it makes sense, which is:- when you need to support multiple platforms, then include each in main.yml
 
- when you need to support multiple platforms, then include each in 
- Use of comments indicate bad code.
 
- All templates must contain a 
- Completeness (especially idempotency) on the target platform is preferred over portability when starting out a new role.
- Don't use: backup: yes, rely on git instead!
General rule for when conditions is that variables do not have to be surrounded like {{ var }}. Below are some general use-cases for when conditions:
- When dealing with multiple suitors for a single condition:
- set_fact:
    hello: 'world'
- name: do task
  command: echo hello world!
  when:
    - hello | intersect( ['world', 'universe'] )- When dealing with multiple whenconditions that need to match in anORfashion:
- name: do task
  command: echo hello world!
  when:
    - ((skip_install != True) or (ansible_os_family == 'Debian'))- When dealing with multiple whenconditions that need to match in anANDfashion:
- name: do task
  command: echo hello world!
  when:
    - (skip_install != True)
    - (ansible_os_family == 'Debian')
    - (command_result.changed == True)