Was ist der einfache Weg, um ein nicht vorhandenes Verzeichnis in ansible automatisch zu erstellen?


117

In meinem Ansible-Playbook muss ich dort oft eine Datei erstellen

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

jetzt ist confdir oft nicht da. Dann muss ich zuerst mehr Aufgaben erstellen, um dieses Verzeichnis zu erstellen.

Gibt es eine einfache Möglichkeit, ein Verzeichnis automatisch zu erstellen, wenn es keine Option gibt?



Ich kann nicht glauben, dass dies in Ansible 2.9 immer noch ein Problem ist. Wie schwierig wäre es für diese Module, einen Umschaltknopf für das Erstellungsverzeichnis zu haben, der standardmäßig deaktiviert ist. Es würde so viel Cruft in den Spielbüchern sparen, wenn man sich mit den Vortests wie den folgenden Antworten befassen müsste
krad

Antworten:


138

Im Moment ist dies der einzige Weg

- 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
Ich denke, hier ist sicher das richtige Wort. Versichern Sie: "Sagen Sie jemandem etwas Positives, um Zweifel auszuräumen", stellen Sie sicher: "Stellen Sie sicher, dass (etwas) eintreten wird oder der Fall ist".
Daniel Compton

Das scheint zu überprüfen, ob die Directorty existiert, aber es scheint sie nicht zu erstellen.
Matt

8
Sollte beachten , dass Sie hinzufügen möchten , recurse=yesum den fileAnruf zu bekommen mkdir -pTypen Verhalten
Mitch

1
Ein weiterer Teil des Puzzles, der hilfreich sein kann, ist der ansible-spezifische dirnameFilter , um das Verzeichnis abzurufen , das eine Datei enthält.
Caspar

1
@radtek Das Dateimodul macht es bereits mit state = directory. Es würde fehlschlagen, wenn nicht sichergestellt werden kann, dass der vorgeschlagene Dateipfad auf ein Verzeichnis verweist.
Alexander Jardim

20

Um den Erfolg mit einem vollständigen Pfad sicherzustellen, verwenden Sie recurse = yes

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

2
Gemäß der Dokumentation (und meinen Tests) werden die Unterverzeichnisse immer erstellt und recurse=yeswenden Berechtigungen nur rekursiv an. In der Dokumentation heißt es jedoch, dass dies seit Version 1.7 automatisch geschieht und daher recursemöglicherweise veraltet ist.
Bis zum

16

Wenn Sie Ansible> = 2.0 ausführen, gibt es auch den Verzeichnisnamenfilter, mit dem Sie den Verzeichnisteil eines Pfads extrahieren können. Auf diese Weise können Sie nur eine Variable verwenden, um den gesamten Pfad zu speichern und sicherzustellen, dass beide Aufgaben nie nicht mehr synchron sind.

Wenn Sie beispielsweise ein Playbook mit einer dest_pathin einer Variablen wie dieser definierten haben, können Sie dieselbe Variable wiederverwenden:

- 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
Obwohl diese Lösung noch ausführlich ist, denke ich, dass sie der Absicht des Autors am nächsten kommt. Ich würde es lieben , wenn es einen einfachen 'Makedirs'-Parameter wie Salt gäbe
lsh

7

AFAIK, der einzige Weg , dies könnte geschehen ist durch die Verwendung der state=directoryOption. Während das templateModul die meisten copyOptionen unterstützt, was wiederum die meisten fileOptionen unterstützt , können Sie so etwas nicht verwenden state=directory. Darüber hinaus wäre es ziemlich verwirrend (würde es bedeuten, dass {{project_root}}/conf/code.confes sich um ein Verzeichnis handelt? Oder würde es bedeuten, dass {{project_root}}/conf/es zuerst erstellt werden sollte.

Daher denke ich nicht, dass dies derzeit möglich ist, ohne eine vorherige fileAufgabe hinzuzufügen .

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

7

Laut dem neuesten Dokument, wenn der Status als Verzeichnis festgelegt ist, müssen Sie keine Parameterrekursion verwenden , um übergeordnete Verzeichnisse zu erstellen. Das Dateimodul kümmert sich darum.

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

Dies ist ausreichend, um die Daten der übergeordneten Verzeichnisse zu erstellen und mit foo zu testen

Bitte beziehen Sie sich auf die Parameterbeschreibung - " state " http://docs.ansible.com/ansible/latest/modules/file_module.html


Bitte fügen Sie hier die Lösung anstelle eines Links hinzu, der in Zukunft möglicherweise beschädigt wird.
Ignacio Ara

@IgnacioAra danke für den wertvollen Kommentar, ich habe Lösung hinzugefügt.
Alby


1

Das Kopiermodul erstellt das Verzeichnis, wenn es nicht vorhanden ist. In diesem Fall wurde das Verzeichnis resolve.conf.d erstellt

- 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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.