<p>Given the <em>foo</em> defaults</p>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; cat roles/foo/defaults/main.yml 
foo_path: /tmp/test.txt
</code></pre>
<p>There are more options:</p>
<ol>
<li>Include the <em>foo</em> defaults into a dictionary and get the variable <em>foo_path</em></li>
</ol>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; cat pb_bar.yml
- hosts: localhost
  pre_tasks:
    - include_vars:
        file: roles/foo/defaults/main.yml
        name: foo_defaults
    - debug:
        var: foo_defaults.foo_path
      when: debug|d(false)|bool
    - set_fact:
        foo_path: &quot;{{ foo_defaults.foo_path }}&quot;
  roles:
    - bar
</code></pre>
<p>Use the variable in the role <em>bar</em></p>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; cat roles/bar/tasks/main.yml
- stat:
    path: &quot;{{ foo_path }}&quot;
  register: foo_path_st
- debug:
    var: foo_path_st
  when: debug|d(false)|bool
- assert:
    that: foo_path_st.stat.exists
</code></pre>
<p>gives</p>
<sup>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; ansible-playbook pb_bar.yml -e debug=true

PLAY [localhost] *****************************************************************************

TASK [include_vars] **************************************************************************
ok: [localhost]

TASK [debug] *********************************************************************************
ok: [localhost] =&gt; 
  foo_defaults.foo_path: /tmp/test.txt

TASK [set_fact] ******************************************************************************
ok: [localhost]

TASK [Assert foo_path] ***********************************************************************
skipping: [localhost]

TASK [bar : stat] ****************************************************************************
ok: [localhost]

TASK [bar : debug] ***************************************************************************
ok: [localhost] =&gt; 
  foo_path_st:
    ansible_facts:
      discovered_interpreter_python: /usr/bin/python3
    changed: false
    failed: false
    stat:
      ...
      exists: true
      ...
      path: /tmp/test.txt

TASK [bar : assert] **************************************************************************
ok: [localhost] =&gt; changed=false 
  msg: All assertions passed

PLAY RECAP ***********************************************************************************
localhost: ok=6    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
</code></pre>
</sup>
<hr>
<ol start="2">
<li>Structure the roles' tasks</li>
</ol>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; tree roles
roles
├── bar
│   └── tasks
│       └── main.yml
└── foo
    ├── defaults
    │   └── main.yml
    └── tasks
        ├── assert_foo_path.yml
        ├── install_foo_path.yml
        └── main.yml

5 directories, 5 files
</code></pre>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; cat roles/foo/tasks/assert_foo_path.yml 
- stat:
    path: &quot;{{ foo_path }}&quot;
  register: foo_path_st
- debug:
    var: foo_path_st
  when: debug|d(false)|bool
- assert:
    that: foo_path_st.stat.exists

shell&gt; cat roles/foo/tasks/install_foo_path.yml 
- file:
    path: &quot;{{ foo_path }}&quot;
    state: touch

shell&gt; cat roles/foo/tasks/main.yml 
- name: Install foo_path
  include_tasks: install_foo_path.yml
- name: Assert foo_path
  include_tasks: assert_foo_path.yml
</code></pre>
<p>and use the module <a href="https://docs.ansible.com/ansible/latest/collections/ansible/builtin/include_role_module.html#ansible-builtin-include-role-module-load-and-execute-a-role" rel="nofollow noreferrer"><em>include_role</em></a></p>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; cat roles/bar/tasks/main.yml 
- name: Assert foo_path
  include_role:
    name: foo
    tasks_from: assert_foo_path.yml
</code></pre>
<p>Create playbooks for testing</p>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; cat pb_foo.yml 
- hosts: localhost
  roles:
    - foo

shell&gt; cat pb_bar.yml 
- hosts: localhost
  roles:
    - bar
</code></pre>
<p>The play will fail if the file is missing</p>
<sup>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; ansible-playbook pb_bar.yml -e debug=false

PLAY [localhost] *****************************************************************************

TASK [Assert foo_path] ***********************************************************************

TASK [foo : stat] ****************************************************************************
ok: [localhost]

TASK [foo : debug] ***************************************************************************
skipping: [localhost]

TASK [foo : assert] **************************************************************************
fatal: [localhost]: FAILED! =&gt; changed=false 
  assertion: foo_path_st.stat.exists
  evaluated_to: false
  msg: Assertion failed

PLAY RECAP ***********************************************************************************
localhost: ok=1    changed=0    unreachable=0    failed=1    skipped=1    rescued=0    ignored=0
</code></pre>
</sup>
<p>Create the file</p>
<sup>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; ansible-playbook pb_foo.yml -e debug=false

PLAY [localhost] *****************************************************************************

TASK [foo : Install foo_path] ****************************************************************
included: /export/scratch/tmp7/test-321/roles/foo/tasks/install_foo_path.yml for localhost

TASK [foo : file] ****************************************************************************
changed: [localhost]

TASK [foo : Assert foo_path] *****************************************************************
included: /export/scratch/tmp7/test-321/roles/foo/tasks/assert_foo_path.yml for localhost

TASK [foo : stat] ****************************************************************************
ok: [localhost]

TASK [foo : debug] ***************************************************************************
skipping: [localhost]

TASK [foo : assert] **************************************************************************
ok: [localhost] =&gt; changed=false 
  msg: All assertions passed

PLAY RECAP ***********************************************************************************
localhost: ok=5    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
</code></pre>
</sup>
<p>The assert task will succeed now</p>
<pre class="lang-yaml prettyprint-override"><code>TASK [foo : assert] **************************************************************************
ok: [localhost] =&gt; changed=false 
  msg: All assertions passed
</code></pre>

CC BY-SA 4.0
2023-05-04T14:59:29.407Z
The splitting of the tasks is interesting, I hadn't thought of that.  I don't necessarily like #1 because the `foo` role will always need that variable to be defined and that is not apparent when creating the play.  It'd also be cumbersome and redundant to have to do that for every playbook that decides to include that role.
FuriousGeorge
CC BY-SA 4.0
2023-05-04T03:57:57.247Z
2023-05-04T04:25:26.273Z
2023-05-04T04:25:26.273Z
Vladimir Botka
<p>I have a role, <code>foo</code> that installs a file <code>{{ foo_path }}</code> that's defined in <code>roles/defaults/main.yml</code>.</p>
<p>I have a second role, <code>bar</code> that depends on that file being there.   I could put <code>foo</code> in the <code>roles/meta/main.yml</code> <code>dependencies</code> but then it will run the entire role which is not ideal. I could potentially tag the task in the role that creates the file, but that's not really scalable, and introduces problems when I'm not the owner of that role's code.</p>
<p>I could just <code>assert</code> that the file is there, but the problem is that I don't know where &quot;there&quot; is.</p>
<p>How can I load the <code>foo_path</code> var from a different role without the overhead of running the play?</p>

<ansible>
Ansible role depend on other roles
FuriousGeorge
# Ansible role depend on other roles

(Asked by: username_0 on 2023-05-03)

I have a role, `foo` that installs a file `{{ foo_path }}` that's defined in `roles/defaults/main.yml`.

I have a second role, `bar` that depends on that file being there. I could put `foo` in the `roles/meta/main.yml` `dependencies` but then it will run the entire role which is not ideal. I could potentially tag the task in the role that creates the file, but that's not really scalable, and introduces problems when I'm not the owner of that role's code.

I could just `assert` that the file is there, but the problem is that I don't know where "there" is.

How can I load the `foo_path` var from a different role without the overhead of running the play?

**Tags:** ansible


---

## 1 answers

### Answer by username_1 on 2023-05-04. Score: 2

Given the foo defaults
shell> cat roles/foo/defaults/main.yml 
foo_path: /tmp/test.txt

There are more options:

Include the foo defaults into a dictionary and get the variable foo_path

shell> cat pb_bar.yml
- hosts: localhost
  pre_tasks:
    - include_vars:
        file: roles/foo/defaults/main.yml
        name: foo_defaults
    - debug:
        var: foo_defaults.foo_path
      when: debug|d(false)|bool
    - set_fact:
        foo_path: "{{ foo_defaults.foo_path }}"
  roles:
    - bar

Use the variable in the role bar
shell> cat roles/bar/tasks/main.yml
- stat:
    path: "{{ foo_path }}"
  register: foo_path_st
- debug:
    var: foo_path_st
  when: debug|d(false)|bool
- assert:
    that: foo_path_st.stat.exists

gives

shell> ansible-playbook pb_bar.yml -e debug=true

PLAY [localhost] *****************************************************************************

TASK [include_vars] **************************************************************************
ok: [localhost]

TASK [debug] *********************************************************************************
ok: [localhost] => 
  foo_defaults.foo_path: /tmp/test.txt

TASK [set_fact] ******************************************************************************
ok: [localhost]

TASK [Assert foo_path] ***********************************************************************
skipping: [localhost]

TASK [bar : stat] ****************************************************************************
ok: [localhost]

TASK [bar : debug] ***************************************************************************
ok: [localhost] => 
  foo_path_st:
    ansible_facts:
      discovered_interpreter_python: /usr/bin/python3
    changed: false
    failed: false
    stat:
      ...
      exists: true
      ...
      path: /tmp/test.txt

TASK [bar : assert] **************************************************************************
ok: [localhost] => changed=false 
  msg: All assertions passed

PLAY RECAP ***********************************************************************************
localhost: ok=6    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0




Structure the roles' tasks

shell> tree roles
roles
├── bar
│   └── tasks
│       └── main.yml
└── foo
    ├── defaults
    │   └── main.yml
    └── tasks
        ├── assert_foo_path.yml
        ├── install_foo_path.yml
        └── main.yml

5 directories, 5 files

shell> cat roles/foo/tasks/assert_foo_path.yml 
- stat:
    path: "{{ foo_path }}"
  register: foo_path_st
- debug:
    var: foo_path_st
  when: debug|d(false)|bool
- assert:
    that: foo_path_st.stat.exists

shell> cat roles/foo/tasks/install_foo_path.yml 
- file:
    path: "{{ foo_path }}"
    state: touch

shell> cat roles/foo/tasks/main.yml 
- name: Install foo_path
  include_tasks: install_foo_path.yml
- name: Assert foo_path
  include_tasks: assert_foo_path.yml

and use the module include_role
shell> cat roles/bar/tasks/main.yml 
- name: Assert foo_path
  include_role:
    name: foo
    tasks_from: assert_foo_path.yml

Create playbooks for testing
shell> cat pb_foo.yml 
- hosts: localhost
  roles:
    - foo

shell> cat pb_bar.yml 
- hosts: localhost
  roles:
    - bar

The play will fail if the file is missing

shell> ansible-playbook pb_bar.yml -e debug=false

PLAY [localhost] *****************************************************************************

TASK [Assert foo_path] ***********************************************************************

TASK [foo : stat] ****************************************************************************
ok: [localhost]

TASK [foo : debug] ***************************************************************************
skipping: [localhost]

TASK [foo : assert] **************************************************************************
fatal: [localhost]: FAILED! => changed=false 
  assertion: foo_path_st.stat.exists
  evaluated_to: false
  msg: Assertion failed

PLAY RECAP ***********************************************************************************
localhost: ok=1    changed=0    unreachable=0    failed=1    skipped=1    rescued=0    ignored=0


Create the file

shell> ansible-playbook pb_foo.yml -e debug=false

PLAY [localhost] *****************************************************************************

TASK [foo : Install foo_path] ****************************************************************
included: /export/scratch/tmp7/test-321/roles/foo/tasks/install_foo_path.yml for localhost

TASK [foo : file] ****************************************************************************
changed: [localhost]

TASK [foo : Assert foo_path] *****************************************************************
included: /export/scratch/tmp7/test-321/roles/foo/tasks/assert_foo_path.yml for localhost

TASK [foo : stat] ****************************************************************************
ok: [localhost]

TASK [foo : debug] ***************************************************************************
skipping: [localhost]

TASK [foo : assert] **************************************************************************
ok: [localhost] => changed=false 
  msg: All assertions passed

PLAY RECAP ***********************************************************************************
localhost: ok=5    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0


The assert task will succeed now
TASK [foo : assert] **************************************************************************
ok: [localhost] => changed=false 
  msg: All assertions passed

> **Comments:**
> **username_0**: The splitting of the tasks is interesting, I hadn't thought of that.  I don't necessarily like #1 because the `foo` role will always need that variable to be defined and that is not apparent when creating the play.  It'd also be cumbersome and redundant to have to do that for every playbook that decides to include that role.  

---

