Repository: ansible/ansible

Issue:
synchronize doesn't substitute variables properly
<!--- Verify first that your issue/request is not already reported in GitHub -->
##### ISSUE TYPE

<!--- Pick one below and delete the rest: -->
- Bug Report
##### ANSIBLE VERSION

<!--- Paste verbatim output from “ansible --version” between quotes below -->

```
ansible 2.1.0.0
  config file = /tmp/ansible.cfg
  configured module search path = Default w/o overrides
```
##### CONFIGURATION

<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

```
[defaults]

hostfile = ./hostfile

remote_tmp = /tmp

forks=10

timeout = 60

[paramiko_connection]

pty=False

[ssh_connection]

scp_if_ssh = True
control_path = %(directory)s/%%h-%%r
```
##### OS / ENVIRONMENT

<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
-->

N/A
##### SUMMARY

<!--- Explain the problem briefly -->
##### STEPS TO REPRODUCE

<!---
For bugs, show exactly how to reproduce the problem.
For new features, show how the feature would be used.
-->

`$cat hostfile`

```
[test]
XXX.compute-1.amazonaws.com
```

`$ cat test.yaml`

```

---
- name: SSH test
  hosts: all
  tasks:
   - local_action: ping
   - synchronize: src=test.yaml dest=/tmp/
```

`$ cat group_vars/all`

```
credentials_base_dir: "{{ user_home }}/.ssh"
ec2_keypair: test
```

`$ cat group_vars/test`

```
aws_credential: test
ansible_ssh_private_key_file: "{{ credentials_base_dir }}/{{ aws_credential }}/{{ ec2_keypair }}.pem"
```

`$ ansible-playbook test.yaml`

<!--- You can also paste gist.github.com links for larger files -->
##### EXPECTED RESULTS

<!--- What did you expect to happen when running the steps above? -->

All tasks will be completed.
##### ACTUAL RESULTS

<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

`synchronize` task fails with unable to resolve `ansible_ssh_private_key_file` variable:

<!--- Paste verbatim command output between quotes below -->

```
PLAY [SSH test] ****************************************************************

TASK [setup] *******************************************************************
ok: [XXX.compute-1.amazonaws.com]

TASK [ping] ********************************************************************
ok: [XXX.compute-1.amazonaws.com -> localhost]

TASK [synchronize] *************************************************************
fatal: [XXX.compute-1.amazonaws.com]: FAILED! => {"changed": false, "cmd": "/opt/local/bin/rsync --delay-updates -F --compress --archive --rsh 'ssh -i {{ credentials_base_dir }}/{{ aws_credential }}/{{ ec2_keypair }}.pem -S none -o StrictHostKeyChecking=no' --out-format='<<CHANGED>>%i %n%L' \"/tmp/test.yaml\" \"root@XXX.compute-1.amazonaws.com:/tmp/\"", "failed": true, "msg": "Warning: Identity file {{ not accessible: No such file or directory.\nssh: Could not resolve hostname credentials_base_dir: nodename nor servname provided, or not known\r\nrsync: connection unexpectedly closed (0 bytes received so far) [sender]\nrsync error: unexplained error (code 255) at io.c(226) [sender=3.1.1]\n", "rc": 255}

NO MORE HOSTS LEFT *************************************************************
    to retry, use: --limit @test.retry

PLAY RECAP *********************************************************************
XXX.compute-1.amazonaws.com : ok=2    changed=0    unreachable=0    failed=1
```



Discussion:
Ok... fix was really easy:

```
--- ansible/plugins/action/synchronize.py.orig  2016-06-17 20:25:19.000000000 +0300
+++ ansible/plugins/action/synchronize.py   2016-06-17 20:42:15.000000000 +0300
@@ -259,13 +259,10 @@
         dest = self._task.args.get('dest', None)
         if not dest_is_local:
             # Private key handling
-            if use_delegate:
-                private_key = task_vars.get('ansible_ssh_private_key_file') or self._play_context.private_key_file
-            else:
-                private_key = task_vars.get('ansible_ssh_private_key_file') or self._play_context.private_key_file
+            private_key = self._play_context.private_key_file

             if private_key is not None:
-                private_key = os.path.expanduser(private_key)
+                private_key = format(os.path.expanduser(private_key))
                 self._task.args['private_key'] = private_key

             # Src and dest rsync "path" handling
```

Please review and commit if appropriate.


Resolving patch:
diff --git a/lib/ansible/plugins/action/synchronize.py b/lib/ansible/plugins/action/synchronize.py
--- a/lib/ansible/plugins/action/synchronize.py
+++ b/lib/ansible/plugins/action/synchronize.py
@@ -272,10 +272,7 @@ def run(self, tmp=None, task_vars=None):
 
         if not dest_is_local:
             # Private key handling
-            if use_delegate:
-                private_key = task_vars.get('ansible_ssh_private_key_file') or self._play_context.private_key_file
-            else:
-                private_key = task_vars.get('ansible_ssh_private_key_file') or self._play_context.private_key_file
+            private_key = self._play_context.private_key_file
 
             if private_key is not None:
                 private_key = os.path.expanduser(private_key)


Test patch: