ansible-collections / ansible.posix

Ansible Collection for Posix
Other
159 stars 153 forks source link

Module synchronize: ansible_host in host vars pointing to a variable is treated as literal #325

Open kimu opened 2 years ago

kimu commented 2 years ago
SUMMARY

Module ansible.posix.synchronize. The parameter ansible_host in a file contained in host_vars pointing to another variable is treated as string literal.

In my case the variable is in a vault protected file, but I guess the same goes for any other location.

hosts.ini

[prox01_host]
proxmox-01.mydomain.com

host_vars/proxmox-01.mydomain.com.yml

ansible_host: "{{ vault_hosts.proxmox_01.host }}"
ansible_ssh_private_key_file: "{{ vault_hosts.proxmox_01.ssh_key }}"
ansible_ssh_user: "{{ vault_hosts.proxmox_01.user }}"

ansible_ssh_private_key_file and ansible_ssh_user are correctly resolved, the value in ansible_host is treated as a literal.

With this task

- name: Download test-folder
  ansible.posix.synchronize:
    mode: pull
    src: /root/test-folder
    dest: ./tmp

I get this error

fatal: [proxmox-01.mydomain.com]: FAILED! => {"changed": false, "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh='/usr/bin/ssh -S none -i /home/user/.ssh/proxmox01_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' --out-format='<< CHANGED>>%i %n%L' root@{{ vault_hosts.proxmox_01.host }}:/root/test-folder /home/user/workspace/project/tmp", "msg": "Unexpected remote arg: }}:/root/test-folder\nrsync error: syntax or usage error (code 1) at main.c(1372) [sender=3.1.3]\n", "rc": 1}

where you can see that {{ vault_hosts.proxmox_01.host }} is treated as a string literal instead of being resolved when host_vars/proxmox0-1.mydomain.com.yml is parsed.

ansible_ssh_private_key_file is correctly resolved to /home/user/.ssh/proxmox01_key ansible_ssh_user is correctly resolved to root as in root@{{ vault_hosts.proxmox_01.host }} ansible_host is not resolved and the value is treated as a string literal {{ vault_hosts.proxmox_01.host }}

The error is Unexpected remote arg: }}:/root/test-folder

If the value in host_vars/proxmox-01.mydomain.com.yml for ansible_host is changed to an IP address

ansible_host: 172.150.60.60
ansible_ssh_private_key_file: "{{ vault_hosts.proxmox_01.ssh_key }}"
ansible_ssh_user: "{{ vault_hosts.proxmox_01.user }}"

the command is successfully executed.

The original configuration works for any another module I have used so far. This problem seems to be affecting only ansible.posix.synchronize.

ISSUE TYPE
COMPONENT NAME

ansible.proxy.synchronize

ANSIBLE VERSION
ansible [core 2.12.1]
  config file = /home/user/workspace/project/ansible.cfg
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/linuxbrew/.linuxbrew/Cellar/ansible/5.1.0/libexec/lib/python3.10/site-packages/ansible
  ansible collection location = /home/user/workspace/project/.ansible/collections
  executable location = /home/linuxbrew/.linuxbrew/bin/ansible
  python version = 3.10.1 (main, Dec  6 2021, 18:38:26) [GCC 5.4.0 20160609]
  jinja version = 3.0.3
  libyaml = True
COLLECTION VERSION
# /home/user/workspace/project/.ansible/collections/ansible_collections
Collection    Version
------------- -------
ansible.posix 1.3.0

# /home/linuxbrew/.linuxbrew/Cellar/ansible/5.1.0/libexec/lib/python3.10/site-packages/ansible_collections
Collection    Version
------------- -------
ansible.posix 1.3.0
CONFIGURATION
COLLECTIONS_PATHS(/home/user/workspace/project/ansible.cfg) = ['/home/user/workspace/project/.ansible/collections']
DEFAULT_HOST_LIST(/home/user/workspace/project/ansible.cfg) = ['/home/user/workspace/project/hosts.ini']
DEFAULT_VAULT_PASSWORD_FILE(/home/user/workspace/project/ansible.cfg) = /home/user/workspace/project/vault_password.txt
OS / ENVIRONMENT

Windows 11. WSL2 with Ubuntu 20.04 LTS.

STEPS TO REPRODUCE

See above.

EXPECTED RESULTS

ansible_host value should be correctly parsed as for any other value in a host_vars files instead of being treated as a string literal.

ACTUAL RESULTS

ansible_host value in a host_vars file is treated as a string literal making the rsync command failing.

saito-hideki commented 2 years ago

@kimu thank you for reporting this issue. If it is possible, can you test what happens if you pass the value of ansible_host as extra_vars like below?

I'm thinking that it possibly be regarding the following variable precedence:

kimu commented 2 years ago

Hi @saito-hideki.

Passing the values as extra_vars works. However, I am not sure what this is demonstrating.

The vars I am using are at level 14. play vars_files

The vault file is included in the playbook

vars_files:
    - vars/vault.yml

Host vars are 9. inventory host_vars so they come later in the precedence order.

Vault vars have already been parsed at this stage and the ansible_host value in host_vars/server10.yml should just be correctly replaced.

As you can read in the description of this issue, this is actually the case for all other vars from the same source

ansible_host: "{{ vault_hosts.proxmox_01.host }}" <-- NOT correctly replaced
ansible_ssh_private_key_file: "{{ vault_hosts.proxmox_01.ssh_key }}" <-- correctly replaced
ansible_ssh_user: "{{ vault_hosts.proxmox_01.user }}" <-- correctly replaced
ansible_python_interpreter: /usr/bin/python3

All vault_hosts... vars comes from the same source vars/vault.yml, if it was a case of precedence order also the other two ansible_ssh_private_key_file and ansible_ssh_user should be affected, but this is happening only for ansible_host.

May be that ansible_host receives a special treatment in the synchronize module or some of the dependencies? Moreover, this issue happens only with the synchronize module, any other Ansible module I use just play fine with this setup. The same host inventory, vault file and host_vars files are used across all the roles in this project. This problem presents itself only in one role which uses ansible.posix.synchronize, when the rsync command is build.

saito-hideki commented 2 years ago

@kimu ahh, thank you for the clarification :) yeah like you pointed out, ansible_host, ansible_port, and ansible_user(not ansible_ssh_user) parameters are special handling in synchronize plugin.

Vanav commented 2 years ago

Related: #275, #344.