Table of Contents

How to perform File System operations (copy, exists, move, …) in Ansible?

About

This page shows you how to perform File system operations in Ansible.

Management

Get file name

{{ item|basename }}
{{ item | basename | splitext | first }}
{{ path | dirname }}

More managing-file-names-and-path-names

Create a directory

http://docs.ansible.com/file_module.html

# create a directory if it doesn't exist
- file:
    path: /etc/some_directory
    state: directory
    mode: 0755

Create a file

- name: Touch a file, using symbolic modes to set the permissions (equivalent to 0644)
  file:
    path: /etc/foo.conf
    state: touch
    mode: u=rw,g=r,o=r

Ownership

Ownership recursively

- file:
    path: /etc/some_directory
    state: directory
    group: 'foo'
    owner: 'bar'
    recurse: yes

Move

from local to host

With Copy
- name: Copy ansible inventory file to client (command on  multi-line - break + indent any continuation lines)
  copy: 
    src: hosts 
    dest: /etc/ansible/hosts
    owner: root 
    group: root 
    mode: 0644
    backup: yes

where the relative search path for src is

The synchronize-module is more efficient than copy for a large number of files. The synchronize module wraps rsync.

With template

See Ansible - Template module

from same host

- name: Move file
  become: yes
  become_user: "{{ prometheus_user_name }}"
  shell:
    cmd: "/bin/cp {{ prometheus_install_dir }}/{{ prometheus_node_exporter_name }}/* {{ prometheus_home }}"

from Host to host

You use normally 'rsync' for this purpose (with the synchronize module or at the command line)

Example:

- name: 'Copy the keystore from the master'
  delegate_to: "{{ hostvars[ groups['gateway'][0] ].inventory_hostname }}"
  shell: |
    sshpass -p "{{ ansible_password }}" rsync \
      -v \
      {{ src_path_file }} \
      {{ ansible_user }}@{{ ansible_host }}:{{ dst_path_file }}
  register: keystore_copy
  changed_when: keystore_copy.rc != 0
- hosts: all
  tasks:    
   - name: Copy Remote-To-Remote (from serverA to serverB)
     synchronize: src=/copy/from_serverA dest=/copy/to_serverB
     delegate_to: serverA
     when: inventory_hostname = serverB

Loop

One directory

with with_fileglob -

- name: display content of all .txt files in dir
  debug: msg={{lookup('fileglob', '/my/path/*.txt')}}

- name: "Connection templates that add the environment as prefix {{ env_name}}"
    become: yes
    become_user: '{{ bdm_install_user }}'
    template:
      src: '{{ item }}'
      dest: '{{ connection_dst }}/{{ item|basename }}_{{ env_name|upper }}'
      owner: '{{ bdm_install_user }}'
      group: '{{ bdm_install_group }}'
      mode: 0770
    with_fileglob: 'template/connections/*'

The tree (recursive)

- name: "Creating connection file properties from template for the environment {{ env_name }}"
    become: yes
    become_user: '{{ bdm_install_user }}'
    template:
      src: '{{ item.src }}'
      dest: '{{ bdm_connection_dst }}/{{ item.path }}_{{ env_name|upper }}'
      owner: '{{ bdm_install_user }}'
      group: '{{ bdm_install_group }}'
      mode: 0770
    with_filetree: 'template/connection/{{ env_name|lower }}'
    when: item.state == 'file'

Conditional task

based on file presence, if file exists

- name: Stat the {{ infa_domain_file }} 
  stat:
    path: '{{infa_domain_file}}'
  register: infa_domain_file

- name: Install if the domain file does not exist
  become: yes
  become_user: '{{ bdm_install_user }}'
  import_tasks: user_install.yml
  when: not infa_domain_file.stat.exists

You can also just fail

- name: Check if Gogs is already installed.
  stat:
    path: "{{ gogs_bin_file }}"
  register: gogs_bin

- name: Download
  when: gogs_bin.stat.islnk is not defined
  block:
  ...

Creation of file with content

You create a file with you own content (ie string) with the copy module

Example with a private key that was encrypted with encrypt string

- name: Private Key
  copy:
    content: "{{ private_key }}"
    dest: "/path/to/my/key"
    owner: 'root'
    group: 'root'
    mode: "0600"

Presence of text in file

Block In File

blockinfile:
    path: /etc/hosts
    block: |
      {{ item.ip }} {{ item.name }}
    marker: "# {mark} ANSIBLE MANAGED BLOCK Hostname"
  with_items:
    - { name: "{{ hostname }}  {{ hostname.split('.', 1)[0] }}", ip: 127.0.0.1 }

Lineinfile

Example:

- name: 'Configure the Java memory requirement'
  lineinfile:
    dest: "{{nexus_application_directory}}/bin/nexus.vmoptions"
    state: present
    regexp: "{{ item.regexp }}"
    line: "{{ item.line }}"
  with_items:
    - regexp: '^-Xms(\\d+)m$'
      line: '-Xms{{nexus_java_memory}}m'
    - regexp: '^-Xmx(\\d+)m$'
      line: '-Xmx{{nexus_java_memory}}m'
    - regexp: '^-XX:MaxDirectMemorySize=(\\d+)m$'
      line: '-XX:MaxDirectMemorySize={{nexus_java_memory}}m'
  notify:
    - nexus reload