Ansible Create File with Content: Write Text to Files (Complete Guide)
By Luca Berton · Published 2024-01-01 · Category: database-automation
How to create files with content in Ansible. Use copy module content parameter, template module with Jinja2, lineinfile for single lines.
Ansible Create File with Content: Write Text to Files (Complete Guide)
Creating files with specific content is one of the most common Ansible tasks. Whether you need to write a configuration file, create a script, or generate a text file with dynamic content, this guide covers every approach.
See also: Ansible Move File: Relocate Files Between Directories (Complete Guide)
Method 1: copy Module with content Parameter (Simplest)
The fastest way to create a file with content on a remote host:
---
- name: Create files with content
hosts: all
tasks:
- name: Create a simple text file
ansible.builtin.copy:
content: "Hello from Ansible!"
dest: /tmp/greeting.txt
owner: root
group: root
mode: '0644'
Multi-Line Content
Use YAML literal block scalar (|) for multi-line content:
- name: Create a multi-line configuration file
ansible.builtin.copy:
content: |
# Application Configuration
app_name: myapp
debug: false
log_level: info
database:
host: localhost
port: 5432
name: myapp_db
dest: /etc/myapp/config.yml
owner: appuser
group: appuser
mode: '0640'
Create a Shell Script
- name: Create a backup script
ansible.builtin.copy:
content: |
#!/bin/bash
# Automated backup script
BACKUP_DIR="/var/backups/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
tar czf "$BACKUP_DIR/app-backup.tar.gz" /opt/app/data/
find /var/backups -type d -mtime +30 -exec rm -rf {} +
echo "Backup completed: $BACKUP_DIR"
dest: /usr/local/bin/backup.sh
owner: root
group: root
mode: '0755'
Method 2: template Module with Jinja2 (Dynamic Content)
For files with variables, loops, and conditionals:
Template file (templates/app.conf.j2):
# Generated by Ansible on {{ ansible_date_time.iso8601 }}
# Host: {{ inventory_hostname }}
[server]
listen_address = {{ app_listen_address | default('0.0.0.0') }}
port = {{ app_port }}
workers = {{ ansible_processor_vcpus * 2 }}
[database]
host = {{ db_host }}
port = {{ db_port | default(5432) }}
name = {{ db_name }}
{% for allowed_ip in allowed_ips %}
allow = {{ allowed_ip }}
{% endfor %}
Playbook:
---
- name: Deploy application config
hosts: app_servers
vars:
app_port: 8080
db_host: db.example.com
db_name: production
allowed_ips:
- 10.0.1.0/24
- 10.0.2.0/24
tasks:
- name: Create config from template
ansible.builtin.template:
src: app.conf.j2
dest: /etc/myapp/app.conf
owner: appuser
group: appuser
mode: '0640'
notify: restart app
See also: Ansible Write to File: Variable Content with copy & template Modules
Method 3: lineinfile for Single Lines
Add or modify a single line in an existing file:
- name: Ensure a line exists in a file
ansible.builtin.lineinfile:
path: /etc/environment
line: 'JAVA_HOME=/usr/lib/jvm/java-17-openjdk'
create: true
owner: root
group: root
mode: '0644'
Method 4: blockinfile for Text Blocks
Insert a managed block of text:
- name: Add SSH config block
ansible.builtin.blockinfile:
path: /etc/ssh/ssh_config
block: |
Host *.internal.example.com
ProxyJump bastion.example.com
User deploy
IdentityFile ~/.ssh/deploy_key
marker: "# {mark} ANSIBLE MANAGED - Internal SSH Config"
create: true
See also: Ansible Create File with Content: copy Module content Parameter
Method 5: Using Variables in copy content
Embed Ansible variables directly in the content parameter:
---
- name: Create file with dynamic content
hosts: all
vars:
app_version: "2.5.1"
environment: production
tasks:
- name: Create version file
ansible.builtin.copy:
content: |
Application: MyApp
Version: {{ app_version }}
Environment: {{ environment }}
Deployed: {{ ansible_date_time.iso8601 }}
Host: {{ inventory_hostname }}
OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
dest: /opt/app/VERSION
mode: '0644'
Method 6: Create JSON or YAML Files
- name: Create JSON config file
ansible.builtin.copy:
content: "{{ config_data | to_nice_json }}"
dest: /etc/app/config.json
mode: '0644'
vars:
config_data:
database:
host: localhost
port: 5432
cache:
enabled: true
ttl: 3600
Comparison: Which Method to Use
| Method | Best For | Dynamic Content | Idempotent |
|--------|----------|----------------|------------|
| copy + content | Simple text, scripts | ✅ Variables only | ✅ Yes |
| template | Complex configs, loops | ✅ Full Jinja2 | ✅ Yes |
| lineinfile | Single line changes | ✅ Regex + backrefs | ✅ Yes |
| blockinfile | Managed text blocks | ✅ Variables | ✅ Yes |
Common Mistakes
1. Missing Newline at End of File
# Content without trailing newline — may cause issues
content: "last_line=true"
# Better — YAML | block adds trailing newline automatically
content: |
last_line=true
2. Not Creating Parent Directories
# Ensure directory exists first
- ansible.builtin.file:
path: /opt/app/config
state: directory
mode: '0755'
- ansible.builtin.copy:
content: "setting=value"
dest: /opt/app/config/settings.ini
3. Forgetting to Set Permissions
Always specify owner, group, and mode for security:
- ansible.builtin.copy:
content: "SECRET_KEY={{ vault_secret_key }}"
dest: /etc/app/.env
owner: appuser
group: appuser
mode: '0600' # Only owner can read
FAQ
How do I create a file with content in Ansible?
Use ansible.builtin.copy with the content parameter. Set content to your text string and dest to the file path. Use YAML literal block scalar (|) for multi-line content.
What is the difference between copy content and template?
The copy module with content parameter is best for simple text with basic variable substitution. The template module uses Jinja2 and supports loops, conditionals, filters, and complex logic — use it for dynamic configuration files.
How do I write a variable to a file in Ansible?
Use ansible.builtin.copy with content: "{{ my_variable }}". For structured data, use content: "{{ my_dict | to_nice_json }}" or content: "{{ my_dict | to_nice_yaml }}".
Can I create a file only if it doesn't exist?
Use the force: false parameter with ansible.builtin.copy: force: false will not overwrite existing files. Alternatively, check with ansible.builtin.stat first.
How do I append content to an existing file?
Use ansible.builtin.lineinfile to add a single line, or ansible.builtin.blockinfile to add a managed block. The copy module always overwrites the entire file.
Conclusion
The copy module with content parameter is the simplest way to create files with content in Ansible. Use template for complex dynamic content, lineinfile for surgical single-line changes, and blockinfile for managed text blocks.
Related Articles
• Ansible Create File: Touch & Create Empty Files with file Module • Ansible lineinfile Module: Add, Replace & Delete Lines in Files • Ansible blockinfile Module: Insert & Manage Multi-Line Text Blocks • ansible.builtin.template Module: Jinja2 Templates Complete Guide • Ansible Move File: Relocate Files Between DirectoriesCategory: database-automation