import_role - support templating _from_files with --extra-vars (#75269)

* Support templating _from_files with --extra-vars for imported roles

* Add tests for templating the filenames for import_role, import_playbook, and import_tasks

* Add documentation

Co-authored-by: Alicia Cozine <879121+acozine@users.noreply.github.com>
Co-authored-by: Martin Krizek <martin.krizek@gmail.com>
pull/71190/merge
Sloane Hertel 3 years ago committed by GitHub
parent d36116ef1c
commit db3e8f2c1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
minor_changes:
- import_role - Template tasks_from, vars_from, defaults_from, and handlers_from with --extra-vars (https://github.com/ansible/ansible/issues/69097).

@ -33,6 +33,17 @@ You can incorporate multiple playbooks into a main playbook. However, you can on
Importing incorporates playbooks in other playbooks statically. Ansible runs the plays and tasks in each imported playbook in the order they are listed, just as if they had been defined directly in the main playbook.
You can select which playbook you want to import at runtime by defining your imported playbook filename with a variable, then passing the variable with either ``--extra-vars`` or the ``vars`` keyword. For example:
.. code-block:: yaml
- import_playbook: "/path/to/{{ import_from_extra_var }}"
- import_playbook: "{{ import_from_vars }}"
vars:
import_from_vars: /path/to/one_playbook.yml
If you run this playbook with ``ansible-playbook my_playbook -e import_from_extra_var=other_playbook.yml``, Ansible imports both one_playbook.yml and other_playbook.yml.
Re-using files and roles
========================
@ -60,6 +71,8 @@ Including roles, tasks, or variables adds them to a playbook dynamically. Ansibl
The primary advantage of using ``include_*`` statements is looping. When a loop is used with an include, the included tasks or role will be executed once for each item in the loop.
The filenames for included roles, tasks, and vars are templated before inclusion.
You can pass variables into includes. See :ref:`ansible_variable_precedence` for more details on variable inheritance and precedence.
Imports: static re-use
@ -67,6 +80,8 @@ Imports: static re-use
Importing roles, tasks, or playbooks adds them to a playbook statically. Ansible pre-processes imported files and roles before it runs any tasks in a playbook, so imported content is never affected by other tasks within the top-level playbook.
The filenames for imported roles and tasks support templating, but the variables must be available when Ansible is pre-processing the imports. This can be done with the ``vars`` keyword or by using ``--extra-vars``.
You can pass variables to imports. You must pass variables if you want to run an imported file more than once in a playbook. For example:
.. code-block:: yaml

@ -29,6 +29,7 @@ from ansible.playbook.role import Role
from ansible.playbook.role.include import RoleInclude
from ansible.utils.display import Display
from ansible.module_utils.six import string_types
from ansible.template import Templar
__all__ = ['IncludeRole']
@ -79,8 +80,15 @@ class IncludeRole(TaskInclude):
ri = RoleInclude.load(self._role_name, play=myplay, variable_manager=variable_manager, loader=loader, collection_list=self.collections)
ri.vars.update(self.vars)
if variable_manager is not None:
available_variables = variable_manager.get_vars(play=myplay, task=self)
else:
available_variables = {}
templar = Templar(loader=loader, variables=available_variables)
from_files = templar.template(self._from_files)
# build role
actual_role = Role.load(ri, myplay, parent_role=self._parent_role, from_files=self._from_files,
actual_role = Role.load(ri, myplay, parent_role=self._parent_role, from_files=from_files,
from_include=True, validate=self.rolespec_validate)
actual_role._metadata.allow_duplicates = self.allow_duplicates

@ -0,0 +1,47 @@
- name: test templating import_playbook with extra vars
import_playbook: "{{ pb }}"
- name: test templating import_playbook with vars
import_playbook: "{{ test_var }}"
vars:
test_var: validate_templated_playbook.yml
- name: test templating import_tasks
hosts: localhost
gather_facts: no
vars:
play_var: validate_templated_tasks.yml
tasks:
- name: test templating import_tasks with play vars
import_tasks: "{{ play_var }}"
- name: test templating import_tasks with task vars
import_tasks: "{{ task_var }}"
vars:
task_var: validate_templated_tasks.yml
- name: test templating import_tasks with extra vars
import_tasks: "{{ tasks }}"
- name: test templating import_role from_files
hosts: localhost
gather_facts: no
vars:
play_var: templated.yml
tasks:
- name: test templating import_role tasks_from with play vars
import_role:
name: role1
tasks_from: "{{ play_var }}"
- name: test templating import_role tasks_from with task vars
import_role:
name: role1
tasks_from: "{{ task_var }}"
vars:
task_var: templated.yml
- name: test templating import_role tasks_from with extra vars
import_role:
name: role1
tasks_from: "{{ tasks_from }}"

@ -0,0 +1,5 @@
---
- hosts: localhost
gather_facts: no
tasks:
- debug: msg="In imported playbook"

@ -128,3 +128,10 @@ ansible-playbook test_include_loop.yml "$@"
ansible-playbook test_include_loop_fqcn.yml "$@"
ansible-playbook include_role_omit/playbook.yml "$@"
# Test templating import_playbook, import_tasks, and import_role files
ansible-playbook playbook/test_templated_filenames.yml -e "pb=validate_templated_playbook.yml tasks=validate_templated_tasks.yml tasks_from=templated.yml" "$@" | tee out.txt
cat out.txt
test "$(grep out.txt -ce 'In imported playbook')" = 2
test "$(grep out.txt -ce 'In imported tasks')" = 3
test "$(grep out.txt -ce 'In imported role')" = 3

Loading…
Cancel
Save