Ansible
Inventory
- Create groups at least by location/network/DC, functionality/role and lifecycle (production/test/…)
- Avoid repeating hosts, reuse groups by grouping (i.e. use children)
- Try to setup variables per groups when there are many or common
- For small changes in specific hosts do it on the main inventory, for large settings do it on host_vars
Playbooks
- Start developing with playbooks, then factorize into roles
- Make playbooks includable
- Add sha-bang so they are executable and will also add support for additional ansible flags
- They should be generic on the hosts applicable and specific on the goal/facet they setup.
- Applicable to the largest subset of hosts
- For a specific goal/facet
- For complex scenarios split tasklist, avoid blocks.
#!/usr/bin/ansible-playbook
- –
- hosts: fleet
gatherfacts: true become: true pretasks: […] roles: […] post_tasks: […]
Roles
- Prefix all vars, facts and settings with rolenameVAR
- Set SAFE DEFAULTS for all variables
- Use vars for almost constant values
- Configure variables for all hosts and then in groups/hosts for specific edge-cases
- Try to make the role sensitive to the environment where is applied (autodetect and gather facts) to avoid too much settings
- For complex scenarios split the tasks or even the vars an use include_tasks with proper conditions to match the scenario.
Tags
- Always set at least one tag
- If you use always or never add an additional tag
- Meaningful tags
Our Tags proposal:
- config configuration files and settings
- setup Non-file setup, users, network, …
- install software or code deployment
- service service configuration or management
- auto task is candidate for automation
- init intialization or task required on first time setup
- debug debugging
Tricks
Managing clusters and groups
When dealing with some kind of cluster, use an inventory group cluster holding all members, and use a variable pointing to that group name cluster_group in the inventory.
cluster_group: cluster
On tasks you can filter and control in someway making tasks aware of their membership:
cluster__members: "{{ groups[cluster__group] }}" cluster__notme: "{{ groups[cluster__group] | difference([ansible_hostname]) }}" cluster__default__to__standalone: "{{ groups[cluster__group] if cluster__group is defined else [ inventory__hostname ] }}" cluster__is__standalone: "{{ cluster_members | length <= 1 }}"
Quite useful with delegateto and runonce keywords. Note you can even delegate to a host not currently in play.
- name: Make one node act over the rest vars: - cluster__notme: "{{ groups[cluster__group] | difference([ansible_hostname]) }}" run_once: true delegate__to: "{{ cluster__notme | random }}" action: nodes: "{{ groups[cluster_group] }}"