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

synchronize doesn't parse variables for ansible_user #275

Open
Vanav opened this issue Sep 30, 2021 · 9 comments
Open

synchronize doesn't parse variables for ansible_user #275

Vanav opened this issue Sep 30, 2021 · 9 comments
Labels
bug This issue/PR relates to a bug. needs_info

Comments

@Vanav
Copy link

Vanav commented Sep 30, 2021

SUMMARY

When using variable in ansible_user, and the default value set_remote_user=true, then we got error:

group_vars/all/default.yml

deploy_user: ubuntu
ansible_user: '{{ deploy_user }}'

task.yml

- name: ANSISTRANO | RSYNC DIRECT | Rsync application files directly to remote release path
  synchronize:
    src: "{{ ansistrano_deploy_from }}"
    dest: "{{ ansistrano_release_path.stdout }}"
    set_remote_user: yes
    recursive: yes
    delete: yes
    archive: yes
    compress: yes
    use_ssh_args: "{{ ansistrano_rsync_use_ssh_args | default(omit) }}"
    rsync_opts: "{{ ansistrano_rsync_extra_params | default(omit) }}"
    rsync_path: "{{ ansistrano_rsync_path | default(omit) }}"

Output (added line breaks):

fatal: [dev_host_site]: FAILED! => {"changed": false, "cmd": 
"/usr/bin/rsync --delay-updates -F --compress --delete-after --archive 
--rsh='/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' 
--no-perms --no-g --chmod=ugo=rwX --omit-dir-times --exclude=/infra/vault_pass.txt 
--quiet --out-format='<<CHANGED>>%i %n%L' 
/srv/Projects/site/infra/.. 
{{ deploy_user }}@84.84.84.84:/srv/site-dev/releases/20210930114615Z", 
"msg": "Warning: Permanently added '84.84.84.84' (ECDSA) to the list of known hosts.\r\n
}}@84.84.84.84: Permission denied (publickey).\r\n
rsync: connection unexpectedly closed (0 bytes received so far) [sender]\n
rsync error: unexplained error (code 255) at io.c(235) [sender=3.1.3]\n", "rc": 255}

As you can see, text {{ deploy_user }} inserted as is, even with spaces, and so SSH login }} is used.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

synchronize

ANSIBLE VERSION
ansible [core 2.11.5] 
  config file = /srv/Projects/Examples/ansistrano-deploy/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/pipx/venvs/ansible/lib/python3.9/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /opt/pipx/bin/ansible
  python version = 3.9.5 (default, May 19 2021, 11:32:47) [GCC 9.3.0]
  jinja version = 3.0.1
  libyaml = True
COLLECTION VERSION
Collection    Version
------------- -------
ansible.posix 1.3.0  
CONFIGURATION
ANSIBLE_PIPELINING(/srv/Projects/site/infra/ansible.cfg) = True
DEFAULT_FORKS(/srv/Projects/site/infra/ansible.cfg) = 1
DEFAULT_HOST_LIST(/srv/Projects/site/infra/ansible.cfg) = ['/srv/Projects/site/infra/hosts.yml']
DEFAULT_JINJA2_NATIVE(/srv/Projects/site/infra/ansible.cfg) = True
DEFAULT_MANAGED_STR(/srv/Projects/site/infra/ansible.cfg) = This file is managed by Ansible, changes will be lost. Source: {file}
DEFAULT_VAULT_PASSWORD_FILE(/srv/Projects/site/infra/ansible.cfg) = /srv/Projects/site/infra/vault_pass.txt
DIFF_ALWAYS(/srv/Projects/site/infra/ansible.cfg) = True
INTERPRETER_PYTHON(/srv/Projects/site/infra/ansible.cfg) = auto
OS / ENVIRONMENT

Ubuntu 20.04

@Vanav Vanav changed the title synchronize does't parse variables for ansistrano_rsync_set_remote_user synchronize does't parse variables for ansible_user Oct 1, 2021
@Vanav Vanav changed the title synchronize does't parse variables for ansible_user synchronize doesn't parse variables for ansible_user Oct 1, 2021
@saito-hideki saito-hideki added bug This issue/PR relates to a bug. needs_triage Needs a first human triage before being processed. labels Oct 22, 2021
@briantist
Copy link

briantist commented Oct 23, 2021

I believe that this is because synchronize uses an action plugin, and that's where the variable is retrieved, and it ends up being an instance of this issue:

See also:

So in fact, I don't know that it is possible (or recommended) to solve this within the synchronize action plugin itself.


The way I would recommend fixing this is to have an explicit option in the plugin for setting the user. It can still default to reading the user from ansible_user, but being able to set it as an explicit option offers better control. If it had that option (I will call it remote_user), then you could invoke it this way:

- name: ANSISTRANO | RSYNC DIRECT | Rsync application files directly to remote release path
  synchronize:
    src: "{{ ansistrano_deploy_from }}"
    dest: "{{ ansistrano_release_path.stdout }}"
    set_remote_user: yes
    recursive: yes
    delete: yes
    archive: yes
    compress: yes
    use_ssh_args: "{{ ansistrano_rsync_use_ssh_args | default(omit) }}"
    rsync_opts: "{{ ansistrano_rsync_extra_params | default(omit) }}"
    rsync_path: "{{ ansistrano_rsync_path | default(omit) }}"
    remote_user: '{{ ansible_user }}'

(see last line)

If ansible_user is set to a static value (no Jinja) then this would be redundant, but in the example in the issue report, this will work, because the Jinja templating will be resolved before the value is passed into the action.


To workaround this issue now, with no changes, you can use set_fact:

- name: "Set the value of ansible_user"
  set_fact:
    ansible_user: '{{ ansible_user }}'

- name: ANSISTRANO | RSYNC DIRECT | Rsync application files directly to remote release path
  synchronize:
    src: "{{ ansistrano_deploy_from }}"
    dest: "{{ ansistrano_release_path.stdout }}"
    set_remote_user: yes
    recursive: yes
    delete: yes
    archive: yes
    compress: yes
    use_ssh_args: "{{ ansistrano_rsync_use_ssh_args | default(omit) }}"
    rsync_opts: "{{ ansistrano_rsync_extra_params | default(omit) }}"
    rsync_path: "{{ ansistrano_rsync_path | default(omit) }}"

But this is not desirable in all cases. You will be setting the precedence of that value differently than it was previously, so you may it find it has an unexpected value in other places where you tried to override it without using set_fact.

@saito-hideki saito-hideki added needs_info and removed needs_triage Needs a first human triage before being processed. labels Nov 8, 2021
@saito-hideki
Copy link
Collaborator

@Vanav Thank you for reporting this. Is there any chance to try the workaround that @briantist provided ?

@saito-hideki saito-hideki added needs_triage Needs a first human triage before being processed. and removed needs_triage Needs a first human triage before being processed. labels Nov 8, 2021
@Vanav
Copy link
Author

Vanav commented Nov 8, 2021

For my use case I was able just to remove variable. But this is definitely unexpected behavior. Maybe it is also a security and data loss risk, because ansible_user contents is passed to rsync unquoted and as is:

/usr/bin/rsync /path/ {{ deploy_user }}@84.84.84.84:/path/

@gaige
Copy link

gaige commented Dec 7, 2021

I just ran into this in a playbook where I was setting ansible_user temporarily using vars: in a block: in my script to force synchronization to go to a specific user on the host.

In my case, the workaround by @briantist wouldn't work (as he notes, "not desirable in all cases"). Although the ability to set the remote_user explicitly as he suggests would solve my problem, by removing the need to set the ansible_user at all in that block.

My workaround right now is to set ansible_user to a static value, but that creates a situation where I need to manually set it in a couple of different places, differently from how I use it in any of the rest of the plays.

Here's an example of what I'm doing:

  - name: synchronize as {{bot_user}}
    vars:
      ansible_user: "{{ bot_user }}"
    block:    
      - name: synchronize test files
        synchronize:
          src: ~/MyData
          dest: "{{ bot_home }}/Development/Test/MapData"
          delete: yes
          owner: no
          group: no
          rsync_opts:
            - --prune-empty-dirs
            - --filter=. /tmp/files_to_copy

@danielpanteleit
Copy link

This worked in ansible==4.3.0 (should be ansible.posix version 1.2.0) and stopped working some time after that.

Not sure if this helps, though.

@juanvalino
Copy link
Contributor

+1

@helmecke
Copy link

ansible.posix==1.2.0 is no viable option because #222. Desperatly need a fix. This and #222 force us to stay at ansible==2.10.7.

@helmecke
Copy link

Found it! Thank you @jovial. #344 fixes the issue for me. Testet with ansible==5.5.0.

@yajo
Copy link

yajo commented Jul 12, 2024

This is a nasty bug and it doesn't seem like the issue would be too hard to fix. Could someone take a look at it? I still have to stay with version 1.2.0 until fixed. 🤷🏼‍♂️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue/PR relates to a bug. needs_info
Projects
None yet
Development

No branches or pull requests

8 participants