Como criar um arquivo vazio com Ansible?

115

Qual é a maneira mais fácil de criar um arquivo vazio usando o Ansible? Sei que posso salvar um arquivo vazio no filesdiretório e depois copiá-lo para o host remoto, mas acho isso um tanto insatisfatório.

Outra maneira é tocar em um arquivo no host remoto:

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

Mas então o arquivo é tocado todas as vezes, aparecendo como uma linha amarela no log, o que também é insatisfatório ...

Existe alguma solução melhor para este problema simples?

dokaspar
fonte

Respostas:

189

A documentação do módulo de arquivo diz

Se state=file, o arquivo NÃO será criado se ele não existir, consulte o módulo de cópia ou modelo se desejar esse comportamento.

Portanto, usamos o módulo de cópia, usando force=nopara criar um novo arquivo vazio apenas quando o arquivo ainda não existe (se o arquivo existir, seu conteúdo é preservado).

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

Esta é uma solução declarativa e elegante.

René Pijl
fonte
15
@ ÁkosVandra: Na verdade, não. Veja: force: no.
palacsint
Obrigado - esta é uma solução muito mais agradável do que file / touch ou a resposta stat / file aceita, e é fácil de fazer com "with_items"
Realista
Ótima resposta, estava curioso para saber como alguém criaria dois arquivos vazios usando a mesma construção que você forneceu?
Tasdik Rahman
Existe uma maneira de criar o diretório pai, se ele não existir, ou preciso fazer isso separadamente?
falsePockets de
Você precisa se certificar de que o diretório pai existe e é gravável. Veja stackoverflow.com/questions/22844905/…
René Pijl
37

Algo assim (usar o statmódulo primeiro para coletar dados sobre ele e, em seguida, filtrar usando uma condicional) deve funcionar:

- 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

Você também pode aproveitar a changed_whenfuncionalidade.

ceejayoz
fonte
20
talvez devesse ser: "when: not p.stat.exists"
piro
28

Outra opção, usando o módulo de comando:

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

O argumento 'cria' garante que esta ação não seja executada se o arquivo existir.

Leynos
fonte
5
Você deve evitar o comando tanto quanto possível, uma vez que não é idempotente. ryaneschinger.com/blog/…
redshark1802
4
@ redshark1802 Concordo. Embora neste caso, a tarefa seja idempotente, pois não será executada se "/ caminho / para / arquivo" já existir. Acho que a solução de René Pijl é a mais parecida com o Ansible das três principais respostas e, definitivamente, a que você deve usar se precisar definir propriedade, modo, etc.
Leynos
15

Com base na resposta aceita, se você deseja que as permissões do arquivo sejam verificadas em cada execução, e estas sejam alteradas de acordo se o arquivo existir, ou apenas crie o arquivo se ele não existir, você pode usar o seguinte:

- 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"}}
AllBlackt
fonte
3
Essa resposta é incrível por causa da flexibilidade que ela oferece na definição dos atributos de arquivo de um arquivo se ele não existir.
Dejay Clayton
10

file: path=/etc/nologin state=touch

Equivalente total do toque (novo no 1.4+) - use estatísticas se não quiser alterar o carimbo de data / hora do arquivo.

Jalmasi
fonte
3
Não é idempotente, a data do arquivo será modificada a cada execução do manual do ansible.
Jérôme B
3
@ Jérôme B Novo no Ansible 2.7: você pode torná-lo idempotente com file: path=/etc/nologin state=touch modification_time=preserve access_time=preserve.
GregV
8

O módulo de arquivo fornece uma maneira de tocar no arquivo sem modificar seu tempo.

- 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

Referência: https://docs.ansible.com/ansible/latest/modules/file_module.html

Ravi Kulkarni
fonte
Esta é a resposta correta para o ansible 2.7+, no entanto, essa informação importante está faltando nele.
Honza
3

Acontece que não tenho reputação suficiente para colocar isso como um comentário, o que seria um lugar mais apropriado para isso:

Ré. Resposta de AllBlackt, se você preferir o formato multilinha do Ansible, você precisa ajustar as citações state(eu gastei alguns minutos trabalhando nisso, então espero que isso acelere alguém),

- 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" }}'
Andrew Richards
fonte
0

Para criar um arquivo na máquina remota com o comando ad-hoc

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

Por favor corrija-me se eu estiver errado

vajrala chakradhar reddy
fonte
0

Alterado se o arquivo não existir. Crie um arquivo vazio.

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

Uma combinação de duas respostas, com um toque diferente. O código será detectado como alterado, quando o arquivo for criado ou a permissão atualizada.

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

e uma versão que também corrige o proprietário e o grupo e detecta como alterado quando corrige estes:

- 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
Roch Bourdon
fonte
ansible 2.7+ apenas - isso deve ser mencionado.
Honza