Skip to content

Commit

Permalink
Document the possibility of vars/main and defaults/main being directo…
Browse files Browse the repository at this point in the history
…ries (#1320)

* feat: document the possibility of vars/main and defaults/main being directories

* fix: add backslashes before "*" symbols to override their special meaning

* fix: implement review feedback

* fix: change documented possible main file extensions

* fix: update feature to accommodate for recently merged documentation of custom main files

* fix: move defaults/vars main directories explanation

* fix: grammar and style changes

* fix: replace "lexicographical" with "alphabetical"

* fix: clarify the possibility of specifying custom file name

* fix: replace spelling out options with ref to an explanation

* fix: fix typo

---------

Co-authored-by: Radim Valach <radim.valach@favorlogic.com>
  • Loading branch information
radvalach and Radim Valach authored May 9, 2024
1 parent ba39855 commit 34bf3a4
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 11 deletions.
2 changes: 1 addition & 1 deletion docs/docsite/rst/playbook_guide/playbooks_filters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ You can provide default values for variables directly in your templates using th

{{ some_variable | default(5) }}

In the above example, if the variable 'some_variable' is not defined, Ansible uses the default value 5, rather than raising an "undefined variable" error and failing. If you are working within a role, you can also add a ``defaults/main.yml`` to define the default values for variables in your role.
In the above example, if the variable 'some_variable' is not defined, Ansible uses the default value 5, rather than raising an "undefined variable" error and failing. If you are working within a role, you can also add role defaults to define the default values for variables in your role. To learn more about role defaults see :ref:`Role directory structure <role_directory_structure>`.

Beginning in version 2.8, attempting to access an attribute of an Undefined value in Jinja will return another Undefined value, rather than throwing an error immediately. This means that you can now simply use
a default with a value in a nested data structure (in other words, :code:`{{ foo.bar.baz | default('DEFAULT') }}`) when you do not know if the intermediate values are defined.
Expand Down
36 changes: 29 additions & 7 deletions docs/docsite/rst/playbook_guide/playbooks_reuse_roles.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Roles let you automatically load related vars, files, tasks, handlers, and other
.. contents::
:local:

.. _role_directory_structure:

Role directory structure
========================

Expand Down Expand Up @@ -77,6 +79,20 @@ Or call those tasks directly when loading the role, which bypasses the ``main.ym
when: ansible_facts['os_family'] == 'Debian'
Directories ``defaults`` and ``vars`` may also include *nested directories*. If your variables file is a directory, Ansible reads all variables files and directories inside in alphabetical order. If a nested directory contains variables files as well as directories, Ansible reads the directories first. Below is an example of a ``vars/main`` directory:

.. code-block:: text
roles/
common/ # this hierarchy represents a "role"
vars/
main/ # <-- variables associated with this role
first_nested_directory/
first_variables_file.yml
second_nested_directory/
second_variables_file.yml
third_variables_file.yml
.. _role_search_path:

Storing and finding roles
Expand Down Expand Up @@ -125,15 +141,21 @@ The classic (original) way to use roles is with the ``roles`` option for a given
- common
- webservers
When you use the ``roles`` option at the play level, for each role 'x':
When you use the ``roles`` option at the play level, each role 'x' looks for a ``main.yml`` (also ``main.yaml`` and ``main``) in the following directories:

- If roles/x/tasks/main.yml exists, Ansible adds the tasks in that file to the play.
- If roles/x/handlers/main.yml exists, Ansible adds the handlers in that file to the play.
- If roles/x/vars/main.yml exists, Ansible adds the variables in that file to the play.
- If roles/x/defaults/main.yml exists, Ansible adds the variables in that file to the play.
- If roles/x/meta/main.yml exists, Ansible adds any role dependencies in that file to the list of roles.
- ``roles/x/tasks/``
- ``roles/x/handlers/``
- ``roles/x/vars/``
- ``roles/x/defaults/``
- ``roles/x/meta/``
- Any copy, script, template or include tasks (in the role) can reference files in roles/x/{files,templates,tasks}/ (dir depends on task) without having to path them relatively or absolutely.

.. note::
``vars`` and ``defaults`` can also match to a directory of the same name and Ansible will process all the files contained in that directory. See :ref:`Role directory structure <role_directory_structure>` for more details.

.. note::
If you use ``include_role/import_role``, you can specify a custom file name instead of ``main``. The ``meta`` directory is an exception because it does not allow for customization.

When you use the ``roles`` option at the play level, Ansible treats the roles as static imports and processes them during playbook parsing. Ansible executes each play in this order:

- Any ``pre_tasks`` defined in the play.
Expand Down Expand Up @@ -365,7 +387,7 @@ role ``meta/argument_specs.yml`` file. All fields are lowercase.

* If ``required`` is ``false``/missing, ``default`` may be specified (assumed ``null`` if missing).
* Ensure that the default value in the docs matches the default value in the code. The actual
default for the role variable will always come from ``defaults/main.yml``.
default for the role variable will always come from the role defaults (as defined in :ref:`Role directory structure <role_directory_structure>`).
* The default field must not be listed as part of the description unless it requires additional information or conditions.
* If the option is a boolean value, you should use ``true``/``false`` if you want to be compatible with ``ansible-lint``.

Expand Down
6 changes: 3 additions & 3 deletions docs/docsite/rst/playbook_guide/playbooks_variables.rst
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ Understanding variable precedence
Ansible does apply variable precedence, and you might have a use for it. Here is the order of precedence from least to greatest (the last listed variables override all other variables):

#. command line values (for example, ``-u my_user``, these are not variables)
#. role defaults (defined in role/defaults/main.yml) [1]_
#. role defaults (as defined in :ref:`Role directory structure <role_directory_structure>`) [1]_
#. inventory file or script group vars [2]_
#. inventory group_vars/all [3]_
#. playbook group_vars/all [3]_
Expand All @@ -437,7 +437,7 @@ Ansible does apply variable precedence, and you might have a use for it. Here is
#. play vars
#. play vars_prompt
#. play vars_files
#. role vars (defined in role/vars/main.yml)
#. role vars (as defined in :ref:`Role directory structure <role_directory_structure>`)
#. block vars (only for tasks in block)
#. task vars (only for the task)
#. include_vars
Expand Down Expand Up @@ -555,7 +555,7 @@ When you read this playbook it is clear that you have chosen to set a variable o
vars:
myname: John

Variables set in one role are available to later roles. You can set variables in a ``roles/common_settings/vars/main.yml`` file and use them in other roles and elsewhere in your playbook:
Variables set in one role are available to later roles. You can set variables in the role's ``vars`` directory (as defined in :ref:`Role directory structure <role_directory_structure>`) and use them in other roles and elsewhere in your playbook:

.. code-block:: yaml

Expand Down

0 comments on commit 34bf3a4

Please sign in to comment.