ansible.posix
ansible.posix copied to clipboard
Allow bypassing rsync built-in transport check for custom ssh-based transports
SUMMARY
When using synchronize
between the ansible controller and a remote target host, using a custom transport plugin, synchronize
refuses to run, and exits with an error message.
While this is a good default behavior, there are situations where it could be made to work with proper manual configuration (for example, using ssh_connection_multiplexing
or rsync_opts
).
Adding a configuration parameter to the synchronize
module would allow those situations to work.
ISSUE TYPE
- Feature Idea
COMPONENT NAME
ansible.posix.synchronize
ADDITIONAL INFORMATION
The custom transport I'm using is eci, it extends the ssh transport mechanism to handle authentication through EC2 Instance Connect.
I'm therefore still connecting through ssh under the hood, but ansible doesn't know that. And even if it did, the current behavior is the correct default behavior, because authentication through eci uses a temporary ssh key, only valid 60s.
I could however easily make rsync re-use the ssh connection and work as expected.
This would also be useful for any custom transport able to provide a socket between hosts, doing something similar to this workaround (before it was natively supported).
Example configuration
Put all following files in the current working directory :
# inventory
<xx.xx.xx.xx> ansible_connection=eci aws_profile=<your_profile> aws_region=<your_aws_region> ansible_user=ubuntu
# ansible.cfg
[defaults]
connection_plugins=plugins/connection
copy eci.py in plugins/connection/
# playbook.yml
- hosts: all
tasks:
- synchronize:
src: plugins/connection # or any existing directory on the controller
dest: . # or any existing directory on the remote
Run :
$ ansible-playbook -i inventory playbook.yml -vvv
[...]
TASK [ansible.posix.synchronize] ***********************************************************************************************************************************************************************************
task path: /path/to/playbook.yml:3
fatal: [wordpress-production]: FAILED! => {
"changed": false,
"msg": "synchronize uses rsync to function. rsync needs to connect to the remote host via ssh, docker client or a direct filesystem copy. This remote host is being accessed via eci instead so it cannot work."
}
Ansible version with which this test was run :
ansible [core 2.15.0]
python version = 3.10.11 (main, May 29 2023, 00:00:00) [GCC 13.1.1 20230511 (Red Hat 13.1.1-2)]
jinja version = 3.0.3
libyaml = True
Fix suggestions
Long-term fix
In my opinion, a "proper" long-term fix would be something along the lines of :
- Expanding the transport plugin API, so that a transport plugin may provide ansible with the ability to create a bidirectional socket between controller and target hosts
- When encountering an unknown transport plugin,
synchronize
would check if it implements this API, and if so, uses it instead of erroring
This would allow any custom transport to make transparent use of synchronize
(and, I'm assuming, other modules currently suffering from the same limitations).
In the long run, we could even imagine transitioning existing standard transport plugins to this mechanism, removing most of the logic from this module, and relying on the transport plugin to implement it instead.
Short-term fix
Adding a new configuration option in the synchronize
module (for example named bypass_transport_compatibility
, defaulting to false), which would just bypass the check, and use the module just like if the transport used was ssh
; allowing a user to make use of ssh_connection_multiplexing
or rsync_opts
to use synchronize
.
If this option sounds reasonable in terms of design and user interface, I would gladly try to provide a PR implementing it !