Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

include_role overrides variables from previous role #36274

Closed
clvx opened this issue Feb 16, 2018 · 7 comments · Fixed by #69040
Closed

include_role overrides variables from previous role #36274

clvx opened this issue Feb 16, 2018 · 7 comments · Fixed by #69040
Labels
affects_2.6 This issue/PR affects Ansible v2.6 bug This issue/PR relates to a bug. has_pr This issue has an associated PR. include_role module This issue/PR relates to a module. support:core This issue/PR relates to code supported by the Ansible Engineering Team. utilities Utilities category

Comments

@clvx
Copy link

clvx commented Feb 16, 2018

ISSUE TYPE
  • Bug Report
  • Documentation Report
container.yml
$tree                                                   
.                                                       
├── inventory                                           
├── roles                                               
│   ├── dummy1                                          
│   │   ├── defaults                                    
│   │   │   └── main.yml                                
│   │   ├── files                                       
│   │   │   └── foo.conf.j2                             
│   │   └── tasks                                       
│   │       └── main.yml                                
│   └── dummy2                                          
│       ├── files                                       
│       └── tasks                                       
│           └── main.yml                                                              
└── test.yml           

$find . -type f -print -exec cat {} \; | grep -v '.git'
./test.yml
---
- hosts: lab
  roles:
    - roles/dummy1
./roles/dummy2/tasks/main.yml
---

- name: Debuggin variables
  debug:
    msg: "{{ role_dir }}/files/{{ vhost_name }}.conf.j2"

- name: Copying file files/
  template:
    src: "{{ role_dir }}/files/{{ vhost_name }}.conf.j2"
    dest: "{{ role_path }}/files/{{ vhost_name }}.conf"
./roles/dummy1/files/foo.conf.j2
echo {{ bar }}
./roles/dummy1/tasks/main.yml
---

- name: debug role path
  debug:
    msg: "{{ role_location }}"


- name: Calling dummy2
  include_role:
    name: dummy2
    private: True
  vars:
    role_dir: "{{ role_location }}"
    vhost_name: "{{ service_name }}"
./roles/dummy1/defaults/main.yml
---

service_name: foo
bar: "{{ service_name }}"
role_location: "{{ role_path }}"
./inventory
[lab]
127.0.0.1

COMPONENT NAME

lib/ansible/modules/utilties/logic/include_role.py

ANSIBLE VERSION
ansible 2.4.2.0
OS / ENVIRONMENT
$cat /etc/os-release 
NAME="Ubuntu"
VERSION="17.10 (Artful Aardvark)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 17.10"
VERSION_ID="17.10"
VERSION_CODENAME=artful
UBUNTU_CODENAME=artful

SUMMARY

include_role doesn't reads variables from role dummy1 instead of dummy2. In this case role_location is defined in dummy1 but not in dummy2.

STEPS TO REPRODUCE
$ansible-playbook test.yml -i inventory -k
SSH password: 

PLAY [lab] **********************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************
ok: [127.0.0.1]

TASK [roles/dummy1 : debug role path] *******************************************************************************************************************************************************************************************
ok: [127.0.0.1] => {
    "msg": "/tmp/lab/roles/dummy1"
}

TASK [roles/dummy1 : Calling dummy2] ********************************************************************************************************************************************************************************************

TASK [dummy2 : Debuggin variables] **********************************************************************************************************************************************************************************************
ok: [127.0.0.1] => {
    "msg": "/tmp/lab/roles/dummy2/files/foo.conf.j2"
}

TASK [dummy2 : Copying file files/] *********************************************************************************************************************************************************************************************
fatal: [127.0.0.1]: FAILED! => {"changed": false, "msg": "Could not find or access '/tmp/lab/roles/dummy2/files/foo.conf.j2'"}
        to retry, use: --limit @/tmp/lab/test.retry

PLAY RECAP **********************************************************************************************************************************************************************************************************************
127.0.0.1                  : ok=3    changed=0    unreachable=0    failed=1   

EXPECTED RESULTS

Success.

roles/dummy1/files/foo.conf should be deployed with echo foo.

ACTUAL RESULTS
TASK [dummy2 : Copying file files/] *********************************************************************************************************************************************************************************************
fatal: [127.0.0.1]: FAILED! => {"changed": false, "msg": "Could not find or access '/tmp/lab/roles/dummy2/files/foo.conf.j2'"}
@ansibot
Copy link
Contributor

ansibot commented Feb 16, 2018

@clvx Greetings! Thanks for taking the time to open this issue. In order for the community to handle your issue effectively, we need a bit more information.

Here are the items we could not find in your description:

  • ansible version
  • component name

Please set the description of this issue with this template:
https://raw.githubusercontent.com/ansible/ansible/devel/.github/ISSUE_TEMPLATE.md

click here for bot help

@ansibot ansibot added affects_2.6 This issue/PR affects Ansible v2.6 bug_report needs_info This issue requires further information. Please answer any outstanding questions. needs_template This issue/PR has an incomplete description. Please fill in the proposed template correctly. needs_triage Needs a first human triage before being processed. support:core This issue/PR relates to code supported by the Ansible Engineering Team. labels Feb 16, 2018
@alikins
Copy link
Contributor

alikins commented Feb 19, 2018

pinging @bcoca

@alikins
Copy link
Contributor

alikins commented Feb 19, 2018

@clvx Was this working prior to version 2.4.2.0 ?

@alikins alikins removed the needs_triage Needs a first human triage before being processed. label Feb 19, 2018
@clvx
Copy link
Author

clvx commented Feb 19, 2018

@alikins I've only tested it with ansible 2.4.2. I haven't verifeid with older ansible versions.

@ansibot ansibot added bug This issue/PR relates to a bug. and removed bug_report labels Mar 1, 2018
@alikins alikins added include_role and removed needs_info This issue requires further information. Please answer any outstanding questions. needs_template This issue/PR has an incomplete description. Please fill in the proposed template correctly. labels Mar 5, 2018
@ansibot ansibot added the module This issue/PR relates to a module. label Mar 5, 2018
@bcoca bcoca added this to Pending in include and import issues Apr 17, 2018
@sivel sivel moved this from Pending to Verified in include and import issues May 1, 2018
@mmhelm
Copy link

mmhelm commented Feb 11, 2019

I came across the same issue (ansible 2.7.6) ...
Nevertheless there's a workaround. You can use set_fact in order to create a variable in advance that you can pass to the include_role task.

./roles/dummy1/tasks/main.yml
---
- name: workaround
  set_fact:
    role_location: "{{ role_path }}"

- name: debug role path
  debug:
    msg: "{{ role_location }}"

- name: Calling dummy2
  include_role:
    name: dummy2
    private: True
  vars:
    role_dir: "{{ role_location }}"
    vhost_name: "{{ service_name }}"
---

As you already pointed out in your example, defining the variable in the defaults file won't work. You need to use set_fact.

@ansibot ansibot added the utilities Utilities category label Feb 19, 2019
g-chauvel pushed a commit to g-chauvel/zuul-jobs that referenced this issue May 15, 2020
Defaults in one role do not automatically transfer to
roles via include_role, and applying things correctly
can lead to recursion issues:

  ansible/ansible#36274

Just set the default in the job.

Change-Id: Iabefd80c8fc40a61a601b082f265c93af643cd83
@samdoran
Copy link
Contributor

Duplicate of #47606
Possibly fixed by #69040, which would be a breaking change.

@s-hertel
Copy link
Contributor

It looks like this is not a roles variable scoping issue, so #69040 will not fix it. This happens since Ansible uses lazy evaluation for variables and role_path is an internal variable that is always supposed to reflect the current role path. set_fact is a workaround, since it forces variable evaluation. I think this is a duplicate of #10374 and I'm going to close this so we can track it in one place.

include and import issues automation moved this from Verified to Done Jul 20, 2021
@ansible ansible locked and limited conversation to collaborators Aug 17, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.6 This issue/PR affects Ansible v2.6 bug This issue/PR relates to a bug. has_pr This issue has an associated PR. include_role module This issue/PR relates to a module. support:core This issue/PR relates to code supported by the Ansible Engineering Team. utilities Utilities category
Projects
Development

Successfully merging a pull request may close this issue.

6 participants