Issue 1:
Issue Type:

Bug Report

Ansible Version:

1.7.2

Environment:

CentOS 6.4

Summary:

Variable substitution occur only once when delegate_to using with serial.

Steps To Reproduce:

hosts

host1 copy_from=host9
host2 copy_from=host8
host3 copy_from=host7

playbook.yml

---
- hosts: all
serial: 1
tasks:
- debug: msg={{ copy_from }}
delegate_to: "{{ copy_from }}"

Expected Results:

TASK: [debug msg={{ copy_from }}] *********************************************
ok: [host3 -> host7] => {
"msg": "host7"
}

TASK: [debug msg={{ copy_from }}] *********************************************
ok: [host2 -> host8] => {
"msg": "host8"
}

TASK: [debug msg={{ copy_from }}] *********************************************
ok: [host1 -> host9] => {
"msg": "host9"
}

Actual Results:

TASK: [debug msg={{ copy_from }}] *********************************************
ok: [host3 -> host9] => {
"msg": "host9"
}

TASK: [debug msg={{ copy_from }}] *********************************************
ok: [host2 -> host9] => {
"msg": "host8"
}

TASK: [debug msg={{ copy_from }}] *********************************************
ok: [host1 -> host9] => {
"msg": "host7"
}

Workaround:

playbook.yml

---
- hosts: all
serial: 1
tasks:
- debug: msg={{ copy_from }}
delegate_to: "{{ item }}"
with_items:
- "{{ copy_from }}"

Issue 2:
Issue Type:

Bug Report

Ansible Version:

all versions

Environment:

N/A

Summary:

There is a bug in the templating code of delegate_to: in that, it only happens once per runner proces fork, instead of for every host.

Steps To Reproduce:

Test inventory and playbook:

$ for n in `seq 0 20`; do echo host$n >> hosts ; done
$ cat test.yml

---
- hosts: all
gather_facts: false
connection: local
tasks:
- command: sleep 1
delegate_to: '{{ inventory_hostname }}'

Expected Results:

ansible-playbook -i hosts test.yml -f 1 (or whatever value for fork)

TASK: [command sleep 1] *******************************************************

changed: [host1 -> host1]

changed: [host0 -> host0]

changed: [host2 -> host2]

changed: [host4 -> host4]

changed: [host8 -> host8]

changed: [host3 -> host3]

changed: [host6 -> host6]

changed: [host9 -> host9]

changed: [host5 -> host5]

changed: [host14 -> host14]

changed: [host16 -> host16]

changed: [host15 -> host15]

changed: [host10 -> host10]

changed: [host13 -> host13]

changed: [host11 -> host11]

changed: [host18 -> host18]

changed: [host17 -> host17]

changed: [host20 -> host20]

changed: [host19 -> host19]

changed: [host7 -> host7]

changed: [host12 -> host12]

Actual Results:

ansible-playbook -i hosts test.yml -f 1

TASK: [command sleep 1] *******************************************************

changed: [host0 -> host0]

changed: [host1 -> host0]

changed: [host2 -> host0]

changed: [host3 -> host0]

changed: [host4 -> host0]

changed: [host5 -> host0]

changed: [host6 -> host0]

changed: [host7 -> host0]

changed: [host8 -> host0]

...

ansible-playbook -i hosts test.yml -f 2

TASK: [command sleep 1] *******************************************************

changed: [host1 -> host1]

changed: [host0 -> host0]

changed: [host3 -> host0]

changed: [host2 -> host1]

changed: [host5 -> host1]

changed: [host4 -> host0]

changed: [host6 -> host1]

changed: [host7 -> host0]

changed: [host9 -> host0]

...

ansible-playbook -i hosts test.yml -f 3

TASK: [command sleep 1] *******************************************************

changed: [host2 -> host2]

changed: [host1 -> host1]

changed: [host0 -> host0]

changed: [host3 -> host2]

changed: [host4 -> host1]

changed: [host5 -> host0]

changed: [host6 -> host2]

changed: [host7 -> host1]

...

The same effect can also be seen by varying the serial: option in the play.