Qual è il modo più semplice per creare automaticamente directory non esistenti in ansible


117

Nel mio playbook Ansible molte volte ho bisogno di creare file lì

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

ora molte volte confdir non c'è. Quindi devo creare più attività per creare prima quella directory.

C'è un modo semplice per creare automaticamente una directory se non esiste con qualche opzione



Non posso credere che questo sia ancora un problema in ansible 2.9. Quanto sarebbe difficile per questi moduli avere un interruttore per la creazione della directory, disattivato di default. Risparmierebbe così tanto cruft nei playbook, dovendo affrontare i pretest come le risposte di seguito
krad

Risposte:


139

In questo momento, questo è l'unico modo

- 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"

2
Penso che qui sia la parola corretta. Assicurare: "dire a qualcuno qualcosa di positivo per fugare ogni dubbio", assicurarsi: "assicurarsi che (qualcosa) accadrà o accadrà".
Daniel Compton

Questo sembra controllare se la directory esiste, ma non sembra crearla.
Matt

8
Tieni presente che potresti voler aggiungere recurse=yesalla filechiamata per ottenere il mkdir -pcomportamento del tipo
Mitch

1
Un altro pezzo del puzzle che può essere utile è il filtro specifico ansibledirname per ottenere la directory che contiene un file.
Caspar

1
@radtek il modulo file lo fa già con state = directory. Fallirebbe se non fosse possibile garantire che il percorso del file proposto punti a una directory.
Alexander Jardim

21

Per garantire il successo con un percorso completo, utilizzare recurse = yes

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

2
Secondo la documentazione (e i miei test), le sottodirectory vengono sempre create e recurse=yesapplica solo i permessi in modo ricorsivo. Tuttavia, la documentazione afferma che ciò avviene automaticamente dalla v1.7, quindi recursepotrebbe essere obsoleto.
A 마 SE

16

Se stai usando Ansible> = 2.0, c'è anche il filtro dirname che puoi usare per estrarre la parte directory di un percorso. In questo modo puoi usare solo una variabile per mantenere l'intero percorso per assicurarti che entrambe le attività non vadano mai fuori sincrono.

Quindi, ad esempio, se hai un playbook dest_pathdefinito in una variabile come questa puoi riutilizzare la stessa variabile:

- 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
        recurse: yes

    # 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 }}"

1
sebbene questa soluzione sia ancora prolissa, penso che sia la più vicina all'intento dell'autore. Mi piace che se ci fosse un semplice parametro 'makedirs' come sale ha: docs.saltstack.com/en/latest/ref/states/all/...
LSH

7

Per quanto ne so, l'unico modo in cui questo potrebbe essere fatto è quello di utilizzare l' state=directoryopzione. Mentre il templatemodulo supporta la maggior parte delle copyopzioni, che a sua volta supporta la maggior parte delle fileopzioni, non puoi usare qualcosa di simile state=directorycon esso. Inoltre, sarebbe abbastanza confuso (significherebbe che {{project_root}}/conf/code.confè una directory? O significherebbe che {{project_root}}/conf/dovrebbe essere creata prima.

Quindi non penso che questo sia possibile in questo momento senza aggiungere un'attività precedente file.

- file: 
    path: "{{project_root}}/conf"
    state: directory
    recurse: yes

7

Secondo l'ultimo documento, quando lo stato è impostato su directory, non è necessario utilizzare il parametro recurse per creare directory padre, il modulo file se ne occuperà.

- name: create directory with parent directories
  file:
    path: /data/test/foo
    state: directory

questo è abbastanza per creare i dati delle directory principali e testare con pippo

fare riferimento alla descrizione dei parametri - " state " http://docs.ansible.com/ansible/latest/modules/file_module.html


Si prega di aggiungere qui la soluzione invece di un collegamento che potrebbe essere interrotto in futuro.
Ignacio Ara

@IgnacioAra grazie per il prezioso commento, ho aggiunto la soluzione.
Alby


1

Il modulo copy crea la directory se non è presente. In questo caso ha creato la directory resolved.conf.d

- 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.