What’s the difference between defaults and vars in an Ansible role?

Question:

When creating a new Ansible role, the template creates both a vars and a defaults directory with an empty main.yml file. When defining my role, I can place variable definitions in either of these, and they will be available in my tasks.

What’s the difference between putting the definitions into defaults and vars? What should go into defaults, and what should to into vars? Does it make sense to use both for the same data?

I know that there’s a difference in precedence/priority between the two, but I would like to understand what should go where.

Let’s say that my role would create a list of directories on the target system. I would like to provide a list of default directories to be created, but would like to allow the user to override them when using the role.

Here’s what this would look like:

I could place this either into the defaults/main.yml or in the vars/main.yml, from an execution perspective, it wouldn’t make any difference – but where should it go?

Answer:

The Ansible documentation on variable precedence summarizes this nicely:

If multiple variables of the same name are defined in different places, they win in a certain order, which is:

  • extra vars (-e in the command line) always win
  • then comes connection variables defined in inventory (ansible_ssh_user, etc)
  • then comes “most everything else” (command line switches, vars in play, included vars, role vars, etc)
  • then comes the rest of the variables defined in inventory
  • then comes facts discovered about a system
  • then “role defaults”, which are the most “defaulty” and lose in priority to everything.

So suppose you have a “tomcat” role that you use to install Tomcat on a bunch of webhosts, but you need different versions of tomcat on a couple hosts, need it to run as different users in other cases, etc. The defaults/main.yml file might look something like this:

Since those are just default values it means they’ll be used if those variables aren’t defined anywhere else for the host in question. You could override these via extra-vars, via facts in your inventory file, etc. to specify different values for these variables.

Note that the above list is for Ansible 1.x. In Ansible 2.x the list has been expanded on. As always, the Ansible Documentation provides a detailed description of variable precedence for 2.x.

Leave a Reply