AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible Move File: Relocate Files Between Directories (Complete Guide)

By Luca Berton · Published 2024-01-01 · Category: installation

How to move files in Ansible between directories. Use copy+file modules, command module with mv, synchronize module.

Ansible Move File: Relocate Files Between Directories (Complete Guide)

Moving files between directories is a common task in system administration, but Ansible doesn't have a dedicated "move" module. This guide covers all practical approaches to move files with Ansible, from the recommended copy+delete pattern to using the command module.

See also: Ansible Create File with Content: Write Text to Files (Complete Guide)

Why No ansible.builtin.move Module?

Ansible follows an idempotent design philosophy. A "move" operation is inherently non-idempotent — running it twice would fail because the source no longer exists after the first run. Instead, Ansible provides building blocks that you combine for safe, repeatable file operations.

The safest and most idempotent approach uses ansible.builtin.copy to copy the file, then ansible.builtin.file to remove the original:

---
- name: Move file using copy + delete pattern
  hosts: all
  tasks:
    - name: Copy file to new location
      ansible.builtin.copy:
        src: /opt/app/config.yml
        dest: /etc/app/config.yml
        remote_src: true
        owner: root
        group: root
        mode: '0644'

- name: Remove original file ansible.builtin.file: path: /opt/app/config.yml state: absent

Key parameter: remote_src: true tells Ansible to copy between paths on the remote host (not from the control node).

See also: Ansible Move File: Rename & Move Files on Remote Hosts (Complete Guide)

Method 2: Command Module with mv

For simple moves where idempotency is handled by conditionals:

---
- name: Move file with command module
  hosts: all
  tasks:
    - name: Check if source file exists
      ansible.builtin.stat:
        path: /tmp/upload/data.csv
      register: source_file

- name: Move file to target directory ansible.builtin.command: cmd: mv /tmp/upload/data.csv /var/lib/app/data.csv when: source_file.stat.exists

Move with creates/removes Guards

Use creates and removes parameters for built-in idempotency:

- name: Move file with idempotency guards
  ansible.builtin.command:
    cmd: mv /tmp/installer.bin /opt/installers/installer.bin
    removes: /tmp/installer.bin
    creates: /opt/installers/installer.bin

Method 3: Rename a File

Renaming is just moving to the same directory with a different name:

- name: Rename configuration file
  ansible.builtin.command:
    cmd: mv /etc/app/config.yml.bak /etc/app/config.yml
    removes: /etc/app/config.yml.bak
    creates: /etc/app/config.yml

See also: Ansible Create File with Content: copy Module content Parameter

Method 4: Move Multiple Files with find + loop

Move all files matching a pattern:

---
- name: Move all log files to archive
  hosts: all
  tasks:
    - name: Find all .log files in /var/log/app
      ansible.builtin.find:
        paths: /var/log/app
        patterns: "*.log"
        age: "7d"
      register: old_logs

- name: Copy log files to archive ansible.builtin.copy: src: "{{ item.path }}" dest: "/var/log/archive/{{ item.path | basename }}" remote_src: true loop: "{{ old_logs.files }}"

- name: Remove original log files ansible.builtin.file: path: "{{ item.path }}" state: absent loop: "{{ old_logs.files }}"

Method 5: Move Directories

Move an entire directory tree:

---
- name: Move directory to new location
  hosts: all
  tasks:
    - name: Synchronize directory to new location
      ansible.posix.synchronize:
        src: /opt/old-app/
        dest: /opt/new-app/
        delete: false
      delegate_to: "{{ inventory_hostname }}"

- name: Remove original directory ansible.builtin.file: path: /opt/old-app state: absent

Or with the command module:

- name: Move directory with mv
  ansible.builtin.command:
    cmd: mv /opt/old-app /opt/new-app
    removes: /opt/old-app
    creates: /opt/new-app

Method 6: Move Files Between Remote Hosts

Use ansible.builtin.fetch + ansible.builtin.copy:

---
- name: Fetch file from source host
  hosts: source_server
  tasks:
    - name: Download file to control node
      ansible.builtin.fetch:
        src: /var/data/export.sql
        dest: /tmp/transfer/
        flat: true

- name: Deploy file to destination host hosts: dest_server tasks: - name: Upload file to destination ansible.builtin.copy: src: /tmp/transfer/export.sql dest: /var/data/import.sql owner: postgres group: postgres mode: '0600'

Comparison: Which Method to Use

| Method | Best For | Idempotent | Preserves Permissions | |--------|----------|------------|----------------------| | copy + delete | Single files, safety | ✅ Yes | ✅ Yes (set explicitly) | | command mv | Speed, large files | ⚠️ With guards | ✅ Yes | | synchronize | Directories | ✅ Yes | ✅ Yes | | fetch + copy | Cross-host | ✅ Yes | ✅ Yes | | find + loop | Pattern matching | ✅ Yes | ✅ Yes |

Common Mistakes

1. Forgetting remote_src

# WRONG — tries to copy from control node
- ansible.builtin.copy:
    src: /etc/app/old.conf
    dest: /etc/app/new.conf

# CORRECT — copies on the remote host - ansible.builtin.copy: src: /etc/app/old.conf dest: /etc/app/new.conf remote_src: true

2. Not Checking Source Exists

# WRONG — fails if source doesn't exist
- ansible.builtin.command:
    cmd: mv /tmp/file.txt /opt/file.txt

# CORRECT — skips if source is gone - ansible.builtin.command: cmd: mv /tmp/file.txt /opt/file.txt removes: /tmp/file.txt

3. Missing Target Directory

# Ensure target directory exists first
- ansible.builtin.file:
    path: /opt/target-dir
    state: directory
    mode: '0755'

- ansible.builtin.command: cmd: mv /tmp/file.txt /opt/target-dir/file.txt removes: /tmp/file.txt

FAQ

How do I move a file in Ansible?

Use the copy module with remote_src: true to copy the file to the new location, then the file module with state: absent to remove the original. Alternatively, use ansible.builtin.command with mv and removes/creates guards for idempotency.

Why doesn't Ansible have a move module?

Ansible is designed for idempotent operations. A move operation is inherently non-idempotent because the source file no longer exists after the first run. The copy + delete pattern achieves the same result while being safely repeatable.

Can I move files between two remote hosts with Ansible?

Yes. Use ansible.builtin.fetch to download the file from the source host to the control node, then ansible.builtin.copy to upload it to the destination host. For directory synchronization, use ansible.posix.synchronize.

How do I rename a file in Ansible?

Renaming is moving a file within the same directory. Use ansible.builtin.command with mv /path/old-name /path/new-name and removes/creates guards, or the copy + delete pattern with remote_src: true.

How do I move multiple files matching a pattern?

Use ansible.builtin.find to locate files matching your pattern, register the results, then loop over them with copy + file delete. See the "Move Multiple Files" example above.

Conclusion

While Ansible lacks a dedicated move module, the copy + delete pattern provides a safe, idempotent approach for most scenarios. Use ansible.builtin.command with mv for performance-critical operations on large files, and ansible.posix.synchronize for directory moves.

Related Articles

Ansible Create Directory: file Module state=directory GuideAnsible Delete File: Remove Files & DirectoriesAnsible Rename File: Move & Rename Filesansible.builtin.find Module: Search Files by PatternAnsible Fetch Module: Copy Files from Remote Hosts

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home