Ansible variables: selecting the best location

Faheem

Defining variables to your Ansible playbooks and roles can grow to be difficult as your undertaking grows.

Searching the Ansible documentation, the variety of Ansible variables location is complicated, to say the least:

  1. command line values (for instance, -u my_user, these aren’t variables)
  2. function defaults (outlined in function/defaults/primary.yml)
  3. stock file or script group_vars
  4. stock group_vars/all
  5. playbook group_vars/all
  6. stock group_vars/*
  7. playbook group_vars/*
  8. stock file or script host_vars
  9. stock host_vars/*
  10. playbook host_vars/*
  11. host details / cached set_facts
  12. play vars
  13. play vars_prompt
  14. play vars_files
  15. function vars (outlined in function/vars/primary.yml)
  16. block vars (just for duties in block)
  17. process vars (just for the duty)
  18. include_vars
  19. set_facts / registered vars
  20. function (and include_role) params
  21. embrace params
  22. further vars (for instance, -e "person=my_user")(all the time win priority)

There are 22 totally different locations the place to retailer your variables! As your code evolve and grow to be extra advanced, it will possibly get messy.

Outline your personal subset of variables areas

The easy method

Everytime you consider a variable, it ought to be apparent the place it’s outlined. If not, perhaps you’re spreading your variables in too many locations. Begin with one thing easy, for example having solely 2 locations the place your variables may be outlined:

  1. function defaults (outlined in function/defaults/primary.yml)
  2. function (and include_role) params

roles/serviceA/default.yml: this file defines all variables required by the function, with some default values. Notice how we will remark variables which can be required, however for which we don’t wish to present any default worth. By doing that, we’re documenting each variable the function wants.

servicea_log_dir: /var/log/servicea

servicea_autorestart: sure

serviceA.yml: this file is the playbook during which the function is named. We put our customized configuration there.

- hosts: groupa
  roles:
  - function: serviceA
    vars:
      servicea_user: gollum
      servicea_autorestart: no

We selected 2 areas for our undertaking: function defaults, et function params. It’s straightforward to know the place to search out our variable. It ought to work in most conditions.

A extra generic method

Let’s have one other subset of areas.

  1. function defaults (outlined in function/defaults/primary.yml)
  2. stock group_vars/*

roles/serviceA/default.yml: function defaults, outlined in the identical because the earlier instance.

servicea_log_dir: /var/log/servicea

servicea_autorestart: sure

stock/group_vars/servicea.yml: these variables are going to be related to the group referred to as servicea

servicea_user: gollum
servicea_autorestart: no

It’s then required to affiliate appropriately the function to the hosts the place you’ve gotten outlined the variables (reminder: at runtime, variables are ultimately related to a bunch: there isn’t a teams or function default, solely host variables). The playbook:

- hosts: servicea
  roles:
  - function: serviceA

Now let’s say we wish to have a number of roles, servicea and serviceb, to run on one group referred to as for instance employee. We may write the customized configuration for each providers (servicea and serviceb) in a single file: stock/group_vars/employee.yml; however then it’s actually not apparent the place to search out your customized variables.

As an alternative, we will have 1 group per service, so 1 configuration file per service within the group_vars folder (servicea.yml and serviceb.yml). We then affiliate the employee hosts to the group of our totally different providers. stock/hosts:

[worker]
worker01.native
worker02.native
worker03.native
worker04.native

[servicea:children]
employee

[serviceb:children]
employee

A improper method

Let’s simply take the two earlier examples and blend them. We select 3 areas:

  1. function defaults (outlined in function/defaults/primary.yml)
  2. stock group_vars/*
  3. function (and include_role) params

Let’s say we wish to modify servicea_log_dir variable. We can’t change the function defaults variable, as we wish our personal customized worth. Now do we alter it within the group_vars or within the function params? Each work, and there’s no method to determine which location you’ll select, until there’s a particular logic behind it. This isn’t appropriate and we wish to maintain issues easy.

Assume gitops

When selecting the few areas to make use of, take into consideration what impact it can have in your code versionning.

The gitops methodology might aid you out. Briefly, you wish to break up your code in 2 repositories: your code repository, and your ops repository.

Making use of it to Ansible, your code repository is the place you model your roles or your Ansible collections. Your ops repository is the place you model every thing particular to an occasion of your code; specifically your stock and customized variables.

When utilizing the easy method, you’ll have to model your playbooks in your ops repository, as they include your customized variables. When utilizing the second methodology we described, the place each customized variable is within the stock group vars, you may model solely the stock in your ops repository.

What issues is that it ought to be attainable to separate the generic code and the properties which can be correct to an occasion. For instance, storing customized variables within the vars folder of a job (eg. roles/servicea/vars/primary.yml) shouldn’t be appropriate.

For those who consider any variable and know for certain the place it has been outlined, then you’re probaly doing issues proper.

Leave a Comment