In the next five minutes, you’re going to become an instant expert at using the ansible.builtin.copy module (one of the first ten Ansible modules you should know) to manage static Linux files. After this, you’ll know how to transfer these files from your version control repo (so you don’t have to wonder anymore if the latest version of a file that you need updated all of your systems is already there); or even easily create new files on the fly (using content that might only be knowable at runtime); as well as use remote sources (to make everything happen on the hosts you’re automating). (And as with just about everything, Ansible provides a similar win_copy module for the Windows platform.) We’ll also outline how the trusty copy module compares to some common Ansible alternatives. So say “so long” to manually scp’ing over that one random file nobody ever remembers to include in the legacy “standard” build process you inherited, and say “hello” to being able to begin truly automating your infrastructure– from the file-level, up.

See also:

Task 1: Copying a File

  • The Ansible copy module helps you transfer a static file (typically maintained in your version control repo) to a remote host. A common Infrastructure as Code (IaC) approach is to place static files (vs. dynamically-generated template files and everything else) in a separate, predictably-located, version controlled-folder called “files” in your source control repo. Using vars like we do here may make it a tad bit harder to read initially, but the benefit is that you and your colleagues can immediately reuse this playbook for a different task whenever inspiration strikes next.
# copy-example1.txt:
- name: Copy file to remote host
  hosts: all
  vars:
    mypath: "/path/to/"
    myfile: "file.txt"
  tasks:
    - name: "Copy {{ myfile }}"
      ansible.builtin.copy:
        src: "files/{{ myfile }}" # files/file.txt
        dest: "{{ mypath }}{{ myfile }}" # /path/to/file.txt
        owner: myuser
        group: wheel
        mode: '0644'

Task 2: Copying Content

  • Use the content parameter instead of src to copy a text directly to a remote file. The pipe character (“|”) tells Ansible to copy the text which follows line by line (meaning it retains any newline characters it finds here.)
# copy-example2.txt:
- name: Copy content line by line to remote host
  hosts: all
  tasks:
    - name: Copy content
      ansible.builtin.copy:
        content: |
          This is the first line.
          This is the second.
        dest: /path/to/file.txt

Task 3: Using remote_src

  • The remote_src parameter copies a file from one location to another with the source file already being on the remote host.
# copy-example3.txt:
- name: Copy file on remote host
  hosts: all
  tasks:
    - name: Copy remote file
      ansible.builtin.copy:
        src: /path/to/remote/source/file.txt
        dest: /path/to/remote/destination/file.txt
        remote_src: true

Module Comparison Points

  • Copy vs. Template
    • Copy: Transfers a file or content from the Ansible controller to the remote host.
    • Template: Generates a file on the remote host based on a Jinja2 template on the controller, allowing dynamic content that you are completely in control of placing where and how you need it (template even includes if-else and for logic).
    • Why you might want Copy rather than Template: for transferring static files, for simple file transfers, and when no templating is required.
  • Copy vs. Synchronize
    • Copy: Uses the Ansible controller to transfer individual files or content to remote hosts.
    • Synchronize: Uses the rsync protocol to efficiently transfer and synchronize multiple files or directories between the controller and remote hosts.
    • Why you might want Copy rather than Synchronize: for copying individual files, for basic content transfers, and when there’s no rsync requirement.
  • Copy vs. Fetch
    • Copy: Transfers a file or content from the Ansible controller to the remote host.
    • Fetch: Retrieves a file or files from remote host and stores them on the controller.
    • Why you might want Copy rather than Fetch: the Copy module’s main job is to copy files FROM the Ansible controller TO the remote host it’s managing. In direct contrast, Fetch is designed to retrieve files from remote hosts and store them on the controller. Fetch is probably a bit more limited in its day-to-day use cases, but it’s going to be good for things like quick system file audits, or when you need simple 1-2 file backups in a pinch.

Wrapping Up

We’ve just explored the flexible and dependable Ansible copy module, which allows you to effortlessly transfer static files and even copy content line by line, like a true automation pro. With these newly-acquired powers at your fingertips, and especially when you understand how copy compares to related modules like template, synchronize, and fetch, you can further streamline your Infrastructure as Code (IaC) practices and improve efficiency of managing your IT resources and processes right away. Putting the copy module to work for you in automating your Linux file management means that you are beginning to unlock the full potential of Ansible from the earliest days. And the copy module is yet another example of how Ansible keeps simple things simple… while making complex things possible.

Get the latest from Level Up delivered to your inbox– DevOps Automation and Cloud news, tips & tricks.

Select list(s) to subscribe to


By submitting this form, you are consenting to receive marketing emails from: Level Up, 20929 Ventura Blvd Ste 47 #265, Woodland Hills, CA, 91364. You can revoke your consent to receive emails at any time by using the SafeUnsubscribe® link, found at the bottom of every email. Emails are serviced by Constant Contact

Spread the word. Share this post!