ansiblersync

Using ansible synchronize to a directory of a different name


I am trying to use ansible.posix.synchronize to populate a remote directory tree from a local copy. The trouble I’m having is that I need the destination directory to be a different name from the source, and I don’t want the source name appearing as a subdirectory in the target.

I need this in a few places, but one particularly pernicious example is writing files into the remote user’s home directory, for example the task:

- name: Add dot files
  ansible.posix.synchronize:
    src: files/legacy/.
    dest: "{{ ansible_env['HOME'] }}/."
    owner: false
    group: false

…creates a legacy directory in the user home directory, containing the files I need to be at the root of the directory.

Since ansible.posix.synchronize is a wrapper around rsync I was hoping to use the /. suffix to synchronize the two directories without creating a subdirectory. Unfortunately, ansible “helpfully” normalizes the value of the src param (though not the dest param), and rsync doesn’t receive the argument with the trailing /..

I either need some way to prevent that normalization from happening (only for this single task), or I need some way to mutate the file names as they pass through? I feel like I must be missing something obvious, but I’ve looked at the documentation for ansible.posix.synchronize and it seems to be a straight wrapper around rsync. Poking into the module source code didn’t show anything obvious, either.


Solution

  • It doesn't seem to have anything to do with Ansible.

    From man rsync:

    A trailing slash on the source changes this behavior to avoid creating an additional directory level at the destination. You can think of a trailing / on a source as meaning "copy the contents of this directory" as opposed to "copy the directory by name", but in both cases the attributes of the containing directory are transferred to the containing directory on the destination. In other words, each of the following commands copies the files in the same way, including their setting of the attributes of /dest/foo:

    rsync -av /src/foo /dest
    rsync -av /src/foo/ /dest/foo
    

    So it works as expected without the trailing dot:

    - name: Add dot files
      ansible.posix.synchronize:
        src: files/legacy/
        dest: "{{ ansible_env['HOME'] }}/."
        owner: false
        group: false
    

    If it doesn't help, you can try to use rsync_opts or play with link_dest.