Qual é a maneira fácil de criar automaticamente um diretório não existente no ansible


117

Muitas vezes, no meu manual do Ansible, preciso criar um arquivo

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

agora, muitas vezes, confdir não está lá. Então eu tenho que criar mais tarefas para criar esse diretório primeiro.

Existe alguma maneira fácil de criar diretório automaticamente se não existir com alguma opção



Não posso acreditar que isso ainda seja um problema no ansible 2.9. Seria muito difícil para esses módulos ter um botão de alternância de criação de dir, desativado por padrão. Isso economizaria muito lixo nos manuais, tendo que lidar com os pré-testes como as respostas abaixo
krad

Respostas:


139

No momento, esta é a única maneira

- 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
Acho que garantir é a palavra correta aqui. Assegure: "diga algo positivamente a alguém para dissipar quaisquer dúvidas", assegure: "certifique-se de que (algo) ocorrerá ou será o caso".
Daniel Compton

Isso parece verificar se o directorty existe, mas não parece criá-lo.
Matt

8
Você pode querer adicionar recurse=yeso comportamento de tipo fileà chamada para obtermkdir -p
Mitch

1
Outra peça do quebra-cabeça que pode ser útil é o filtro específicodirname do ansible para obter o diretório que contém o arquivo.
Caspar

1
@radtek o módulo de arquivo já faz isso com state = directory. Ele falhará se não for possível garantir que o caminho do arquivo proposto aponte para um diretório.
Alexander Jardim

21

Para garantir o sucesso com um caminho completo, use recurse = yes

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

2
De acordo com a documentação (e meus testes), os subdiretórios são sempre criados e recurse=yessó aplicam as permissões recursivamente. No entanto, a documentação afirma que isso acontece automaticamente desde a v1.7, portanto, recursepode estar obsoleto.
Para 마 SE

16

Se você estiver executando Ansible> = 2.0, há também o filtro dirname que pode ser usado para extrair a parte do diretório de um caminho. Dessa forma, você pode usar apenas uma variável para conter todo o caminho e garantir que as duas tarefas nunca saiam de sincronia.

Então, por exemplo, se você tiver o manual dest_pathdefinido em uma variável como esta, você pode reutilizar a mesma variável:

- 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
embora esta solução ainda seja prolixa, acho que é a mais próxima da intenção do autor. Eu adoraria se houvesse um parâmetro 'makedirs' simples como o Salt tem: docs.saltstack.com/en/latest/ref/states/all/…
lsh

7

AFAIK, a única maneira que isso poderia ser feito é usando a state=directoryopção. Embora o templatemódulo suporte a maioria das copyopções, que por sua vez oferece suporte à maioria das fileopções, você não pode usar algo semelhante state=directorycom ele. Além disso, seria bastante confuso (significaria que {{project_root}}/conf/code.confé um diretório? Ou significaria que {{project_root}}/conf/deveria ser criado primeiro.

Portanto, não acho que isso seja possível agora sem adicionar uma filetarefa anterior .

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

7

De acordo com o documento mais recente, quando o estado é definido como diretório, você não precisa usar o parâmetro recurse para criar diretórios pais, o módulo de arquivo cuidará disso.

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

isso é fácil o suficiente para criar os dados do diretório pai e testar com foo

consulte a descrição do parâmetro - " estado " http://docs.ansible.com/ansible/latest/modules/file_module.html


Adicione aqui a solução em vez de um link que pode ser quebrado no futuro.
Ignacio Ara

@IgnacioAra obrigado pelo valioso comentário, eu adicionei solução.
Alby


1

o módulo de cópia cria o diretório se não estiver lá. Neste caso, ele criou o diretório resolvido.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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.