¿Cuál es la manera fácil de crear automáticamente un directorio no existente en ansible?


117

En mi libro de jugadas de Ansible muchas veces necesito crear un archivo allí

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

ahora muchas veces confdir no está ahí. Entonces tengo que crear más tareas para crear ese directorio primero.

¿Hay alguna manera fácil de crear automáticamente un directorio si no existe con alguna opción?



No puedo creer que esto siga siendo un problema en ansible 2.9. ¿Qué tan difícil sería para estos módulos tener un conmutador de creación de directorio, predeterminado en desactivado? Ahorraría mucho dinero en los libros de jugadas, tener que lidiar con las pruebas preliminares como las respuestas a continuación
krad

Respuestas:


139

Ahora mismo, esta es la única forma

- 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
Creo que asegurar es la palabra correcta aquí. Asegurar: "decirle a alguien algo de manera positiva para disipar cualquier duda", asegurar: "asegurarse de que (algo) ocurrirá o será el caso".
Daniel Compton

Eso parece comprobar si existe el directorio, pero no parece crearlo.
Matt

8
Debe tener en cuenta que es posible que desee agregar recurse=yesa la filellamada para obtener el mkdir -pcomportamiento de tipo
Mitch

1
Otra pieza del rompecabezas que puede ser útil es el filtro específico de ansibledirname para obtener el directorio que contiene un archivo.
Caspar

1
@radtek el módulo de archivo ya lo hace con state = directory. Fallaría si no es posible asegurarse de que la ruta de archivo propuesta apunte a un directorio.
Alexander Jardim

21

Para garantizar el éxito con una ruta completa, use recurse = yes

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

2
Según la documentación (y mis pruebas), los subdirectorios siempre se crean y recurse=yessolo aplican permisos de forma recursiva. Sin embargo, la documentación indica que esto ocurre automáticamente desde la v1.7, por lo recurseque bien podría estar obsoleto.
Hasta el SE

16

Si está ejecutando Ansible> = 2.0, también existe el filtro de nombre de directorio que puede usar para extraer la parte del directorio de una ruta. De esa manera, solo puede usar una variable para mantener la ruta completa y asegurarse de que ambas tareas nunca se desincronicen.

Entonces, por ejemplo, si tiene un libro de jugadas dest_pathdefinido en una variable como esta, puede reutilizar la misma 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 }}"

1
Si bien esta solución aún es detallada, creo que está más cerca de la intención del autor. Me encantaría si hubiera un parámetro simple 'makedirs' como Salt tiene: docs.saltstack.com/en/latest/ref/states/all/…
lsh

7

AFAIK, la única forma en que esto podría hacerse es usando la state=directoryopción. Si bien el templatemódulo admite la mayoría de las copyopciones, que a su vez admite la mayoría de las fileopciones, no puede usar algo así state=directory. Además, sería bastante confuso (¿significaría que {{project_root}}/conf/code.confes un directorio? O significaría que{{project_root}}/conf/ debería crearse primero.

Entonces, no creo que esto sea posible ahora sin agregar una filetarea anterior .

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

7

De acuerdo con el último documento, cuando el estado está configurado como directorio, no necesita usar el parámetro recurse para crear directorios principales, el módulo de archivo se encargará de ello.

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

esto es suficiente para crear los datos del directorio principal y probar con foo

consulte la descripción del parámetro - " estado " http://docs.ansible.com/ansible/latest/modules/file_module.html


Agregue aquí la solución en lugar de un vínculo que podría romperse en el futuro.
Ignacio Ara

@IgnacioAra gracias por el valioso comentario, he agregado solución.
Alby


1

El módulo de copia crea el directorio si no está allí. En este caso creó el directorio resuelto.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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.