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.