Reputation: 5623
In my Ansible playbook many times i need to create a file:
- name: Copy file
template:
src: code.conf.j2
dest: "{{ project_root }}/conf/code.conf"
Many times conf
dir is not there. Then I have to create another task to create that dir first.
Is there any easy way to auto create the dir if it doesn't exist with some option?
Upvotes: 180
Views: 205356
Reputation: 333
To ensure success with a full path use recurse: true
:
- name: ensure custom facts directory exists
file:
path: /etc/ansible/facts.d
recurse: true
state: directory
Upvotes: 30
Reputation: 1187
If you are running Ansible >= 2.0 there is also the dirname filter you can use to extract the directory part of a path. That way you can just use one variable to hold the entire path to make sure both tasks never get out of sync.
So for example if you have playbook with dest_path
defined in a variable like this you can reuse the same variable:
---
- hosts: my_hosts
vars:
dest_path: /home/ubuntu/some_dir/some_file.txt
tasks:
- name: Make sure destination dir exists
file:
path: "{{ dest_path | dirname }}"
state: directory
# now this task is always save to run no matter how dest_path get's changed around
- name: Add file or template to remote instance
template:
src: foo.txt.j2
dest: "{{ dest_path }}"
Upvotes: 42
Reputation: 341
According to the latest document when state is set to be directory, you don't need to use parameter recurse to create parent directories, file module will take care of it.
- name: create directory with parent directories
file:
path: /data/test/foo
state: directory
This is fare enough to create the parent directories data and test with foo.
Please refer the parameter description - "state" of the file_module.
Upvotes: 24
Reputation: 2476
Right now, this is the only way:
- name: ensures {{ project_root }}/conf dir exists
file:
path: "{{ project_root }}/conf"
state: directory
- name: Copy file
template:
src: code.conf.j2
dest: "{{ project_root }}/conf/code.conf"
Upvotes: 181
Reputation: 10153
The question says "copy" but it then specifically ask for "template" file creation.
For using template:
, I believe a preceding step is required, as answered by many others here already.
But for copy:
however (plain copying over things, no templating) then you can do it in one instead of two steps, simply by copying the full directory instead an individual file:
- name: SBT repo configuration
copy:
src: files/.sbt/ # Copying the file `./files/.sbt/repositories`
dest: $HOME/.sbt/ # Works irrespective of whether the directory exists or not
Other files already present in $HOME/.sbt/
are unaffected.
Upvotes: -1
Reputation: 121
copy module creates the directory if it's not there. In this case it created the resolved.conf.d directory
- name: put fallback_dns.conf in place
copy:
src: fallback_dns.conf
dest: /etc/systemd/resolved.conf.d/
mode: '0644'
owner: root
group: root
become: true
tags: testing
Upvotes: -4
Reputation: 789
you can create the folder using the following depending on your ansible version.
Latest version 2<
- name: Create Folder
file:
path: "{{project_root}}/conf"
recurse: yes
state: directory
Older version:
- name: Create Folder
file:
path="{{project_root}}/conf"
recurse: yes
state=directory
Refer - http://docs.ansible.com/ansible/latest/file_module.html
Upvotes: 3
Reputation: 18279
AFAIK, the only way this could be done is by using the state=directory
option.
While template
module supports most of copy
options, which in turn supports most file
options, you can not use something like state=directory
with it. Moreover, it would be quite confusing (would it mean that {{project_root}}/conf/code.conf
is a directory ? or would it mean that {{project_root}}/conf/
should be created first.
So I don't think this is possible right now without adding a previous file
task.
- file:
path: "{{project_root}}/conf"
state: directory
recurse: yes
Upvotes: 10