Comment créer un fichier vide avec Ansible?


115

Quelle est la manière la plus simple de créer un fichier vide à l'aide d'Ansible? Je sais que je peux enregistrer un fichier vide dans le filesrépertoire, puis le copier sur l'hôte distant, mais je trouve cela quelque peu insatisfaisant.

Une autre façon consiste à toucher un fichier sur l'hôte distant:

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

Mais ensuite, le fichier est touché à chaque fois, apparaissant comme une ligne jaune dans le journal, ce qui est également insatisfaisant ...

Y a-t-il une meilleure solution à ce problème simple?

Réponses:


189

La documentation du module de fichiers dit

Si state=file, le fichier ne sera PAS créé s'il n'existe pas, consultez le module de copie ou de modèle si vous souhaitez ce comportement.

Nous utilisons donc le module de copie, qui permet force=node créer un nouveau fichier vide uniquement lorsque le fichier n'existe pas encore (si le fichier existe, son contenu est conservé).

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

C'est une solution déclarative et élégante.


15
@ ÁkosVandra: En fait, ce n'est pas le cas. Voir: force: no.
palacsint

Merci - c'est une solution beaucoup plus agréable que file / touch ou la réponse stat / file acceptée, et c'est facile à faire avec "with_items"
Réaliste

Excellente réponse, vous êtes curieux de savoir comment créer deux fichiers vides en utilisant la même construction que vous avez fournie?
Tasdik Rahman

Existe-t-il un moyen de créer le répertoire parent s'il n'existe pas, ou dois-je le faire séparément?
falsePockets

Vous devez vous assurer que le répertoire parent existe et qu'il est accessible en écriture. Voir stackoverflow.com/questions/22844905/…
René Pijl

37

Quelque chose comme ça (en utilisant d'abord le statmodule pour collecter des données à ce sujet, puis en filtrant à l'aide d'un conditionnel) devrait fonctionner:

- 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

Vous pourriez également être en mesure de tirer parti de la changed_whenfonctionnalité.


20
peut-être que ça devrait être: "quand: pas p.stat.exists"
piro

28

Une autre option, en utilisant le module de commande:

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

L'argument «crée» garantit que cette action n'est pas effectuée si le fichier existe.


5
Vous devez éviter la commande autant que possible car elle n'est pas idempotente. ryaneschinger.com/blog/…
redshark1802

4
@ redshark1802 D'accord. Bien que dans ce cas, la tâche soit idempotente, puisqu'elle ne sera pas exécutée si "/ chemin / vers / fichier" existe déjà. Je pense que la solution de René Pijl est la plus semblable à Ansible des trois principales réponses, et certainement celle que vous devriez utiliser si vous devez définir la propriété, le mode, etc.
Leynos

15

En vous basant sur la réponse acceptée, si vous souhaitez que le fichier soit vérifié pour les autorisations à chaque exécution, et que celles-ci soient modifiées en conséquence si le fichier existe, ou créez simplement le fichier s'il n'existe pas, vous pouvez utiliser ce qui suit:

- 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
Cette réponse est géniale en raison de la flexibilité qu'elle vous donne dans la définition des attributs de fichier d'un fichier s'il n'existe pas.
Dejay Clayton

10

file: path=/etc/nologin state=touch

Equivalent complet de touch (nouveau dans 1.4+) - utilisez stat si vous ne voulez pas changer l'horodatage du fichier.


3
Ce n'est pas idempotent, la date du fichier sera modifiée à chaque exécution du playbook ansible.
Jérôme B

3
@ Jérôme B Nouveau dans Ansible 2.7: vous pouvez le rendre idempotent avec file: path=/etc/nologin state=touch modification_time=preserve access_time=preserve.
GregV

8

Le module de fichiers permet de toucher le fichier sans modifier son heure.

- 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

Référence: https://docs.ansible.com/ansible/latest/modules/file_module.html


C'est la bonne réponse pour ansible 2.7+, mais il manque des informations importantes.
Honza

3

Il s'avère que je n'ai pas assez de réputation pour mettre cela en commentaire, ce qui serait un endroit plus approprié pour cela:

Ré. Réponse d'AllBlackt, si vous préférez le format multiligne d'Ansible, vous devez ajuster les citations state(j'ai passé quelques minutes à travailler sur cela, alors j'espère que cela accélère quelqu'un d'autre),

- 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

Pour créer un fichier dans la machine distante avec la commande ad-hoc

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

S'il vous plait corrigez moi si je me trompe


0

Modifié si le fichier n'existe pas. Créez un fichier vide.

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

0

Une combinaison de deux réponses, avec une torsion. Le code sera détecté comme modifié, lorsque le fichier est créé ou l'autorisation mise à jour.

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

et une version qui corrige également le propriétaire et le groupe et le détecte comme modifié lorsqu'il corrige ces derniers:

- 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

ansible 2.7+ uniquement - cela devrait être mentionné.
Honza
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.