Ansible Tips Part 3: Write First, Use Variables Later

When first starting out writing tasks within a role, write the entire task as you normally would. do not include any variables or things that may change. by doing this, you keep to the simplest form of Ansible provisioning possible. In the software development world, this is a two-part form of YAGNI and premature optimization. Consider this first cut of the role a draft, requiring proofreading before committing to version control.

---
# roles/ssh/tasks/main.yml
- name: configure sshd daemon
  template: >
    src=sshd_config.j2
    dest=/etc/ssh/sshd_config
    owner=root
    group=root
    mode=644
  sudo: yes
  notify: Restart ssh

Then, once you have finished with the role, re-read each task in the role and look for things that stand out as hard-coded strings. For example, paths to configuration files, owners and groups, or even permissions. Think of each of these as a possible candidate for a variable. Using the above example, I can rewrite the task using variables.

---
# roles/ssh/defaults/main.yml
sshd_config_file: /etc/ssh/sshd_config
sshd_config_owner: root
sshd_config_group: root
sshd_config_permissions: 644

---
# roles/ssh/tasks/main.yml
- name: configure sshd daemon
  template: >
    src=sshd_config.j2
    dest={{ sshd_config_file }}
    owner={{ sshd_config_owner }}
    group={{ sshd_config_group }}
    mode={{ sshd_config_permissions }}
  sudo: yes
  notify: Restart ssh

This example is a bit contrived because the SSH daemon configuration file rarely, if ever, changes its location, owner, group, or permissions. However, it is possible that a super-secure systems administrator might want to change it in a production environment (versus a staging environment). If you use variables, you can tell simply override them with variables from a group_vars file, and now nobody needs to read the role.

Friday's Special Mini-Tip

Notice how awesome the YAML file looks? It fits within 80 characters! That's because I am using YAML multi-line string syntax. Basically, it says that the following value is a multi-line string, even though no quotes are being used.

Here is what the code would look like if it wasn't using multi-line syntax:

---
# roles/ssh/tasks/main.yml
- name: configure sshd daemon
  template: src=sshd_config.j2 dest={{ sshd_config_file }} owner={{ sshd_config_owner }} group={{ sshd_config_group }} mode={{ sshd_config_permissions }}
  sudo: yes
  notify: Restart ssh

Yuck. Now that you've seen the way to make a YAML file more succinct, I no longer want to see super-long-lines-that-wrap-on-and-on in your code. Got it? Thanks.

For reference on the multi-line string syntax, see Example 2.16 of the YAML specification.