How to Use the Ansible Copy Module to Copy or Move Files Only on the Remote Host

Set remote_src: yes in your Ansible copy module task to copy or move files that already exist on the target host without transferring data from the controller.

The Ansible copy module is fundamentally designed to transfer files from the control node to managed hosts, but it also supports remote-only operations through a specific parameter flag. When you need to reorganize files directly on the target server or perform atomic moves without network overhead, understanding the remote_src implementation in the ansible/ansible repository is essential. This guide examines the source code in lib/ansible/modules/copy.py and provides production-ready examples for executing remote-only file operations.

How the remote_src Parameter Changes Module Behavior

By default, the copy module reads the source file on the Ansible controller and transfers it to the managed node. When you set remote_src: yes, the module treats the src path as a location already present on the remote host, eliminating network transfer entirely.

In lib/ansible/modules/copy.py, the argument specification declares remote_src as a boolean parameter defaulting to false at line 477. When this flag is enabled, the execution logic branches around line 532 to skip the upload phase, operating directly against the remote filesystem using standard Python file operations.

Copying Files Between Locations on the Same Remote Host

To duplicate a file that already exists on the managed node, use remote_src: yes with standard src and dest paths. This approach respects Ansible's idempotency while avoiding controller-to-target data transfer.

- name: Backup a remote configuration file
  ansible.builtin.copy:
    src: /etc/app/config.yaml
    dest: /etc/app/config.yaml.bak
    remote_src: yes
    mode: '0644'

Performing Atomic Move Operations

For renaming or moving files atomically on the remote host, combine remote_src: yes with state: link and force: yes. According to the source code in lib/ansible/modules/copy.py, this configuration triggers module.atomic_move() at line 637, performing an atomic rename operation that replaces the target if it exists.

The implementation passes keep_dest_attrs=not remote_src to the atomic move function, ensuring that original file attributes are preserved when operating in remote-source mode.

- name: Atomically promote a staged release directory
  ansible.builtin.copy:
    src: /var/www/staging
    dest: /var/www/production
    remote_src: yes
    state: link
    force: yes
    mode: preserve

Understanding the Action Plugin Architecture

While lib/ansible/modules/copy.py handles argument parsing and remote execution, the lib/ansible/plugins/action/copy.py action plugin manages controller-side logic such as checksum calculation and synchronization decisions. Together, these files determine whether to upload content or execute a remote-only operation based on the remote_src flag.

Summary

  • Set remote_src: yes to copy files that already exist on the remote host without network transfer from the controller.
  • The parameter is defined as a boolean defaulting to false in lib/ansible/modules/copy.py at line 477.
  • When enabled, the module skips the upload step at line 532 and works directly with the remote filesystem.
  • For atomic moves, combine remote_src: yes with state: link and force: yes to trigger module.atomic_move() at line 637.
  • Attribute preservation is controlled via keep_dest_attrs=not remote_src, ensuring original permissions are maintained during remote-only operations.

Frequently Asked Questions

What is the difference between local and remote source in the Ansible copy module?

By default, the copy module operates in local-to-remote mode, reading src from the Ansible controller and uploading it to the managed node. When you set remote_src: yes, the module treats src as a path already existing on the remote host, performing all operations locally on the target filesystem without network transfer.

How do I perform an atomic move operation using the Ansible copy module?

Combine remote_src: yes with state: link and force: yes. This configuration triggers the module.atomic_move() function (line 637 in lib/ansible/modules/copy.py), which performs an atomic rename operation. If the destination exists, force: yes ensures it is replaced atomically.

Does using remote_src: yes preserve file permissions and ownership?

Yes. The module passes keep_dest_attrs=not remote_src to the underlying atomic move function. When remote_src is true, this parameter becomes false, instructing the module to preserve the original source file's attributes rather than adopting the destination's defaults.

When should I use the copy module versus the command module for remote file operations?

Use the copy module when you need idempotency, safety checks like checksum validation, and integration with Ansible's reporting. While the command or shell modules can execute mv or cp for simple operations, the copy module provides unsafe_writes protection, diff mode support, and proper change detection as implemented in lib/ansible/plugins/action/copy.py.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s https://instagit.com/install.md

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client