Ansible Directory Structure Explained: Defaults vs Vars (Best Practices & Examples)

Distinguishing between defaults and variables is an important design decision when developing an Ansible role. Defaults serve as your public interface, providing suitable values ​​that users can modify according to their needs. Variables, on the other hand, represent your internal framework, containing constants that must remain constant for the role to function effectively.  Striking the right balance not only makes your role user-friendly, but also ensures that it’s flexible and clearly states what can be customized. A key point is this: use default values ​​for values ​​that users can change, and reserve variables for the role’s internal needs.

$ tree -d
.
├── defaults
├── files
├── handlers
├── media
├── meta
├── molecule
│   └── default
│       └── tests
├── tasks
└── templates

10 directories

We can read online about the significance of these directories but often there is some confusion around two of them that always bugs me, which are vars and defaults. Whenever I write a role I often think of whether to put my variables in defaults or the vars

[ Also Read: How to Activate Virtual Environment in Python VS Code ]

  • Defaults vs Vars in Ansible: What’s the Difference?

    According to official Ansible documentation:

    • defaults → contain default variables for the role

    • vars → contain other role-specific variables

    Key Difference: Variable Precedence

    Variables in vars have higher precedence than variables in defaults.

    Example:
    If a variable version appears in both directories:

    • defaults: version: 5.0.1

    • vars: version: 7.1.3

    The final value used by Ansible will be 7.1.3 (from vars).

Due to my limited understanding of this, I used to define all variables in defaults and whenever needed to override them, I declared those variables in vars.

But There’s More: Static vs Dynamic Variables

Understanding precedence is only part of the story. Through practical usage, we also categorize variables by their nature:

1. Static Variables (Constant Values)

Use defaults/ for:

  • Values that rarely change

  • Role-wide constants

  • Base URLs, paths, or fixed configurations

2. Dynamic Variables (Frequently Changing)

Use vars/ for:

  • Values likely to be customized per environment

  • Versions

  • Instance sizes

  • User-driven inputs

Practical Example: Tomcat Download URL

Suppose the Tomcat download URL is:

“https://archive.apache.org/dist/tomcat/tomcat-version/”

Breakdown:

  • Static part"https://archive.apache.org/dist/tomcat/tomcat-"

  • Dynamic part"version"

Here, we can make a variable for the fixed value in the defaults with any name suppose “tomcat_base_url” and varying value should be declared in vars, let it be with any name suppose “tomcat-version”.

So, whenever I have to use the tomcat download url in the role it will be: “{{ tomcat_base_url }}/{{ tomcat-version }}”.

defaults: contain variables which user have to not alter.

vars: contain variables that require input by user.

Best Practice Summary

Directory Purpose Best Use Case
defaults/ Low-priority static variables Constants, base URLs, default configurations
vars/ High-priority dynamic variables Versions, environment-specific inputs

A simple rule to follow:

  • defaults = values users should NOT frequently change
  • vars = values users will likely override

This structure keeps your Ansible roles maintainable, predictable, and easy for others to customize.

Conclusion

Understanding when to use defaults vs vars in Ansible roles is crucial for clean, scalable configuration management. Using static variables in defaults and dynamic variables in vars ensures consistency and makes roles easier for end users to customize.

If you feel I missed any important points or have more questions about variable precedence or Ansible best practices—drop a comment. Happy Automating!

Source: https://docs.ansible.com/projects/ansible/latest/getting_started/index.html

Related Searches – Cloud Engineering ServicesData Engineering ServicesGenerative AI Solutions