Ansible 복사 모듈 및 생성 - 권한이 거부되었습니다.

Ansible 복사 모듈 및 생성 - 권한이 거부되었습니다.

localhost폴더를 다른 위치로 복사하기 위해 Ansible 스크립트를 실행하고 있습니다 . 하지만,

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

나에게주고있다 [Errno 13] Permission denied: b'd/f1'. become_user명령이 루트로 실행될 것으로 예상했지만 작동하지 않았습니다. 이 파일의 권한은 입니다 0600(root:root).

Ansible을 사용하여 복사하기 위해 이 파일에 액세스할 수 있는 방법을 알려 주시겠습니까?

메모:

  • sudo ansible-playbook p.ymlsudo완벽하게 작동하지만 필요하지 않고 ansible에 트릭이 있는 경우 ansible 명령과 함께 사용하고 싶지 않습니다 .

  • command: cp -r /d/ /dest/d/sudoansible 명령( )에 추가하지 않고 작동합니다 ansible-playbook p.yml. 그러나 멱등성 및 모듈에 작업에 필요한 옵션이 있기 command때문에 도움을 줄 수 있다면 사용하고 싶지 않습니다 .copymode

답변1

업데이트: 로컬 호스트 마스터에서 권한을 루트로 승격할 수 있는 경우 해결책은 설정하는 것입니다 remote_src: true(credit @ivandov).

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

아래 세부정보에서는 localhost에서 루트로 에스컬레이션할 수 없는 경우에 대해 설명합니다. localhost의 파일이 주어지면

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

모듈복사예상대로 작동

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

먼저, 파일 읽기를 시도했지만 실패합니다.

치명적: [localhost]: 실패했습니다! => msg: '''/tmp/test/d/f1'' 파일을 읽는 동안 오류가 발생했습니다. [Errno 13] 권한이 거부되었습니다: b''/tmp/test/d/f1''. [Errno 13] 권한이 거부되었습니다: b''/tmp/test/d/f1'''

기본적으로 모듈복사다음에서 파일을 복사합니다.소스(원격 서버에 복사할 파일의 로컬 경로)목적지(파일을 복사해야 하는 원격 절대 경로). 이 경우 become: trueAnsible은 원격 호스트에 대한 권한을 에스컬레이션하지만 로컬 호스트 마스터에서는 에스컬레이션하지 않음을 의미합니다. 작업이 localhost에서 실행되고 있다는 사실에도 불구하고, 즉 마스터와 원격 호스트가 모두 localhost라는 사실에도 불구하고 remote_src: true설정이 없으면 become: true파일을 읽는 것이 아닌 쓰기에만 적용됩니다. localhost 설정에서 루트로 에스컬레이션할 수 없는 경우remote_src: true

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

실패할 것이다

치명적: [localhost]: 실패했습니다! => 변경됨=false ansible_facts: discover_interpreter_python: /usr/bin/python3 module_stderr: |- sudo: 비밀번호가 필요함 module_stdout: '' msg: |- 모듈 오류 정확한 오류는 stdout/stderr을 참조하세요. rc: 1


큐:"해결책이 있나요?"

A: 루트로 에스컬레이션하지 않으면 해결 방법이 없습니다. 파일의 소유권과 권한을 위반하게 됩니다. 예를 들어 컨트롤러에 파일이 있는 경우

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

아래 플레이북은 권한이 없는 사용자에 의해 시작되었습니다.

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

충돌할 것이다

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

localhost 마스터에서 루트로 에스컬레이션할 수 없는 경우 해결 방법은 플레이북을 실행하는 사용자가 파일을 읽을 수 있도록 만드는 것입니다.

답변2

Vladimir의 답변을 바탕으로 실제로 간단한 해결 방법이 있습니다!

아래의 설명(그리고 굵은 글씨로 추가한 강조 부분)이 핵심이었습니다.

모듈 복사에서 be: yes는 파일 쓰기에만 적용됩니다.그것을 읽는 것이 아니라.

remote_src: true파일을 로컬로 복사하는 경우에도 을 사용하세요 . 이로 인해 은(는 ) 원격 시스템으로 처리되고 권한 에스컬레이션이 올바르게 적용되므로 로컬 시스템에서 파일/디렉터리를 become읽을 때 권한이 올바르게 에스컬레이션 됩니다.srcsrc

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

답변3

tl;dr - Ansible은 become: root플레이북을 실행하는 Ansible 호스트가 아닌 대상 머신에 적용됩니다. 해결 방법이 가능합니다.

나는 답을 썼다여기단일 파일에 대해 이 문제를 해결 하려면: 플레이북을 실행하는 Ansible 호스트는 root; become: root이는 대상 시스템에만 적용됩니다. 원래 질문에는 둘 다 있지만 이 동작은 여전히 ​​​​적용된다고 생각합니다. 권한이 없는 '소스'와 권한이 있는 대상 localhost으로 생각하십시오 .rootroot

솔루션은 필요한 파일을 메모리에 사용합니다 delegate_to: localhost. slurp즉, 로컬에서 마법을 작동한 다음 저장된 파일을 대상 컴퓨터에 쓸 수 있습니다 delegate_to:.become: root

원래 질문에서는 디렉터리에 대해 이 작업을 수행하는 방법에 대해 묻습니다. slurp디렉터리 지정에 대해서도 논의되었습니다.여기이는 파일별 솔루션과 결합될 때 적절한 시작점을 제공해야 합니다 slurp. 해당 답변에 대한 @guzmonne의 의견을 참고하세요. 파일별 해결 방법을 사용하기 전에 파일 목록을 구성합니다 slurp(훌륭하지는 않지만 파일/디렉터리 권한을 변경하는 것보다 나을 수 있음).

관련 정보