AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible Delete File & Remove File: file Module absent State Guide

By Luca Berton · Published 2024-01-01 · Category: database-automation

How to delete and remove files in Ansible with the file module (state=absent). Delete files, remove directories recursively, manage symlinks and permissions.

Ansible provides several modules for file operations: file (create/delete/permissions/links), copy (create files with content), stat (check existence), and command/shell for moves and renames. This guide covers every common file operation.

Create Files and Directories

Create an Empty File

- name: Create empty file
  ansible.builtin.file:
    path: /opt/app/config.yml
    state: touch
    owner: appuser
    group: appuser
    mode: '0644'

Create a File with Content

# Using copy module
- name: Create file with content
  ansible.builtin.copy:
    content: |
      # Application Configuration
      database_host: db.example.com
      database_port: 5432
      log_level: info
    dest: /opt/app/config.yml
    owner: appuser
    mode: '0644'

# From a variable
- name: Write variable to file
  ansible.builtin.copy:
    content: "{{ my_config | to_nice_yaml }}"
    dest: /opt/app/config.yml
    mode: '0644'

Create Directory

- name: Create directory
  ansible.builtin.file:
    path: /opt/app/logs
    state: directory
    owner: appuser
    group: appuser
    mode: '0755'

# Create nested directories
- name: Create directory tree
  ansible.builtin.file:
    path: /opt/app/data/cache/sessions
    state: directory
    # Creates all parent directories automatically

Create Multiple Directories

- name: Create application directories
  ansible.builtin.file:
    path: "{{ item }}"
    state: directory
    owner: appuser
    group: appuser
    mode: '0755'
  loop:
    - /opt/app/config
    - /opt/app/data
    - /opt/app/logs
    - /opt/app/tmp

See also: Ansible get_url Module Complete Reference: Checksums, Auth, Proxies & Retries

Delete Files and Directories

Delete a File

- name: Delete file
  ansible.builtin.file:
    path: /tmp/old-config.yml
    state: absent

Delete a Directory (Recursively)

- name: Delete directory and all contents
  ansible.builtin.file:
    path: /opt/old-app
    state: absent

Delete All Files in a Directory

# Find and delete files, keep directory
- name: Find all files in directory
  ansible.builtin.find:
    paths: /opt/app/logs
    file_type: file
  register: log_files

- name: Delete all log files
  ansible.builtin.file:
    path: "{{ item.path }}"
    state: absent
  loop: "{{ log_files.files }}"

# Or with patterns
- name: Delete old log files
  ansible.builtin.find:
    paths: /opt/app/logs
    patterns: "*.log"
    age: 30d
  register: old_logs

- name: Remove old logs
  ansible.builtin.file:
    path: "{{ item.path }}"
    state: absent
  loop: "{{ old_logs.files }}"

Rename and Move Files

# Rename/move a file
- name: Rename file
  ansible.builtin.command: mv /opt/app/config.yml.bak /opt/app/config.yml
  args:
    removes: /opt/app/config.yml.bak
    creates: /opt/app/config.yml

# Rename a directory
- name: Rename directory
  ansible.builtin.command: mv /opt/myapp-old /opt/myapp-new
  args:
    removes: /opt/myapp-old
    creates: /opt/myapp-new

# Copy + delete (for cross-filesystem moves)
- name: Copy file to new location
  ansible.builtin.copy:
    src: /opt/app/config.yml
    dest: /mnt/backup/config.yml
    remote_src: true

- name: Remove original
  ansible.builtin.file:
    path: /opt/app/config.yml
    state: absent

See also: Ansible 2.17.0-rc1: Elevating Automation with ‘Gallows Pole’

- name: Create symbolic link
  ansible.builtin.file:
    src: /opt/app/releases/2.1.0
    dest: /opt/app/current
    state: link

# Symlink for binary
- name: Link binary to PATH
  ansible.builtin.file:
    src: /opt/app/current/bin/myapp
    dest: /usr/local/bin/myapp
    state: link
  become: true
- name: Deploy new version
  ansible.builtin.unarchive:
    src: "myapp-{{ version }}.tar.gz"
    dest: /opt/app/releases/{{ version }}/

# Symlink update is atomic — no downtime
- name: Switch to new version
  ansible.builtin.file:
    src: /opt/app/releases/{{ version }}
    dest: /opt/app/current
    state: link
    force: true    # Overwrite existing symlink
  notify: restart app
- name: Remove symbolic link
  ansible.builtin.file:
    path: /usr/local/bin/myapp
    state: absent

Permissions and Ownership

Change Permissions (chmod)

- name: Set file permissions
  ansible.builtin.file:
    path: /opt/app/bin/start.sh
    mode: '0755'

# Symbolic mode
- name: Add execute permission
  ansible.builtin.file:
    path: /opt/app/bin/start.sh
    mode: 'u+x'

# Recursive permissions
- name: Set directory permissions recursively
  ansible.builtin.file:
    path: /opt/app/data
    state: directory
    recurse: true
    mode: '0755'

Change Ownership (chown)

- name: Change file ownership
  ansible.builtin.file:
    path: /opt/app
    owner: appuser
    group: appgroup
    recurse: true
  become: true

Common Permission Patterns

# Private key
- name: Secure SSH key
  ansible.builtin.file:
    path: /home/deploy/.ssh/id_ed25519
    owner: deploy
    group: deploy
    mode: '0600'

# Config file (owner read/write, group read)
- name: Set config permissions
  ansible.builtin.file:
    path: /etc/app/config.yml
    owner: root
    group: appuser
    mode: '0640'

# Executable script
- name: Set script permissions
  ansible.builtin.file:
    path: /opt/app/bin/start.sh
    mode: '0755'

# Shared directory
- name: Set shared directory
  ansible.builtin.file:
    path: /opt/shared
    state: directory
    mode: '2775'    # setgid bit
    group: sharedgroup

See also: ansible_date_time: Access Date, Time & Timestamp Facts in Ansible

Check if File/Directory Exists

- name: Check if file exists
  ansible.builtin.stat:
    path: /opt/app/config.yml
  register: config_file

- name: Create config if missing
  ansible.builtin.template:
    src: config.yml.j2
    dest: /opt/app/config.yml
  when: not config_file.stat.exists

# Check directory
- name: Check if directory exists
  ansible.builtin.stat:
    path: /opt/app/data
  register: data_dir

- name: Initialize data directory
  ansible.builtin.command: /opt/app/bin/init-data
  when: not data_dir.stat.exists

Copy Multiple Files

# Using with_fileglob
- name: Copy all config files
  ansible.builtin.copy:
    src: "{{ item }}"
    dest: /etc/app/conf.d/
    owner: appuser
    mode: '0644'
  with_fileglob:
    - "files/configs/*.conf"

# Using loop
- name: Copy specific files
  ansible.builtin.copy:
    src: "{{ item.src }}"
    dest: "{{ item.dest }}"
    mode: "{{ item.mode | default('0644') }}"
  loop:
    - { src: app.conf, dest: /etc/app/app.conf }
    - { src: logging.conf, dest: /etc/app/logging.conf }
    - { src: start.sh, dest: /opt/app/bin/start.sh, mode: '0755' }

FAQ

How do I create a file with content in Ansible?

Use the copy module with content parameter: ansible.builtin.copy: content="my content" dest=/path/to/file. For templates with variables, use ansible.builtin.template instead.

How do I delete a file in Ansible?

Use the file module with state: absent: ansible.builtin.file: path=/path/to/file state=absent. This works for both files and directories (recursive delete).

How do I rename a file in Ansible?

Use ansible.builtin.command: mv /old/path /new/path with removes and creates arguments for idempotency. There's no dedicated rename module — the command module with mv is the standard approach.

Use the file module with state: link: ansible.builtin.file: src=/target dest=/link state=link. Use force: true to overwrite existing symlinks.

How do I change file permissions recursively?

Use the file module with recurse: true: ansible.builtin.file: path=/opt/app state=directory recurse=true mode='0755' owner=appuser.

How do I check if a file exists in Ansible?

Use the stat module and check register_var.stat.exists: register the result, then use when: not result.stat.exists or when: result.stat.exists in subsequent tasks.

Conclusion

OperationModuleKey Parameter
Create empty filefilestate: touch
Create with contentcopycontent:
Create directoryfilestate: directory
Delete file/dirfilestate: absent
Rename/movecommandmv with creates/removes
Symlinkfilestate: link
Permissionsfilemode:
Ownershipfileowner:, group:
Check existsstat.stat.exists

Category: database-automation

Browse all Ansible tutorials · AnsiblePilot Home