What's the easy way to auto create non existing dir in ansible

Ansible

Ansible Problem Overview


In my Ansible playbook many times i need to create file there

 - name: Copy file
   template:
     src: code.conf.j2
     dest: "{{project_root}}/conf/code.conf"

now many times conf dir is not there. Then I have to create more task to create that dir first.

Is there any easy way to auto create dir if don't exist with some option

Ansible Solutions


Solution 1 - Ansible

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"

Solution 2 - Ansible

To ensure success with a full path use recurse=yes

- name: ensure custom facts directory exists
    file: >
      path=/etc/ansible/facts.d
      recurse=yes
      state=directory

Solution 3 - Ansible

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:

- name: My playbook
  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 arround
    - name: Add file or template to remote instance
      template: 
        src: foo.txt.j2
        dest: "{{ dest_path }}"

Solution 4 - Ansible

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" http://docs.ansible.com/ansible/latest/modules/file_module.html

Solution 5 - Ansible

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

Solution 6 - Ansible

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

Solution 7 - Ansible

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.

Solution 8 - Ansible

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1994660View Question on Stackoverflow
Solution 1 - AnsibleAlexander JardimView Answer on Stackoverflow
Solution 2 - AnsibleIan T PriceView Answer on Stackoverflow
Solution 3 - AnsibleStefan HorningView Answer on Stackoverflow
Solution 4 - AnsibleAlbyView Answer on Stackoverflow
Solution 5 - AnsibleleucosView Answer on Stackoverflow
Solution 6 - AnsibleChathuranga AbeyrathnaView Answer on Stackoverflow
Solution 7 - AnsibleconnyView Answer on Stackoverflow
Solution 8 - AnsiblePatrick BrunswyckView Answer on Stackoverflow