Quel est le moyen facile de créer automatiquement un répertoire non existant dans Ansible

117

Dans mon playbook Ansible plusieurs fois, j'ai besoin de créer un fichier là-bas

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

maintenant plusieurs fois confdir n'est pas là. Ensuite, je dois créer plus de tâches pour créer ce répertoire en premier.

Existe-t-il un moyen facile de créer automatiquement un répertoire s'il n'existe pas avec une option

user1994660
la source
Je ne peux pas croire que ce soit toujours un problème dans ansible 2.9. Quelle serait la difficulté pour ces modules d'avoir une bascule de création de répertoire, désactivée par défaut. Cela permettrait d'économiser tellement de cruauté dans les playbooks, de devoir faire face aux prétests comme les réponses ci
krad

Réponses:

139

En ce moment, c'est le seul moyen

- 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"
Alexandre Jardim
la source
2
Je pense que garantir est le mot correct ici. Assurez-vous: «dites quelque chose de positif à quelqu'un pour dissiper tout doute», assurez-vous: «assurez-vous que (quelque chose) se produira ou se produira».
Daniel Compton
Cela semble vérifier si le directorty existe, mais cela ne semble pas le créer.
Matt
8
Veuillez noter que vous voudrez peut-être ajouter recurse=yesà l' fileappel pour obtenir le mkdir -pcomportement de type
Mitch
1
Une autre pièce du puzzle qui peut être utile est le filtre spécifiquedirname à ansible pour obtenir le répertoire qui contient un fichier.
Caspar
1
@radtek le module de fichiers le fait déjà avec state = directory. Il échouerait s'il n'est pas possible de garantir que le chemin du fichier proposé pointe vers un répertoire.
Alexander Jardim
21

Pour garantir le succès avec un chemin complet, utilisez recurse = yes

- name: ensure custom facts directory exists
    file: >
      path=/etc/ansible/facts.d
      recurse=yes
      state=directory
Prix ​​Ian T
la source
2
D'après la documentation (et mes tests), les sous-répertoires sont toujours créés, et recurse=yesn'appliquent les autorisations que de manière récursive. Cependant, la documentation indique que cela se produit automatiquement depuis la v1.7, donc recursepourrait bien être obsolète.
Au 마 SE
16

Si vous exécutez Ansible> = 2.0, vous pouvez également utiliser le filtre de nom de répertoire pour extraire la partie répertoire d'un chemin. De cette façon, vous pouvez simplement utiliser une variable pour contenir le chemin complet afin de vous assurer que les deux tâches ne se désynchronisent jamais.

Donc, par exemple, si vous avez un playbook avec dest_pathdéfini dans une variable comme celle-ci, vous pouvez réutiliser la même 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
        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 }}"
Stefan Horning
la source
1
bien que cette solution soit encore verbeuse, je pense qu'elle est la plus proche de l'intention de l'auteur. Je l' aime s'il y avait d' un simple paramètre 'makedirs de type sel a: docs.saltstack.com/en/latest/ref/states/all/...
LSH
7

Autant que je sache, la seule façon pourrait être fait est en utilisant l' state=directoryoption. Bien que le templatemodule prenne en charge la plupart des copyoptions, qui à leur tour prennent en charge la plupart des fileoptions, vous ne pouvez pas utiliser quelque chose comme state=directoryavec lui. De plus, ce serait assez déroutant (cela signifierait-il qu'il {{project_root}}/conf/code.confs'agit d'un répertoire? Ou cela signifierait-il qu'il {{project_root}}/conf/devrait être créé en premier.

Je ne pense donc pas que cela soit possible pour le moment sans ajouter une filetâche précédente .

- file: 
    path: "{{project_root}}/conf"
    state: directory
    recurse: yes
leucos
la source
7

Selon le dernier document lorsque l'état est défini sur répertoire, vous n'avez pas besoin d'utiliser le paramètre recurse pour créer des répertoires parents, le module de fichiers s'en chargera.

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

c'est assez pour créer les données des répertoires parents et tester avec foo

veuillez vous référer à la description des paramètres - " state " http://docs.ansible.com/ansible/latest/modules/file_module.html

Alby
la source
Veuillez ajouter ici la solution au lieu d'un lien qui pourrait être rompu à l'avenir.
Ignacio Ara
@IgnacioAra merci pour le précieux commentaire, j'ai ajouté une solution.
Alby
1

vous pouvez créer le dossier en utilisant ce qui suit en fonction de votre version ansible.

Dernière version 2 <

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

Ancienne version:

- name: Create Folder
  file: 
      path="{{project_root}}/conf"
      recurse: yes
      state=directory

Consulter - http://docs.ansible.com/ansible/latest/file_module.html

Chathuranga Abeyrathna
la source
1

Le module de copie crée le répertoire s'il n'y est pas. Dans ce cas, il a créé le répertoire résolu.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
Patrick Brunswyck
la source