Ansible Copy Module: Copy Files to Remote Targets

The Ansible copy module is used in various real-world scenarios where you need to copy files or templates from the Ansible host machine to a set of remote servers. Here are some common use cases.

  • Static Content Deployment: If you have static content such as HTML, CSS, JavaScript files, or other assets you want to deploy on web servers or application servers, you can use the copy module to ensure that these files are copied to the appropriate locations.
  • Key Files Deployment: Sometimes, you may need to distribute SSL certificates or SSH keys to multiple servers. The copy module allows you to securely distribute these files while maintaining control over their permissions and ownership.
  • Custom Templates: You can use Jinja2 templates with the copy module to dynamically generate configuration files or other text-based files based on variables or conditions specific to each managed node.
  • Configuration File Management: You can use the copy module to deploy a common configuration file for Nginx, Apache, or any other service across multiple servers.

Prerequisites

Before getting started, ensure you have the following:

  • Ansible is installed on your control node.
  • Access to one or more target hosts where you want to copy files.
  • Basic understanding of Ansible concepts such as inventory, playbooks, and tasks.

Understanding the Ansible Copy Module

Ansible copy module provides a simple and effective way to distribute files and directories across your infrastructure.

The basic syntax of a copy module is shown below:

- name: Copy file from control node to managed node
  copy:
    src: /source-pth/file.txt
    dest: /destination-path/file.txt

Explanation:

  • src: Specifies the path to the source file on the Ansible control node.
  • dest: Specifies the path to the destination file or directory on the remote nodes.

Now, let's explore some practical scenarios.

Practical Examples of Using Ansible Copy Model

Now that you are familiar with the syntax, let me share some practical use cases where you are likely to be using this Ansible module.

Example 1: Distributing Configuration Files

In this example, you will deploy an Nginx virtual host configuration file to multiple servers using Ansible's copy module and dynamically change the configuration file for different domain names using Ansible variables

First, create an Nginx configuration file template (nginx.conf.j2) that includes variables for the domain name. Here's an example:

nano nginx.conf.j2

Add the following configuration:

server {
    listen 80;
    server_name {{ domain_name }};
    root /var/www/{{ domain_name }};
    index index.html index.htm;

    access_log /var/log/nginx/{{ domain_name }}.log;
    error_log /var/log/nginx/{{ domain_name }}.log;

}

Next, create an Ansible playbook playbook.yml that uses the copy module to deploy the Nginx configuration file to multiple servers and dynamically sets the domain name using Ansible variables:

nano playbook.yml

Add the following configuration:

---
- name: Deploy Nginx configuration file
  hosts: nginx_servers
  vars:
    nginx_conf_path: /etc/nginx/conf.d/
    domain_names:
      - site1.example.com
      - site2.example.com
      - site3.example.com
  tasks:
    - name: Copy Nginx configuration file
      copy:
        src: nginx.conf.j2
        dest: "{{ nginx_conf_path }}{{ item }}"
      with_items: "{{ domain_names }}"

Now, run the above playbook.

ansible-playbook -i inventory_file playbook.yml

Replace inventory_file with your Ansible inventory file containing the list of remote servers.

This playbook will deploy the Nginx configuration file (nginx.conf.j2) to each server in the nginx_servers group. The copy module will dynamically replace the {{ domain_name }} variable in the template with each domain name specified in the domain_names variable. This allows you to deploy different Nginx configurations for different domain names across multiple servers using Ansible variables.

Example 2: Deploy Static Content

The Ansible copy module is an excellent choice for deploying static content like HTML, CSS, JavaScript files, and other assets to web or application servers. Here's how you can use the copy module to ensure that these files are copied to the appropriate locations:

First, create an Ansible playbook that defines the tasks to copy the static content files to the appropriate locations on your servers.

nano playbook.yml

Add the following configuration:

---
- name: Deploy static content to web servers
  hosts: web_servers
  become: yes
  become_user: root

  tasks:
    - name: Copy HTML files
      copy:
        src: /backup/html_files/
        dest: /var/www/html/
        owner: www-data
        group: www-data
        mode: '0755'


    - name: Copy CSS files
      copy:
        src: /backup/css_files/
        dest: /var/www/html/css/
        owner: www-data
        group: www-data
        mode: '0755'

    - name: Copy JavaScript files
      copy:
        src: /backup/js_files/
        dest: /var/www/html/js/
        owner: www-data
        group: www-data
        mode: '0755'

In this playbook:

  • web_servers is a group of servers where you want to deploy the static content.
  • src is the path to the local directory containing your HTML, CSS, and JavaScript files.
  • dest is the destination directory on the servers where you want to copy the files.

Now, run the Ansible playbook using the ansible-playbook command:

ansible-playbook -i inventory_file playbook.yml

Replace inventory_file with your Ansible inventory file containing the list of web servers.

Example 3: Deploying SSH and SSL Files

Ansible copy module is used for securely distributing sensitive files like SSL certificates, SSH keys, or other credentials to multiple servers while maintaining control over their permissions and ownership.

First, create a playbook.yml file.

nano playbook.yml

Add the following configuration:

---
- name: Distribute SSL certificates and SSH keys
  hosts: all
  tasks:
    - name: Copy SSL certificate file
      copy:
        src: /ssl/ssl_certificate.crt
        dest: /etc/ssl/certs/ssl_certificate.crt
        mode: '0644'
        owner: root
        group: root

    - name: Copy SSL private key file
      copy:
        src: /ssl/ssl_private_key.key
        dest: /etc/ssl/private/ssl_private_key.key
        mode: '0600'
        owner: root
        group: root

    - name: Copy SSH private key file
      copy:
        src: /ssh/ssh_private_key
        dest: /home/{{ ansible_user }}/ssh/ssh_private_key
        mode: '0600'
        owner: "{{ ansible_user }}"
        group: "{{ ansible_user }}"

Here is the explanation of the above playbook.

For SSL certificates and keys, we set appropriate file modes (0644 for certificates, 0600 for private keys) and ownership (root:root).

For SSH keys, we assume that each user has their own SSH directory. The ansible_user variable is used to dynamically set the owner and group of the SSH private key file.

Now, run the above playbook.

ansible-playbook -i inventory_file playbook.yml

Example 4: Copying File within Remote Servers

The copy module is typically used in Ansible to copy files from the Ansible control node to the target hosts. However, suppose you want to copy a file from the remote server to the same remote server in another location without involving the local machine. In that case, you can use the remote_src option along with the copy module.

Let's say you have a file named example.txt located on the remote host at /tmp/example.txt, and you want to copy it to a different location on the same host, say /var/tmp/. Let's create a playbook to achieve this task.

nano playbook.yml

Add the following configuration.

- name: Copy example.txt to /var/tmp/
  hosts: your_target_host
  tasks:
    - name: Copy file from remote host to another location
      copy:
        src: /tmp/example.txt  
        dest: /var/tmp/example.txt  
        remote_src: yes

In this example:

  • src: Specifies the source file on the remote host (/tmp/example.txt).
  • dest: Specifies the destination file on the remote host (/var/tmp/example.txt).
  • remote_src: yes: Indicates that the source file path is relative to the remote host.

When you run this Ansible playbook, it will copy example.txt from /tmp/example.txt on the remote host to /var/tmp/example.txt on the same remote host.

Conclusion

Overall, the copy module is a fundamental tool in Ansible for managing file distribution and configuration across your infrastructure. It helps ensure consistency and repeatability in your environment by automating the process of file distribution and configuration management.

If you are new to Ansible and want to learn it from the scratch, our Ansible tutorial series will be of great help. It's written for RHCE exam but it helps you the same whether you are preparing for the exam or not.

RHCE Ansible EX294 Exam Preparation Course
Learn all the essentials of Ansible with this hands-on tutorial series. It is ideal for RHCE Ansible EX294 exam preparation.
✍️
Author: Hitesh Jethwa has more than 15+ years of experience with Linux system administration and DevOps. He likes to explain complicated topics in easy to understand way.