Choosing between Ansible’s copy and template modules

When it comes to transferring files to a remote system with Ansible, the copy and template modules are great tools for the job. So many things can be done in Linux using simple files. Copying essential configuration files to remote servers is an excellent use case for those who are just starting their Ansible journey. This article discusses some best practices for choosing between the Ansible copy and template modules.

Before I begin, let me show you the directory structure that I am using for this tutorial so you can follow along:

$ tree
├── copy.yml
├── files
│   └── etc
│       └── motd
├── inventory.yml
├── templates
│   └── etc
│       └── keepalived
│           └── keepalived.conf.j2
└── template.yml

5 directories, 5 files

I am executing these playbooks against a single host, as seen in my inventory file below:

$ cat inventory.yml

The copy module

Ansible’s copy module does exactly what you expect: It copies a file from the local host to a remote server. The copy module is easy to use and requires little explanation:

- hosts:
  gather_facts: no
    - name: Copy MOTD into place
        dest: /etc/motd
        src: etc/motd
        owner: root
        group: root
        mode: 0644

After running my Ansible playbook with ansible-playbook -i inventory.yml copy.yml, I have an updated motd file on the remote system:

root@nyc1-webserver-1:~# cat /etc/motd 
This is an MOTD added via Ansible

The copy module is perfect for those files that are always consistent across all of your systems. Some examples include:

  • Login banners and messages of the day (motd)
  • Base application configuration files that never vary between systems, such as an SSH configuration file that you want to keep consistent
  • A binary application file that you want to copy exactly from your local system to remote systems

If you’re using source code management, such as Git, for your Ansible playbooks, ensure that any files handled by the copy module are appropriate to put in source code. You should never use a tool like Git to store files with sensitive information, such as passwords or private data.

The template module

The template module also copies a file to a remote server, but it allows you to use Jinja2 to render a template to a file dynamically. This enables you to use variables, such as Ansible facts, to customize a particular file for a specific server. That might sound confusing to the new Ansible user, so I’ll break it down a bit through an example.

The playbook below installs and configures keepalived. If you’ve read my previous series about Linux high availability, then you’re already familiar with the purpose of keepalived. If you’re not, then don’t worry about it. Just realize that the playbook below installs the keepalived application and writes a needed configuration file:

- hosts:
  gather_facts: yes
    keepalived_priority: 100
    keepalived_state: MASTER
    keepalived_vrid: 10
    keepalived_vrrp_instance_name: "HA_10"
    - name: Install Keepalived
        name: keepalived
        state: present

    - name: Add Keepalived config file
        dest: /etc/keepalived/keepalived.conf
        src: etc/keepalived/keepalived.conf.j2
      notify: Restart Keepalived

    - name: Restart Keepalived
        name: keepalived
        state: restarted

The source file is stored at templates/etc/keepalived/keepalived.conf.j2. Ansible is smart enough to automatically search for templates in specific known locations, such as templates/, so that you don’t have to worry about typing the entire path. This path contains the keepalived configuration file. The file uses the .j2 suffix so that you know it is a Jinja2 template.

Notice that Jinja2 syntax is used to reference both built-in Ansible facts (ansible_default_ipv4['interface']) and variables (keepalived_state) that are provided via the vars key in the playbook YAML:

vrrp_instance {{ keepalived_vrrp_instance_name }} {
  interface                 {{ ansible_default_ipv4['interface'] }}
  state                     {{ keepalived_state }}
  virtual_router_id         {{ keepalived_vrid }}
  priority                  {{ keepalived_priority }}

  virtual_ipaddress {
    {{ keepalived_vip }} dev {{ ansible_default_ipv4['interface'] }} label {{ ansible_default_ipv4['interface'] }}:VIP

Once you run this playbook via ansible-playbook -i inventory.yml template.yml, the destination file on the remote system will have a completed configuration file, with all variables filled in, at /etc/keepalived/keepalived.conf:

root@nyc1-webserver-1:~# cat /etc/keepalived/keepalived.conf 
vrrp_instance HA_10 {
  interface                 ens3
  state                     MASTER
  virtual_router_id         10
  priority                  100

  virtual_ipaddress { dev ens3 label ens3:VIP

Jinja2 templates are a very powerful way to render customized files out to hosts (or groups of hosts, if you want to use group variables that apply to multiple hosts). This is just a basic example. Complex templates using loops and advanced logic are possible with Jinja2, as described in the documentation.

What to choose?

So when would you use the template module instead of the copy module? Personally, I find that I use the template module most of the time. There’s almost always something about a configuration file that needs to be customized on a per-host basis. Some concrete examples include:

  • Application configuration files with dynamic content, such as the NGINX server block that I discussed in my previous article about Ansible for web servers.
  • Configurations that might need to be rendered an arbitrary number of times based on host or group variables. For example, you might dynamically configure multiple Filebeat settings based on log file paths that are passed in as variables. Not all servers have the same log file paths, so templates are the ideal solution for per-host customization.
  • Files with sensitive data in them that shouldn’t be stored in source control. You can even use Ansible Vault to store the secret and dynamically render it with Jinja2.

Using the template module is a great way to enable reusability in your playbooks. Your playbooks are generalized because they don’t contain host-specific information, and so they are portable between different hosts, projects, or even companies. Remember: Always try to write code that can be reused!

Final thoughts

Before I leave you, I’d like to cover two aspects of my playbooks that you might have noticed. First, I use a full-path directory structure for the source of files and templates (e.g., templates/etc/keepalived/keepalived.conf.j2) instead of just throwing all files into the root directory (e.g., templates/keepalived.conf.j2). This is a great habit to form. While this may grow your directory tree, it makes the destination of a file or template immediately obvious without actually reading the playbook code.

You probably also noticed that the syntax is nearly identical for the copy and template modules. This makes it easy to swap out one for the other as your needs change. You might start by copying over a static application configuration to all of the servers in your environment. As you continue to build your automation capabilities, you might find that certain parts of that configuration should be customized on a per-host basis. You can easily substitute the copy key for the template key in your playbook and benefit from the flexibility offered by the Jinja2 template language.

The adage that “everything is a file in Linux” generally holds true, and this makes file management one of the most critical tasks that you can automate with tools like Ansible. In this article, you learned the basics of the copy and template modules, including some use cases for each. Equipped with this information, you can begin to write powerful and flexible Ansible playbooks for file management in your environment.

[ Need more on Ansible? Take a free technical overview course from Red Hat. Ansible Essentials: Simplicity in Automation Technical Overview. ]

Source link

Recent articles

At Pentagon, Fears Grow That Trump Will Pull Military Into Election Unrest

WASHINGTON — Senior Pentagon leaders have a lot to worry about — Afghanistan, Russia, Iraq, Syria, Iran, China, Somalia, the Korean Peninsula. But...

What’s New on Netflix UK This Week & Top 10s: September 25th, 2020

Halloween (2018) is now available to stream on Netflix Not an extremely busy week on Netflix UK, but with the impending arrival of October,...

Babar Qadri, Lawyer and Defender of Kashmir, is Murdered

SRINAGAR, Kashmir — On television and in the courtroom, the young lawyer could be a force. Babar Qadri stood as a rare, pugilistic...

​Wizz and KLM scale back European capacity amid restrictions | News

Wizz Air has again reduced its capacity outlook for October while KLM has put its short-haul network expansion plans “on hold” as ongoing coronavirus-related travel restrictions...

How to Get Great Photos of the Character Cavalcades at Walt Disney World

Currently, the only way you can see and photograph Disney characters at Walt Disney World is during the many Character Cavalcades at each...

South African mobile recruitment platform Giraffe wants to get young people back to work

After months of being ignored by recruiters in her home country of South Africa, the economics graduate began using a recruitment website called...

Leave a reply

Please enter your comment!
Please enter your name here