# Variables from not-activated roles get set

**URL:** <https://forum.ansible.com/t/variables-from-not-activated-roles-get-set/45732>\
**Category:** Get Help\
**Tags:** variables\
**Created:** [April 24, 2026, 12:38am UTC](https://forum.ansible.com/t/variables-from-not-activated-roles-get-set/45732 "2026-04-24T00:38:49Z")\
**Posts on this page:** 8\
**Page:** 3

<div class="post-metadata">

**Author:** ![shertel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/shertel/32/1241_2.png) [@shertel](https://forum.ansible.com/u/shertel)\
**Post date:** [April 27, 2026, 7:22pm UTC](https://forum.ansible.com/t/variables-from-not-activated-roles-get-set/45732/41 "2026-04-27T19:22:29Z")

</div>

`roles` and `dependencies` are realy limited. If you upgrade those to use `import_role`, then you could work around the fact that imports themselves are not skippable by using the `defaults_from` option.

```yaml
roles:
  - common-pcengine
tasks:
   - import_role:
       name: dhcpd
       tasks_from: "{{ conditional }}"
       defaults_from: "{{ conditional }}"
     vars:
       # This assumes an empty.yml file exists in tasks/ and defaults/
       conditional: "{{ migrated_to_kea_dhcpd | default(false) | ternary('empty', 'main') }}"
     # Task keywords like 'when' ONLY apply to the tasks within the import.
     # By using the *_from arguments, you can make tasks, defaults, vars, and handlers conditional.
     # when: not (migrated_to_kea_dhcpd | default(false))

```

---

<div class="post-metadata">

**Author:** ![mirabilos](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/mirabilos/32/9721_2.png) [@mirabilos](https://forum.ansible.com/u/mirabilos)\
**Post date:** [April 28, 2026, 2:02pm UTC](https://forum.ansible.com/t/variables-from-not-activated-roles-get-set/45732/42 "2026-04-28T14:02:02Z")

</div>

> [@shertel](#):
>
> `roles` and `dependencies` are realy limited. If you upgrade those to use `import_role`, then you could work around the fact that imports themselves are not skippable by using the `defaults_from` option.

Interesting… but it would need to be `roles` and `dependencies` that have these option, as `import_role` tasks run too late.

---

<div class="post-metadata">

**Author:** ![shertel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/shertel/32/1241_2.png) [@shertel](https://forum.ansible.com/u/shertel)\
**Post date:** [April 28, 2026, 2:09pm UTC](https://forum.ansible.com/t/variables-from-not-activated-roles-get-set/45732/43 "2026-04-28T14:09:44Z")

</div>

In the example given, `common-pcengine` does have access to the defaults from `dhcpd` when it runs. It doesn’t run ‘too late’.

But, keep in mind the dependencies of `dhcpd` would run regardless, so for that to work as expected, dependencies of `dhcpd` would need to be replaced with `import_role` tasks too.

I know this isn’t a good or convenient solution for you, but it’s the only way to skip imports, so I thought I’d mention it. The legacy style imports (`roles` and `dependencies`) have no way to do this.

---

<div class="post-metadata">

**Author:** ![bcoca](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/bcoca/32/9269_2.png) [@bcoca](https://forum.ansible.com/u/bcoca)\
**Post date:** [April 28, 2026, 2:10pm UTC](https://forum.ansible.com/t/variables-from-not-activated-roles-get-set/45732/44 "2026-04-28T14:10:12Z")

</div>

`import_role` can run BEFORE `roles`, not sure how that is too late

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [April 28, 2026, 2:16pm UTC](https://forum.ansible.com/t/variables-from-not-activated-roles-get-set/45732/45 "2026-04-28T14:16:41Z")

</div>

I’m still missing one thing: What is it the playbook knows (upon which it bases the decision of whether to import or include a role) that the common role doesn’t know?

---

<div class="post-metadata">

**Author:** ![mirabilos](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/mirabilos/32/9721_2.png) [@mirabilos](https://forum.ansible.com/u/mirabilos)\
**Post date:** [April 28, 2026, 2:48pm UTC](https://forum.ansible.com/t/variables-from-not-activated-roles-get-set/45732/46 "2026-04-28T14:48:38Z")

</div>

> [@utoddl](#):
>
> What is it the playbook knows (upon which it bases the decision of whether to import or include a role) that the common role doesn’t know?

There are many playbooks, roles and hosts.

For some, the playbook just lists the dhcpd4 role. (Or not.)

For some, the playbook just lists the install\_server role, which used to depend on the dhcpd role, but has been changed to depend on the dhcpd4 role instead, without having to touch the common role.

For some, they are a group of almost identically set-up machines, there’s a group playbook, and experimentation with moving to KEA has started, so they include the dhcpd role by default, except if a hostvar is set, then they include the dhcpd4 role instead.

The common role doesn’t know about dhcpd{,4}. Its job is, however, to set up the APT repos. (It can also install packages collected from roles that run later, via `"{{ [] + lookup('community.general.merge_variables', 'common_basepkgs_', initial_value=[], pattern_type='prefix') + common_extra_packages }}"` in the `ansible.builtin.apt` `name` argument, so that the later roles do not have to invoke APT once again, as a speedup.) The dhcpd{,4} roles require the APT repos to be set up. (For now, due to this situation, they install their respective DHCP dæmon in their own tasks.)

---

<div class="post-metadata">

**Author:** ![mirabilos](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/mirabilos/32/9721_2.png) [@mirabilos](https://forum.ansible.com/u/mirabilos)\
**Post date:** [April 28, 2026, 2:54pm UTC](https://forum.ansible.com/t/variables-from-not-activated-roles-get-set/45732/47 "2026-04-28T14:54:07Z")

</div>

> [@shertel](#):
>
> In the example given, `common-pcengine` does have access to the defaults from `dhcpd` when it runs. It doesn’t run ‘too late’.

Ooh, if I formulate _both_ like that, it does indeed work.

Runs (only the relevant parts):

```auto
tg@tgb1:/tmp/mwe $ ansible-playbook testplay.yml                                                                
TASK [common : variable in common role] *************************************************************************
ok: [localhost] => {
    "msg": "variable foo=False"
}

tg@tgb1:/tmp/mwe $ ansible-playbook testplay.yml -e migrated_to_kea_dhcpd=true                                  
TASK [common : variable in common role] *************************************************************************
ok: [localhost] => {
    "msg": "variable foo=True"
}
 
TASK [extra : hi from role extra] *******************************************************************************
ok: [localhost] => {
    "msg": "hi"
}

```

Changed MWE for that:

```auto
tg@tgb1:/tmp/mwe $ find . -type f -print0 | sort -z | while IFS= read -rd '' x; do printf '\n‣ %s\n' "$x"; cat "$x"; done                    
 
‣ ./roles/common/tasks/main.yml
---
- name: variable in common role
  debug:
    msg: variable foo={{ foo | default(false) }}
 
‣ ./roles/extra/defaults/empty.yml
---
 
‣ ./roles/extra/defaults/main.yml
---
foo: true
 
‣ ./roles/extra/tasks/empty.yml
---
 
‣ ./roles/extra/tasks/main.yml
---
- name: hi from role extra
  debug: msg=hi
 
‣ ./testplay.yml
- hosts: localhost
  become: false
  gather_facts: false
  tasks:
  - import_role:
      name: common
  - import_role:
      name: extra
      tasks_from: "{{ conditional }}"
      defaults_from: "{{ conditional }}"
    vars:
      conditional: "{{ migrated_to_kea_dhcpd | default(false) | bool | ternary('main', 'empty') }}"

```

> [@shertel](#):
>
> But, keep in mind the dependencies of `dhcpd` would run regardless, so for that to work as expected, dependencies of `dhcpd` would need to be replaced with `import_role` tasks too.

Yeah, I’ll keep this possible solution in mind, but I’ve already submitted the way where we just accept the repo is present on more hosts than strictly necessary last week.

Thanks!

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [May 28, 2026, 2:54pm UTC](https://forum.ansible.com/t/variables-from-not-activated-roles-get-set/45732/48 "2026-05-28T14:54:15Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.

[Previous page](https://forum.ansible.com/t/variables-from-not-activated-roles-get-set/45732.md?page=2)
