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 Create File with Content: copy Module content Parameter

By Luca Berton · Published 2024-01-01 · Category: linux-administration

How to create files with content in Ansible using the copy module content parameter. Write text, YAML, JSON to files without templates.

Ansible Create File with Content: copy Module content Parameter

I'm going to show you a live Playbook with some simple Ansible code. I'm Luca Berton and welcome to today's episode of Ansible Pilot.

Ansible create a text file

Today we're talking about Ansible module copy. The full name is ansible.builtin.copy which means is part of the collection of modules "builtin" with ansible and shipped with it. This module is pretty stable and out for years. The purpose is to copy files to remote locations but it's also capable to create some simple text files. If you need a more complex configuration it's better to rely on the template module.

See also: Ansible Create Empty File: Touch Files with file Module (Guide)

Parameters

• dest path - destination file • content string - text • mode/owner/group - permission • setype/seuser/selevel - SELinux

The parameter list is pretty wide but I'll summarize the most useful for the use case. The only required parameter is "dest" which specifies the remote absolute path destination. The content parameter sets the contents of a file directly to the specified value. It works only when dest is a file/ Please note that if you use a variable in the content parameter will result in unpredictable output. For advanced formatting or if the content contains a variable, use the ansible.builtin.template module. Let me also highlight that we could also specify the permissions and SELinux properties.

## Playbook Let's jump into a real-life playbook on how to create an empty file with Ansible.

code

• copy.yml
---
- name: copy module Playbook
  hosts: all
  vars:
    myfile: "{{ ~/example.txt }}"
  tasks:
  - name: create a text file
    ansible.builtin.copy:
      dest: "{{ myfile }}"
      content: |
        line 1
        line 2

code with ❤️ in GitHub

Conclusion

Now you know better how to create a text file with Ansible.

See also: Ansible Rename File: Move & Rename Files with copy + file Modules

Advanced copy Module Examples

Write multi-line content

- name: Create config file with multiple lines
  ansible.builtin.copy:
    content: |
      [database]
      host = db.example.com
      port = 5432
      name = myapp
      user = {{ db_user }}
      password = {{ db_password }}
    dest: /etc/myapp/database.conf
    owner: appuser
    group: appuser
    mode: '0600'
  become: true

Write variable content to file

- name: Gather system info
  ansible.builtin.setup:
    gather_subset: network

- name: Save IP address to file ansible.builtin.copy: content: "{{ ansible_default_ipv4.address }}" dest: /etc/myapp/server_ip.txt mode: '0644'

Copy file from controller to remote

- name: Copy local file to remote host
  ansible.builtin.copy:
    src: files/nginx.conf
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'
    backup: true  # Create backup of existing file
  become: true
  notify: restart nginx

Create file only if it doesn't exist

- name: Create default config (don't overwrite)
  ansible.builtin.copy:
    content: |
      # Default configuration
      debug: false
      log_level: info
    dest: /etc/myapp/config.yml
    force: false  # Don't overwrite if file exists
    mode: '0644'
  become: true

Save command output to file

- name: Run diagnostic command
  ansible.builtin.command: df -h
  register: disk_info
  changed_when: false

- name: Save output to file ansible.builtin.copy: content: "{{ disk_info.stdout }}" dest: /tmp/disk_report.txt mode: '0644'

copy vs template vs lineinfile

| Module | Best For | |--------|----------| | copy (content=) | Static text, simple variable substitution | | copy (src=) | Copying files from controller | | template | Complex Jinja2 templates with loops/conditions | | lineinfile | Modifying a single line in existing files | | blockinfile | Adding/replacing a block in existing files |

See also: Ansible Create Symlink: file Module with state=link (Guide)

Key Parameters

| Parameter | Type | Description | |-----------|------|-------------| | content | string | Text content to write | | src | string | Local file to copy | | dest | string | Remote destination path | | mode | string | File permissions (e.g., '0644') | | owner | string | File owner | | group | string | File group | | force | bool | Overwrite if exists (default: true) | | backup | bool | Create backup before overwriting | | validate | string | Command to validate before replacing |

FAQ

How do I write JSON content to a file?

- name: Write JSON config
  ansible.builtin.copy:
    content: "{{ my_dict | to_nice_json }}"
    dest: /etc/myapp/config.json
    mode: '0644'

How do I append to a file instead of overwriting?

copy always overwrites. Use lineinfile or blockinfile to add content, or use shell:

- name: Append line to file
  ansible.builtin.lineinfile:
    path: /etc/myapp/app.log
    line: "Deployed at {{ ansible_date_time.iso8601 }}"
    create: true

What's the maximum content size for copy?

There's no hard limit, but for large files (>1MB), use src instead of content for better performance. For templates with complex logic, use the template module.

Create File with Content

- name: Create config file
  ansible.builtin.copy:
    content: |
      # Application Config
      DB_HOST=db.internal
      DB_PORT=5432
      LOG_LEVEL=info
    dest: /etc/myapp/.env
    owner: deploy
    group: deploy
    mode: '0600'
  become: true

Copy from Controller

- copy:
    src: files/nginx.conf
    dest: /etc/nginx/nginx.conf
    owner: root
    mode: '0644'
    backup: true  # Keep backup of original
  become: true
  notify: restart nginx

Copy with Variables

- copy:
    content: |
      APP_NAME={{ app_name }}
      APP_PORT={{ app_port }}
      APP_ENV={{ env }}
      DB_HOST={{ db_host }}
    dest: /opt/myapp/.env
    mode: '0600'
  become: true

Copy Multiple Files

- copy:
    src: "{{ item.src }}"
    dest: "{{ item.dest }}"
    mode: "{{ item.mode | default('0644') }}"
  loop:
    - { src: app.conf, dest: /etc/myapp/app.conf }
    - { src: logging.conf, dest: /etc/myapp/logging.conf }
    - { src: deploy.sh, dest: /opt/scripts/deploy.sh, mode: '0755' }
  become: true

Create JSON File

- copy:
    content: "{{ config_data | to_nice_json }}"
    dest: /etc/myapp/config.json
    mode: '0644'
  become: true

Create YAML File

- copy:
    content: "{{ config_data | to_nice_yaml }}"
    dest: /etc/myapp/config.yml
    mode: '0644'
  become: true

Backup Before Overwrite

- copy:
    src: new-config.conf
    dest: /etc/myapp/config.conf
    backup: true  # Creates timestamped backup
  become: true

Remote to Remote Copy

- copy:
    src: /opt/myapp/config.yml
    dest: /opt/myapp/config.yml.bak
    remote_src: true
  become: true

copy vs template

| Feature | copy | template | |---------|------|----------| | Static files | ✅ | ✅ | | Jinja2 processing | ❌ | ✅ | | Inline content | ✅ (content:) | ❌ | | Variable substitution | Limited | Full | | Loops/conditionals | ❌ | ✅ |

Key Parameters

| Parameter | Description | |-----------|-------------| | src | Source file on controller | | dest | Destination path on remote | | content | Inline file content | | owner | File owner | | group | File group | | mode | File permissions | | backup | Create backup before overwrite | | remote_src | Source is on remote host | | force | Overwrite if different (default: true) | | validate | Command to validate before placing |

FAQ

copy vs template for config files?

Use copy for static files or inline content: with simple variable substitution. Use template when you need Jinja2 logic (loops, conditionals).

How do I avoid overwriting a file?

- copy:
    content: "initial content"
    dest: /etc/myapp/config
    force: false  # Don't overwrite if exists

Can I copy a directory?

Yes — if src is a directory (with trailing /), copy transfers all contents. Without trailing /, it copies the directory itself.

Related Articles

Jinja2 templating in Ansiblerole-based playbook organization in Ansible

Category: linux-administration

Watch the video: Ansible Create File with Content: copy Module content Parameter — Video Tutorial

Browse all Ansible tutorials · AnsiblePilot Home