Issue 1:
ISSUE TYPE

Bug Report

COMPONENT NAME

core

(with_items and nested environments)

ANSIBLE VERSION

ansible 2.4.1.0
config file = /home/centos/repos/ansible/ansible.cfg
configured module search path = [u'/home/centos/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]

CONFIGURATION

> ansible-config dump --only-changed
ANSIBLE_FORCE_COLOR(/home/centos/repos/ansible/ansible.cfg) = True
RETRY_FILES_ENABLED(/home/centos/repos/ansible/ansible.cfg) = False

OS / ENVIRONMENT

Control + Remote (local playbook):

Centos 7

> uname -sr
Linux 3.10.0-693.5.2.el7.x86_64

SUMMARY

Use of with_items in a command task that runs within a nested set of environments is flattening the nesting and reverting to the top level environment instead of keeping the most nested environment

STEPS TO REPRODUCE

Create the below files in a single directory and then run this command from within that directory:

SHELL_ENV_VAR=shell_env_var SHARED_ENV_VAR=shell_env_var ansible-playbook playbook.yml -i localhost, -c local -v

ansible.cfg

[defaults]
force_color=1
retry_files_enabled=False

playbook.yml

---
- hosts: all
gather_facts: false

tasks:
- debug: msg="This is the playbook level"

- import_tasks: first-level-tasks.yml
environment:
PLAYBOOK_ENV_VAR: "playbook_env_var"
SHARED_ENV_VAR: "playbook_env_var"

first-level-tasks.yml

- debug: msg="This is the first level tasks"

- import_tasks: second-level-tasks.yml
environment:
LVL1_ENV_VAR: "lvl1_env_var"
SHARED_ENV_VAR: "lvl1_env_var"

second-level-tasks.yml

- debug: msg="This is the second level tasks"

- name: Command singular
command: "echo Shell: \"${SHELL_ENV_VAR}\"; Playbook: \"${PLAYBOOK_ENV_VAR}\"; Lvl1: \"${LVL1_ENV_VAR}\"; Shared: \"${SHARED_ENV_VAR}\""

- name: Command with items
command: "echo Shell: \"${SHELL_ENV_VAR}\"; Playbook: \"${PLAYBOOK_ENV_VAR}\"; Lvl1: \"${LVL1_ENV_VAR}\"; Shared: \"${SHARED_ENV_VAR}\""
with_items:
- 1

EXPECTED RESULTS

The command stdout/stdout_lines from both tasks in second-level-tasks.yml (TASK [Command singular] and TASK [Command with items]) should be identical

ACTUAL RESULTS

The addition of with_items: [1] (which should be a non-semantic change to a command that doesn't actually reference the {{ item }}s) causes the output of the task to change. It appears that the nested environment is reverting to the top-level (i.e. playbook level) environment when with_items is used (see playbook output below)

Using /home/centos/repos/ansible/ansible.cfg as config file

PLAY [all] ***************************************************************************************************************************************************

TASK [debug] *************************************************************************************************************************************************
ok: [localhost] => {
"msg": "This is the playbook level"
}

TASK [debug] *************************************************************************************************************************************************
ok: [localhost] => {
"msg": "This is the first level tasks"
}

TASK [debug] *************************************************************************************************************************************************
ok: [localhost] => {
"msg": "This is the second level tasks"
}

TASK [Command singular] **************************************************************************************************************************************
changed: [localhost] => {"changed": true, "cmd": ["echo", "Shell:", "${SHELL_ENV_VAR};", "Playbook:", "${PLAYBOOK_ENV_VAR};", "Lvl1:", "${LVL1_ENV_VAR};", "Shared:", "${SHARED_ENV_VAR}"], "delta": "0:00:00.014676", "end": "2017-11-29 09:02:18.033588", "failed": false, "rc": 0, "start": "2017-11-29 09:02:18.018912", "stderr": "", "stderr_lines": [], "stdout": "Shell: shell_env_var; Playbook: playbook_env_var; Lvl1: lvl1_env_var; Shared: lvl1_env_var", "stdout_lines": ["Shell: shell_env_var; Playbook: playbook_env_var; Lvl1: lvl1_env_var; Shared: lvl1_env_var"]}

TASK [Command with items] ************************************************************************************************************************************
changed: [localhost] => (item=1) => {"changed": true, "cmd": ["echo", "Shell:", "${SHELL_ENV_VAR};", "Playbook:", "${PLAYBOOK_ENV_VAR};", "Lvl1:", "${LVL1_ENV_VAR};", "Shared:", "${SHARED_ENV_VAR}"], "delta": "0:00:00.005918", "end": "2017-11-29 09:02:18.384945", "failed": false, "item": 1, "rc": 0, "start": "2017-11-29 09:02:18.379027", "stderr": "", "stderr_lines": [], "stdout": "Shell: shell_env_var; Playbook: playbook_env_var; Lvl1: lvl1_env_var; Shared: playbook_env_var", "stdout_lines": ["Shell: shell_env_var; Playbook: playbook_env_var; Lvl1: lvl1_env_var; Shared: playbook_env_var"]}

PLAY RECAP ***************************************************************************************************************************************************
localhost : ok=5 changed=2 unreachable=0 failed=0

Issue 2:
For example, the following yaml:

environment:
str: "play level"
tasks:
- name: test 1
command: "/bin/echo $str"
environment:
str: "task level"
- name: test 2
command: "/bin/echo $str"
with_items: [ 1, 2, 3]
environment:
str: "task level"

And execute: ansible-playbook bug.yml -v

Task 'test 1' will have 'task level' in stdout

Task 'test 2' will loop 3 times with 'play level' in stdout

IF environment is not defined on play-level, 'test 2' will use the task-level setting.

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

TASK [test 1] *************************************************************************************************************************************************************
changed: [localhost] => {"changed": true, "cmd": ["/bin/echo", "$str"], "delta": "0:00:00.001448", "end": "2017-11-08 15:36:32.769761", "failed": false, "rc": 0, "start": "2017-11-08 15:36:32.768313", "stderr": "", "stderr_lines": [], "stdout": "task level", "stdout_lines": ["task level"]}

TASK [test 2] *************************************************************************************************************************************************************
changed: [localhost] => (item=1) => {"changed": true, "cmd": ["/bin/echo", "$str"], "delta": "0:00:00.001317", "end": "2017-11-08 15:36:32.971494", "failed": false, "item": 1, "rc": 0, "start": "2017-11-08 15:36:32.970177", "stderr": "", "stderr_lines": [], "stdout": "play level", "stdout_lines": ["play level"]}
changed: [localhost] => (item=2) => {"changed": true, "cmd": ["/bin/echo", "$str"], "delta": "0:00:01.002670", "end": "2017-11-08 15:36:34.150920", "failed": false, "item": 2, "rc": 0, "start": "2017-11-08 15:36:33.148250", "stderr": "", "stderr_lines": [], "stdout": "play level", "stdout_lines": ["play level"]}
changed: [localhost] => (item=3) => {"changed": true, "cmd": ["/bin/echo", "$str"], "delta": "0:00:01.002600", "end": "2017-11-08 15:36:35.349230", "failed": false, "item": 3, "rc": 0, "start": "2017-11-08 15:36:34.346630", "stderr": "", "stderr_lines": [], "stdout": "play level", "stdout_lines": ["play level"]}

PLAY RECAP ****************************************************************************************************************************************************************
localhost : ok=3 changed=2 unreachable=0 failed=0

ISSUE TYPE

Bug Report

ANSIBLE VERSION

ansible 2.4.1.0