Módulo Ansible Copiar e tornar-se - Permissão negada

Módulo Ansible Copiar e tornar-se - Permissão negada

Estou executando um script ansible localhostpara copiar uma pasta para outro local. No entanto,

- name: Copy Network
  become: yes
  become_user: root
  copy:
    src: /d/
    dest: "/dest/d/"
    mode: 0644
  tags: [network]

está me dando [Errno 13] Permission denied: b'd/f1'. Eu esperava become_userque o comando fosse executado como root, não funcionou. A permissão deste arquivo é 0600(root:root).

Você pode me dar dicas para obter acesso a este arquivo e copiá-lo usando ansible?

Observação:

  • sudo ansible-playbook p.ymlfunciona perfeitamente, no entanto, não quero usar sudoo comando ansible se não for necessário e o ansible tiver um truque para isso.

  • command: cp -r /d/ /dest/d/funciona sem anexar sudoao comando ansible ( ansible-playbook p.yml). No entanto, não quero usar commandse puder ajudar por causa da idempotência e copyo módulo tem modea opção necessária para a tarefa.

Responder1

Atualização: Se você puder escalar o privilégio para root no localhost master, a solução é definir remote_src: true(crédito @ivandov)

- copy:
    src: /d/
    dest: /dest/d/
    mode: '0644'
    remote_src: true
  become: true
  become_user: root

Os detalhes abaixo descrevem o caso em que você não consegue escalar para root no host local. Dado o arquivo em localhost

shell> ll /tmp/test/d/f1
-rw-r----- 1 root root 0 Aug 25 23:23 /tmp/test/d/f1

o módulocópia defunciona como esperado

- copy:
    src: /tmp/test/d/
    dest: /tmp/test/dest/
  become: true
  become_user: root

Primeiro, ele tenta ler o arquivo e falha

fatal: [localhost]: FALHA! => msg: 'ocorreu um erro ao tentar ler o arquivo ''/tmp/test/d/f1'': [Erro 13] Permissão negada: b''/tmp/test/d/f1''. [Errno 13] Permissão negada: b''/tmp/test/d/f1'''

Por padrão, módulocópia decopia arquivos defonte(caminho local para um arquivo a ser copiado para o servidor remoto) paradestino(caminho absoluto remoto para onde o arquivo deve ser copiado). Nesse caso, become: truesignifica que o Ansible escala privilégios no host remoto, mas não no host local mestre. Apesar de a tarefa estar sendo executada em localhost, ou seja, tanto o host mestre quanto o host remoto são localhost, sem remote_src: truea configuração become: truese aplica apenas à gravação do arquivo e não à sua leitura. Se você não conseguir escalar para root na configuração localhostremote_src: true

- copy:
    src: /tmp/test/d/
    dest: /tmp/test/dest/
    remote_src: true
  become: true
  become_user: root

vai falhar

fatal: [localhost]: FALHA! => alterado = falso ansible_facts:discovered_interpreter_python: /usr/bin/python3 module_stderr: |- sudo: uma senha é necessária module_stdout: '' msg: |- MODULE FAILURE Consulte stdout/stderr para obter o erro exato rc: 1


P:"Existe alguma solução alternativa para isso?"

R: Sem o escalonamento para a raiz, não há solução alternativa. Isso violaria a propriedade e as permissões dos arquivos. Por exemplo, dado o arquivo no controlador

shell> ll f1
-rw-rw---- 1 root root 0 Sep 13 18:17 f1

O manual abaixo foi iniciado por um usuário sem privilégios

shell> cat playbook.yml
- hosts: test_01
  become: true
  tasks:
    - copy:
        src: f1
        dest: /tmp

vai falhar

TASK [copy] ****
fatal: [test_01]: FAILED! => 
  msg: 'an error occurred while trying to read the file ''/scratch/f1'':
       [Errno 13] Permission denied: b''/scratch/f1'''

Se você não conseguir escalar para root no mestre localhost, a solução é tornar o arquivo legível para o usuário que executa o manual.

Responder2

Com base na resposta de Vladimir, EXISTE uma solução alternativa simples!

O comentário abaixo (e a ênfase que adicionei em negrito) foi a chave.

Na cópia do módulo, torne-se: sim aplica-se apenas à gravação do arquivonão para ler.

Basta usar remote_src: true, mesmo que você esteja copiando o arquivo localmente. Isso faz com que o becomeprivilégio seja escalonado corretamente ao ler o srcarquivo/diretório da máquina local porque ele o trata srccomo uma máquina remota e aplica corretamente o escalonamento de privilégios.

- name: Copy Network
  become: yes
  become_user: root
  copy:
    src: /d/
    dest: "/dest/d/"
    remote_src: true  # this allows become to work as expected
    mode: 0644
  tags: [network]

Responder3

dr - O Ansible become: rootse aplica à máquina de destino, não ao host Ansible que executa o playbook. Soluções alternativas são possíveis.

Eu escrevi uma respostaaquipara resolver esse problema para um único arquivo: O host Ansible que executa o playbook não aumenta suas próprias permissões para rootwith become: root; isso se aplica apenas à máquina de destino. Na pergunta original, ambos são, localhostmas acho que esse comportamento ainda se aplica, pense nele como uma root'fonte' não privilegiada e um rootalvo privilegiado.

A solução usa delegate_to: localhosto slurparquivo necessário na memória - delegate_to:permite become: rootfazer sua mágica localmente e, em seguida, gravar o arquivo salvo na máquina de destino.

A pergunta original pergunta sobre como fazer isso para diretórios: slurping diretórios também foi discutidoaquique deve fornecer um ponto de partida adequado quando combinado com a solução por arquivo slurp, esp. observe o comentário de @guzmonne sobre essa resposta. construir uma lista de arquivos slurpantes de usar a solução alternativa por arquivo (o que não é ótimo, mas pode ser preferível a alterar as permissões de arquivo/diretório).

informação relacionada