Mastering File Management with Ansible: A Comprehensive Guide

Welcome to this comprehensive guide on managing files using Ansible modules. Here, you’ll discover how to efficiently copy, edit, insert, download, and replace files with Ansible.

What Will We Cover?

  • Copying files using ‘copy’ and ‘template’ modules
  • Downloading files using the ‘fetch’ module
  • Editing files using ‘blockinfile’, ‘lineinfile’, and ‘replace’ modules
  • Managing file attributes

Copying Files with Ansible

Ansible offers modules to facilitate the copying of files from a local directory to remote target machines using the ‘copy’ and ‘template’ modules.
The ‘copy’ module is ideal for file transfer from the ‘files’ directory, whereas the ‘template’ module works with Jinja2 templates from the ‘templates’ directory, perfect for reusable configurations.

1. Copy File from Local to Remote Target Machine

Copy the ‘sources.list’ configuration from the local ‘files’ directory to the remote machine’s ‘/etc/apt/sources.list’. The existing file will be replaced and a backup will be created with a timestamp.

- name: Copy from Local to Remote Target Machine with 'copy'
  copy:
    src: sources.list
    dest: /etc/apt/sources.list
    backup: yes

2. Copy File on Remote Machine to Another Directory

Transfer the sudoers configuration ‘/etc/sudoers.d/hakase’ from one directory on the remote machine to ‘/home/hakase/hakase-sudoers.txt’. Utilize the ‘remote_src’ option to achieve this.

- name: Copy file from one directory to another on the Remote Machine
  copy:
    src: /etc/sudoers.d/hakase
    dest: /home/hakase/hakase-sudoers.txt
    remote_src: yes

3. Copy File and Modify Permissions and Ownership

Transfer the bash file from the ‘files’ directory to the remote machine and set the default file permission to ‘0755’ with ‘hakase’ as the owner.

- name: Copy file and set up the permission and owner of the file
  copy:
    src: simple.sh
    dest: /home/hakase/simple.sh
    owner: hakase
    group: hakase
    mode: 0755

4. Copy File with Template Module

Transfer the Jinja2 template for an Nginx virtual host from the ‘templates’ directory to ‘/etc/sites-enabled/’ on the remote machine. Use variables within Jinja2 templates for enhanced reusability.

- name: Copy file using 'template' module
  template:
    src: default.j2
    dest: /etc/nginx/sites-enabled/
    backup: yes
    owner: root
    group: root
    mode: 0644

Downloading Files Using the Fetch Module

The ‘fetch’ module enables downloading files from a remote machine to the local Ansible node.

1. Download from Remote to Local

Backup the nginx configuration file ‘nginx.conf’ by transferring it from the remote server to the local directory ‘/home/hakase/backup’. The ‘fetch’ module maintains directory structures by default.

- name: Download file from Remote Machine to Local ansible-node directory
  become: yes
  fetch:
    src: /etc/nginx/nginx.conf
    dest: /home/hakase/backup/

2. Download Without Directory Structures

To download without directory structures, add the ‘flat’ option.

- name: Download file from Remote Machine to Local ansible node without directory structures
  become: yes
  fetch:
    src: /etc/nginx/nginx.conf
    dest: /home/hakase/backup/
    flat: yes

Editing Files with Ansible

Ansible offers several modules for editing files, such as ‘blockinfile’, ‘lineinfile’, and ‘replace’. These modules allow you to modify files by inserting, deleting, or replacing lines and blocks.

1. Insert Multiple Lines Using ‘blockinfile’

Add multiple configuration lines to ‘sshd_config’ with the ‘blockinfile’ module. The new configuration is inserted at the bottom by default.

- name: Insert multiple lines and Backup
  blockinfile:
    path: /etc/ssh/sshd_config
    backup: yes
    block: |
      ClientAliveInterval 360
      ClientAliveCountMax 0

2. Insert with Marker Options

To insert lines at a specific position, use the ‘marker’ option with ‘insertafter’ or ‘insertbefore’.

- name: Insert after regex, backup, and validate
  blockinfile:
    path: /etc/ssh/sshd_config
    backup: yes
    marker: "# {mark} ANSIBLE MANAGED BLOCK "
    insertbefore: '^UsePAM '
    block: |
      AllowUsers hakase vagrant
      PermitEmptyPasswords no
      PermitRootLogin no
    validate: '/usr/sbin/sshd -T -f %s'

3. Delete/Remove Block with Markers

Eliminate a block of text surrounded by the Ansible marker ‘# BEGIN ANSIBLE MANAGED BLOCK’.

- name: Remove text block surrounded by markers
  blockinfile:
    path: /etc/ssh/sshd_config
    marker: "# {mark} ANSIBLE MANAGED BLOCK"
    content: ""
    backup: yes

4. Insert a New Line

Insert ‘PasswordAuthentication no’ under the specified regex ‘#PermitEmptyPasswords’ in ‘/etc/ssh/sshd_config’.

- name: Insert New Line under the Regex configuration
  lineinfile:
    path: /etc/ssh/sshd_config
    backup: yes
    regexp: '^PasswordAuthentication '
    insertafter: '^#PermitEmptyPasswords '
    line: 'PasswordAuthentication no'
    validate: '/usr/sbin/sshd -T -f %s'

5. Remove a Line with ‘lineinfile’

Use ‘state: absent’ to delete a line that matches a specified regex from the file.

- name: Remove a line from the file
  lineinfile:
    path: /etc/ssh/sshd_config
    state: absent
    regexp: '^PasswordAuthentication'

6. Replace Pattern Strings

Utilize the ‘replace’ module to alter strings using regex. For instance, change the host name in ‘/etc/hosts’.

- name: Replace the default
  replace:
    path: /etc/hosts
    regexp: '(\s+)node\.provision\.labs(\s+.*)?$'
    replace: '\1box.hakase.labs\2'
    backup: yes

7. Uncomment Configurations

The ‘replace’ module can also uncomment configurations by removing ‘#’ at the beginning of a line.

- name: Uncomment configuration
  replace:
    path: /etc/nginx/nginx.conf
    regexp: '#(\s+)server_tokens'
    replace: 'server_tokens'
    backup: yes

8. Comment a Configuration Line

Comment a configuration line by adding ‘#’ at the beginning of the line.

- name: Comment Line configuration
  replace:
    path: /etc/nginx/nginx.conf
    regexp: '(\s+)gzip on'
    replace: '\n\t#gzip on'
    backup: yes

Managing File Attributes with Ansible

Ansible’s file module can modify file attributes, such as changing the owner, group, and permissions, as well as creating symlinks, directories, and deleting entities.

1. Create a Symlink

Create a symlink for Nginx virtual host configuration ‘vhost’ to ‘/etc/nginx/sites-enabled/’.

- name: Create Symlink of file
  file:
    src: /etc/nginx/sites-available/vhost
    dest: /etc/nginx/sites-enabled/vhost
    owner: root
    group: root
    state: link

2. Create a New Directory

Create a directory using the file module by setting ‘state’ to ‘directory’.

- name: Create a New Directory using file
  file:
    path: /etc/nginx/ssl
    state: directory
    owner: root
    group: root
    mode: 0755

Reference

For more information, visit the Ansible documentation.

FAQ

What is the primary purpose of the ‘copy’ module in Ansible?

The ‘copy’ module is used to transfer files directly from the local ‘files’ directory to remote machines.

How does the ‘template’ module differ from ‘copy’?

The ‘template’ module deploys Jinja2 templates and is particularly helpful for generating dynamic, reusable configurations.

What can the ‘fetch’ module do?

The ‘fetch’ module downloads files from remote machines to the local node, preserving directory structures by default, unless the ‘flat’ option is used.

How does ‘lineinfile’ differ from ‘blockinfile’?

‘lineinfile’ manages individual lines, whereas ‘blockinfile’ handles multiple line blocks in a file.

Can I modify file permissions with Ansible?

Yes, the ‘file’ module can change permissions, ownership, create directories, symlinks, and manage other file attributes.