Come creare un file vuoto con Ansible?


115

Qual è il modo più semplice per creare un file vuoto utilizzando Ansible? So di poter salvare un file vuoto nella filesdirectory e quindi copiarlo sull'host remoto, ma lo trovo in qualche modo insoddisfacente.

Un altro modo è toccare un file sull'host remoto:

- name: create fake 'nologin' shell
  file: path=/etc/nologin state=touch owner=root group=sys mode=0555

Ma poi il file viene toccato ogni volta, presentandosi come una linea gialla nel registro, il che è anche insoddisfacente ...

Esiste una soluzione migliore a questo semplice problema?

Risposte:


189

La documentazione del modulo file dice

Se state=fileil file NON verrà creato se non esiste, vedere il modulo copia o modello se si desidera tale comportamento.

Quindi usiamo il modulo di copia, utilizzando force=noper creare un nuovo file vuoto solo quando il file non esiste ancora (se il file esiste, il suo contenuto viene preservato).

- name: ensure file exists
  copy:
    content: ""
    dest: /etc/nologin
    force: no
    group: sys
    owner: root
    mode: 0555

Questa è una soluzione dichiarativa ed elegante.


15
@ ÁkosVandra: In realtà non lo è. Vedi: force: no.
— palacsint

Grazie - questa è una soluzione molto più carina di file / touch o della risposta stat / file accettata, ed è facile da fare con "with_items"
— Realista

Ottima risposta, ero curioso di sapere come si potrebbero creare due file vuoti usando lo stesso costrutto che hai fornito?
— Tasdik Rahman

C'è un modo per fare in modo che questo crei la directory principale se non esiste, o devo farlo separatamente?
— falsePockets

È necessario assicurarsi che la directory principale esista e sia scrivibile. Vedi stackoverflow.com/questions/22844905/…
— René Pijl

37

Qualcosa di simile (usando statprima il modulo per raccogliere dati su di esso e poi filtrando usando un condizionale) dovrebbe funzionare:

- stat: path=/etc/nologin
  register: p

- name: create fake 'nologin' shell
  file: path=/etc/nologin state=touch owner=root group=sys mode=0555
  when: p.stat.exists is defined and not p.stat.exists

In alternativa potresti essere in grado di sfruttare la changed_whenfunzionalità.


20
forse dovrebbe essere: "quando: non p.stat.exists"
— piro

28

Un'altra opzione, utilizzando il modulo di comando:

- name: Create file
  command: touch /path/to/file
  args:
    creates: /path/to/file

L'argomento "crea" assicura che questa azione non venga eseguita se il file esiste.


5
Dovresti evitare il comando il più possibile poiché non è idempotente. ryaneschinger.com/blog/…
— redshark1802

4
@ redshark1802 d'accordo. Sebbene in questo caso, l'attività sia idempotente, poiché non verrà eseguita se "/ path / to / file" esiste già. Penso che la soluzione di René Pijl sia la più Ansible delle tre risposte principali, e sicuramente quella che dovresti usare se devi impostare proprietà, modalità, ecc.
— Leynos

15

Basandosi sulla risposta accettata, se si desidera che il file venga controllato per le autorizzazioni ad ogni esecuzione e queste vengano modificate di conseguenza se il file esiste, o semplicemente creare il file se non esiste, è possibile utilizzare quanto segue:

- stat: path=/etc/nologin
  register: p

- name: create fake 'nologin' shell
  file: path=/etc/nologin 
        owner=root
        group=sys
        mode=0555
        state={{ "file" if  p.stat.exists else "touch"}}

3
Questa risposta è fantastica per la flessibilità che ti offre nel definire gli attributi di file di un file se non esiste.
— Dejay Clayton

10

file: path=/etc/nologin state=touch

Equivalente completo del tocco (nuovo in 1.4+): usa stat se non vuoi cambiare il timestamp del file.


3
Non è idempotente, la data del file verrà modificata ad ogni esecuzione del playbook ansible.
— Jérôme B

3
@ Jérôme B Novità di Ansible 2.7: puoi renderlo idempotente con file: path=/etc/nologin state=touch modification_time=preserve access_time=preserve.
— GregV

8

Il modulo file fornisce un modo per toccare il file senza modificarne l'ora.

- name: Touch again the same file, but dont change times this makes the task idempotent
  file:
    path: /etc/foo.conf
    state: touch
    mode: u+rw,g-wx,o-rwx
    modification_time: preserve
    access_time: preserve

Riferimento: https://docs.ansible.com/ansible/latest/modules/file_module.html


Questa è la risposta corretta per ansible 2.7+, tuttavia mancano informazioni importanti.
— Honza

3

Risulta che non ho abbastanza reputazione per metterlo come commento, il che sarebbe un posto più appropriato per questo:

Ri. La risposta di AllBlackt, se preferisci il formato multilinea di Ansible, devi regolare la citazione per state(ho passato alcuni minuti a risolverlo, quindi spero che questo acceleri qualcun altro),

- stat:
    path: "/etc/nologin"
  register: p

- name: create fake 'nologin' shell
  file:
    path: "/etc/nologin"
    owner: root
    group: sys
    mode: 0555
    state: '{{ "file" if  p.stat.exists else "touch" }}'

0

Per creare un file nella macchina remota con il comando ad-hoc

ansible client -m file -a"dest=/tmp/file state=touch"

Perfavore, correggimi se sbaglio


0

Modificato se il file non esiste. Crea file vuoto.

- name: create fake 'nologin' shell
  file:
    path: /etc/nologin
    state: touch
  register: p
  changed_when: p.diff.before.state == "absent"

0

Una combinazione di due risposte, con una svolta. Il codice verrà rilevato come modificato, quando il file viene creato o l'autorizzazione viene aggiornata.

- name: Touch again the same file, but dont change times this makes the task idempotent
  file:
    path: /etc/foo.conf
    state: touch
    mode: 0644
    modification_time: preserve
    access_time: preserve
  changed_when: >
    p.diff.before.state == "absent" or
    p.diff.before.mode|default("0644") != "0644"

e una versione che corregge anche il proprietario e il gruppo e li rileva come modificati quando li corregge:

- name: Touch again the same file, but dont change times this makes the task idempotent
  file:
    path: /etc/foo.conf
    state: touch
    state: touch
    mode: 0644
    owner: root
    group: root
    modification_time: preserve
    access_time: preserve
  register: p
  changed_when: >
    p.diff.before.state == "absent" or
    p.diff.before.mode|default("0644") != "0644" or
    p.diff.before.owner|default(0) != 0 or
    p.diff.before.group|default(0) != 0

solo ansible 2.7+ - questo dovrebbe essere menzionato.
— Honza
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.