26 janvier 2018

Ansible role configuration: best practice

Let’s take for example HAProxy. This wonderful piece of software can be configured with hundreds of options. How to write an Ansible role to handle this, AND share this role accross multiple projects/teams/companies ?

The naive solution: the boss template

If you use Ansible, you may have met the boss template: a big template, with dozens of variables (frequently nested) to handle all available configuration options, {% if %} and {% for %} jinja2 everywhere…​ And when someone needs a new option, a new variable is added.

Theses roles are nightmares to maintain. For HAproxy, your template will be huge. Same thing for other softwares (softwares like Kafka, Elasticsearch…​ also have a lot of configuration options).

Furthermore, these roles are impossible to share between teams/open source, because they are often designed for a specific company use case, with a specific configuration.

Move configuration outside of the role.

Let’s continue with HAProxy. Just write a simple HAProxy role: installing HAProxy, templating a default configuration, and dealing with restart/reload on configuration change. But let the person using the role override the default configuration files.
You can see my HAProxy role on Github.

In defaults/main.yml, define a variable containing a list of templates (HAProxy does not support loading configuration from a directory, so these files will be assembled together by the role):

haproxy_templates:
  - src: haproxy.config.j2
    dest: 01_haproxy_config

haproxy.config.j2 contains the default HAProxy configuration (the same you have when you install HAProxy using apt-get).

Now, in playbook_dir you will probably have this arborescence:

playbook.yml
group_vars/
    haproxy.yml
templates/
    haproxy/
         my-config.j2

The user can now provide his own configuration for HAProxy, by overriding haproxy_templates in group_vars/haproxy.yml for example:

haproxy_templates:
  - src: haproxy/my-config.j2
    dest: 01_my_config

The user can put everything he wants in my-config.j2, use his own configuration variables in the file without polluting the role.

The role stay simple and the user can do everything he wants.

Conclusion

Moving the configuration out of a role is often the right thing to do. Just let the user override the whole role templates, and don’t over conplexify the role itself. Simplicity is the key.

Tags: devops ansible haproxy english
Top of page