Ansible Create Empty File: Touch Files with file Module (Guide)
By Luca Berton · Published 2024-01-01 · Category: installation
How to create empty files in Ansible with the file module state=touch. Create files, set permissions and ownership on new files.

How to create an empty file with Ansible?
Use ansible.builtin.file with state: touch to create an empty file on a remote host — identical to the Linux touch command. If the file already exists, its content is preserved and only the timestamps are updated. Combine with mode, owner, and group to set permissions in the same task.
See also: Ansible Create Symlink: file Module with state=link (Guide)
Ansible create an empty file — ansible.builtin.file
Today we're talking about the Ansible modulefile.
The full name is ansible.builtin.file, which means that is part of the collection of modules "builtin" with ansible and shipped with it.
It's a module pretty stable and out for years.
It works in a different variety of operating systems.
It manages files and file properties.
For Windows targets, use the ansible.windows.win_file module instead.
Main Parameters
- path string (dest, name) - file path
- state string - file/absent/directory/hard/link/touch
## Playbook Let's jump into a real-life playbook on how to create an empty file with Ansible.
- file.yml
---
- name: file module demo
hosts: all
vars:
myfile: "~/example.txt"
tasks:
- name: Creating an empty file
ansible.builtin.file:
path: "{{ myfile }}"
state: touchSee also: Ansible Create File with Content: copy Module content Parameter
Conclusion
Now you know how to create an empty file or update access time with Ansible.
Advanced File Creation Examples
Create file with specific ownership and permissions
- name: Create config file with proper permissions
ansible.builtin.file:
path: /etc/myapp/config.yml
state: touch
owner: appuser
group: appuser
mode: '0640'
become: trueCreate file only if it doesn't exist
The touch state always updates the timestamp. To create only if missing:
- name: Check if file exists
ansible.builtin.stat:
path: /etc/myapp/config.yml
register: config_file
- name: Create file only if missing
ansible.builtin.file:
path: /etc/myapp/config.yml
state: touch
mode: '0644'
when: not config_file.stat.existsCreate multiple files
- name: Create multiple empty files
ansible.builtin.file:
path: "{{ item }}"
state: touch
mode: '0644'
loop:
- /tmp/file1.txt
- /tmp/file2.txt
- /tmp/file3.logCreate a file with content (use copy module instead)
If you need content in the file, use ansible.builtin.copy:
- name: Create file with content
ansible.builtin.copy:
content: |
# Configuration file
setting1: value1
setting2: value2
dest: /etc/myapp/config.yml
owner: root
group: root
mode: '0644'
become: trueCreate parent directories automatically
The file module with state: touch requires parent directories to exist. Create them first:
- name: Ensure parent directory exists
ansible.builtin.file:
path: /opt/myapp/logs
state: directory
mode: '0755'
- name: Create log file
ansible.builtin.file:
path: /opt/myapp/logs/app.log
state: touch
mode: '0644'See also: Ansible Rename File: Move & Rename Files with copy + file Modules
touch vs copy vs template
| Module | Use Case |
|---|---|
file (state=touch) | Create empty file or update timestamp |
copy (content=) | Create file with static content |
template | Create file from Jinja2 template |
lineinfile | Add/modify a single line in existing file |
blockinfile | Add/modify a block of text in existing file |
FAQ
What's the difference between state: touch and state: file?
touch: Creates the file if it doesn't exist, updates timestamp if it doesfile: Only modifies attributes (owner, mode) of an existing file; fails if file doesn't exist
How do I create a file on Windows?
Use ansible.windows.win_file:
- name: Create file on Windows
ansible.windows.win_file:
path: C:\Temp\myfile.txt
state: touchCreate Empty File
- name: Create empty log file
ansible.builtin.file:
path: /var/log/myapp/app.log
state: touch
owner: appuser
group: appgroup
mode: '0644'
become: trueCreate with Parent Directories
# Create directory first (touch doesn't create parents)
- ansible.builtin.file:
path: /opt/myapp/logs
state: directory
owner: appuser
mode: '0755'
become: true
- ansible.builtin.file:
path: /opt/myapp/logs/app.log
state: touch
owner: appuser
mode: '0644'
become: trueCreate Multiple Empty Files
- ansible.builtin.file:
path: "{{ item }}"
state: touch
mode: '0644'
loop:
- /opt/myapp/logs/access.log
- /opt/myapp/logs/error.log
- /opt/myapp/logs/debug.log
- /opt/myapp/.env
become: trueCreate Only If Not Exists
# touch updates timestamp if file exists
# Use copy with force: false to only create
- ansible.builtin.copy:
content: ""
dest: /opt/myapp/.lock
force: false # Don't overwrite if exists
mode: '0644'
become: trueCreate File with Content
# For files WITH content, use copy instead
- ansible.builtin.copy:
content: |
# Application config
APP_ENV=production
APP_PORT=8080
dest: /opt/myapp/.env
mode: '0600'
become: truetouch vs copy (empty)
| Method | Creates | Updates Timestamp | Overwrites |
|---|---|---|---|
file: state=touch | Yes | Always | No (preserves content) |
copy: content="" | Yes | Only if changed | Yes (empties file) |
copy: force=false | Yes | No | No |
Set Access/Modification Time
- ansible.builtin.file:
path: /opt/myapp/marker
state: touch
access_time: "202601010000.00"
modification_time: "202601010000.00"FAQ
Does touch overwrite existing file content?
No — state: touch creates an empty file OR updates the timestamp of an existing file without changing its content. It's safe to use on files with data.
Why does touch always report "changed"?
Because it updates the timestamp every run. To avoid this, use copy: content="" force=false or add a stat check first.
How do I create an empty file on Windows?
- ansible.windows.win_file:
path: C:\app\logs\app.log
state: touchCreate Empty File
- ansible.builtin.file:
path: /opt/myapp/.installed
state: touch
become: trueWith Permissions
- file:
path: /var/log/myapp/app.log
state: touch
mode: '0644'
owner: appuser
group: appuser
become: trueCreate Only If Missing
# state=touch always updates mtime!
# To only create if missing:
- stat:
path: /opt/myapp/.initialized
register: init_file
- file:
path: /opt/myapp/.initialized
state: touch
when: not init_file.stat.exists
become: trueCreate with copy (Content)
# Empty file with copy
- copy:
content: ""
dest: /opt/myapp/.keep
force: false # Don't overwrite if exists
become: trueMarker/Flag Files
# Create after successful deployment
- command: /opt/deploy.sh
- file:
path: /opt/myapp/.deployed
state: touch
# Check marker before running
- stat:
path: /opt/myapp/.deployed
register: deployed
- command: /opt/post-deploy.sh
when: deployed.stat.existsMultiple Empty Files
- file:
path: "{{ item }}"
state: touch
mode: '0644'
loop:
- /var/log/myapp/access.log
- /var/log/myapp/error.log
- /var/log/myapp/debug.log
become: truetouch vs file state=file
# state=touch — creates file, updates mtime if exists
- file: { path: /tmp/test, state: touch }
# state=file — FAILS if file doesn't exist (only modifies existing)
- file: { path: /tmp/test, state: file, mode: '0644' }FAQ
Does touch update the modification time?
Yes — state: touch always updates mtime, even if the file exists. Use a stat check first to avoid this.
How to create an empty file with specific content later?
Use copy: content="" dest=/path force=false to create empty, then later copy: content="data" or template to fill it.
touch vs copy with empty content?
touch updates mtime every run (always "changed"). copy: content="" force=false only creates if missing (idempotent).
Create Empty File
- ansible.builtin.file:
path: /opt/myapp/.initialized
state: touch
become: trueWith Permissions
- file:
path: /opt/myapp/app.log
state: touch
mode: '0644'
owner: appuser
group: appgroup
become: trueCreate Only If Missing
- stat:
path: /opt/myapp/.initialized
register: flag
- file:
path: /opt/myapp/.initialized
state: touch
when: not flag.stat.exists
become: trueMultiple Empty Files
- file:
path: "{{ item }}"
state: touch
mode: '0644'
loop:
- /var/log/myapp/access.log
- /var/log/myapp/error.log
- /var/log/myapp/debug.log
become: trueFlag File Pattern
# Create flag after successful deployment
- name: Deploy application
unarchive:
src: /tmp/app.tar.gz
dest: /opt/myapp/
remote_src: true
become: true
- name: Create deployment flag
file:
path: /opt/myapp/.deployed
state: touch
become: true
# Later: check flag before running
- stat:
path: /opt/myapp/.deployed
register: deployed
- debug:
msg: "App is deployed"
when: deployed.stat.existstouch vs copy for Empty Files
# file + touch — creates empty file, updates timestamp if exists
- file:
path: /tmp/marker
state: touch
# copy + empty content — creates empty file, idempotent (no timestamp change)
- copy:
content: ""
dest: /tmp/marker
# copy with content — creates file with data
- copy:
content: "initialized\n"
dest: /tmp/markerModify Timestamp
# touch updates access and modification time
- file:
path: /opt/myapp/heartbeat
state: touch
modification_time: preserve # Don't change mtime
access_time: preserve # Don't change atimeFAQ
touch changes timestamp — is that a problem?
state: touch always reports changed because it updates the timestamp. If you only want to create (not update), check with stat first.
How to create a file with content?
Use copy module with content parameter instead of file + touch.
Can I create files in directories that don't exist?
No — parent directories must exist. Create them first with file: { path: ..., state: directory }.
Related Articles
- the ansible.builtin.file reference
- Windows fleet automation with Ansible
- Ansible Create Symlink: file Module with state=link (Guide)
See also
Category: installation
Watch the video: Ansible Create Empty File: Touch Files with file Module (Guide) — Video Tutorial