Ansible 스크립트 모듈 'Permission denied' 오류 해결 방법

AnsibleBeginner
지금 연습하기

소개

Ansible 은 인프라 관리 및 구성을 단순화하는 강력한 자동화 도구입니다. Ansible script 모듈을 사용하면 플레이북 내에서 사용자 지정 스크립트를 실행하여 Ansible 의 기능을 내장 모듈 이상으로 확장할 수 있습니다. 그러나 사용자는 이 모듈을 사용할 때 종종 'Permission denied' 오류를 겪게 되며, 이는 자동화 워크플로우를 방해할 수 있습니다.

이 Lab 에서는 Ansible 의 script 모듈에서 권한 관련 문제를 이해하고 해결하는 과정을 안내합니다. 권한 오류의 원인을 식별하고 Ansible 스크립트가 성공적으로 실행되도록 하기 위한 다양한 솔루션을 구현하는 방법을 배우게 됩니다.

Ansible 설치 및 환경 설정

Ansible 스크립트의 권한 문제를 살펴보기 전에 환경을 설정해야 합니다. Ansible 을 설치하고 테스트 환경의 기본 구조를 만들어 보겠습니다.

Ansible 설치

먼저 패키지 인덱스를 업데이트하고 Ansible 을 설치해 보겠습니다.

sudo apt update
sudo apt install -y ansible

설치가 완료되면 Ansible 이 올바르게 설치되었는지 확인합니다.

ansible --version

Ansible 버전 및 구성 세부 정보를 보여주는 다음과 유사한 출력을 볼 수 있습니다.

ansible [core 2.12.x]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/labex/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/labex/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.x (default, Mar 01 2023, 12:34:56) [GCC 11.2.0]
  jinja version = 3.0.3
  libyaml = True

프로젝트 구조 설정

이제 Ansible 플레이북 및 스크립트를 위한 프로젝트 디렉토리 구조를 만들어 보겠습니다.

mkdir -p ~/project/ansible-lab/{playbooks,scripts}
cd ~/project/ansible-lab

이 구조에서:

  • playbooks/는 Ansible 플레이북을 포함합니다.
  • scripts/는 Ansible 에서 실행할 셸 스크립트를 포함합니다.

간단한 스크립트 생성

Ansible 과 함께 사용할 간단한 셸 스크립트를 만들어 보겠습니다. scripts 디렉토리에 hello.sh라는 파일을 만듭니다.

cd ~/project/ansible-lab/scripts
touch hello.sh

편집기에서 hello.sh 파일을 열고 다음 내용을 추가합니다.

#!/bin/bash
echo "Hello from $(hostname)!"
echo "Current time: $(date)"
echo "Current user: $(whoami)"

이 스크립트는 호스트 이름, 현재 시간 및 스크립트를 실행한 사용자를 출력합니다.

인벤토리 파일 생성

다음으로 Ansible 용 간단한 인벤토리 파일을 만들어 보겠습니다. Ansible 에서 인벤토리 파일은 Ansible 이 관리할 호스트 및 그룹을 정의합니다.

cd ~/project/ansible-lab
touch inventory.ini

inventory.ini 파일을 열고 다음을 추가합니다.

[local]
localhost ansible_connection=local

이 인벤토리 파일은 Ansible 에게 로컬 머신에서 명령을 실행하도록 지시합니다.

기본 플레이북 생성

이제 script 모듈을 사용하는 기본 Ansible 플레이북을 만들어 보겠습니다.

cd ~/project/ansible-lab/playbooks
touch run_script.yml

run_script.yml 파일을 열고 다음 내용을 추가합니다.

---
- name: Run a script
  hosts: local
  tasks:
    - name: Execute the hello script
      script: ../scripts/hello.sh

이 플레이북은 로컬 머신에서 hello.sh 스크립트를 실행하려고 시도합니다.

이 기본 설정을 통해 다음 단계에서 Ansible 스크립트의 권한 문제를 살펴볼 준비가 되었습니다.

'Permission Denied' 오류 발생

이제 환경을 설정했으므로 Ansible 플레이북을 실행하고 'permission denied' 오류가 발생할 때 어떤 일이 발생하는지 이해해 보겠습니다.

플레이북 실행

플레이북을 실행해 보겠습니다.

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini playbooks/run_script.yml

다음과 유사한 오류 메시지가 표시될 것입니다.

TASK [Execute the hello script] *******************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "failed to execute the script: /bin/sh: 1: /home/labex/.ansible/tmp/ansible-tmp-1234567890.12-123456789012345/AnsiballZ_script.py: Permission denied"}

이것은 Ansible script 모듈을 사용할 때 흔히 발생하는 'permission denied' 오류입니다. 이 오류는 스크립트에 실행 권한이 없기 때문에 발생하며, 스크립트를 실행하려면 실행 권한이 필요합니다.

Linux 에서 파일 권한 이해

Linux 에서 모든 파일에는 파일을 읽고, 쓰고, 실행할 수 있는 사용자를 결정하는 권한이 있습니다. 세 가지 유형의 권한이 있습니다.

  1. 읽기 (r): 파일 내용을 읽을 수 있습니다.
  2. 쓰기 (w): 파일을 수정할 수 있습니다.
  3. 실행 (x): 파일을 프로그램으로 실행할 수 있습니다.

이러한 권한은 세 가지 다른 사용자 범주에 할당됩니다.

  1. 사용자 (소유자): 파일의 소유자
  2. 그룹: 파일의 그룹 구성원인 사용자
  3. 기타: 다른 모든 사용자

ls -l 명령을 사용하여 파일의 권한을 볼 수 있습니다.

ls -l ~/project/ansible-lab/scripts/hello.sh

다음과 같은 출력을 볼 수 있습니다.

-rw-rw-r-- 1 labex labex 95 Jun 10 12:34 /home/labex/project/ansible-lab/scripts/hello.sh

이 출력에서 첫 번째 문자 집합 (-rw-rw-r--) 은 파일의 권한을 나타냅니다.

  • 첫 번째 문자 (-) 는 이것이 일반 파일임을 나타냅니다.
  • 다음 세 문자 (rw-) 는 소유자의 권한입니다 (읽기, 쓰기, 실행 없음).
  • 다음 세 문자 (rw-) 는 그룹의 권한입니다.
  • 마지막 세 문자 (r--) 는 기타 사용자의 권한입니다.

모든 사용자 범주에 대해 실행 권한 (x) 이 없음을 알 수 있습니다. 이것이 'permission denied' 오류가 발생하는 이유입니다.

현재 권한 확인

스크립트의 현재 권한을 살펴보겠습니다.

ls -l ~/project/ansible-lab/scripts/hello.sh

Ansible 이 실행하려면 필요한 실행 권한이 스크립트에 없음을 알 수 있습니다.

다음 단계에서는 이 권한 문제를 해결하고 Ansible 플레이북을 성공적으로 실행하는 방법을 배우겠습니다.

chmod 를 사용하여 권한 문제 해결

"Permission denied" 오류를 해결하는 가장 일반적인 방법은 스크립트 파일에 실행 권한을 추가하는 것입니다. chmod 명령을 사용하여 이 작업을 수행할 수 있습니다.

chmod 명령 이해

chmod 명령은 Linux 에서 파일 또는 디렉토리의 권한을 변경하는 데 사용됩니다. 이 명령은 권한을 지정하는 여러 가지 방법을 가지고 있습니다.

  1. 기호 모드 (Symbolic mode): 권한을 나타내기 위해 문자 (r, w, x) 를 사용합니다.
  2. 숫자 모드 (Numeric mode): 권한을 나타내기 위해 숫자 (4, 2, 1) 를 사용합니다.

우리의 목적을 위해 기호 모드를 사용하여 실행 권한을 추가하겠습니다.

스크립트에 실행 권한 추가

스크립트에 실행 권한을 추가해 보겠습니다.

chmod +x ~/project/ansible-lab/scripts/hello.sh

+x 옵션은 모든 사용자 범주 (사용자, 그룹 및 기타) 에 대한 실행 권한을 추가합니다.

권한이 업데이트되었는지 확인해 보겠습니다.

ls -l ~/project/ansible-lab/scripts/hello.sh

이제 다음과 유사한 출력을 볼 수 있습니다.

-rwxrwxr-x 1 labex labex 95 Jun 10 12:34 /home/labex/project/ansible-lab/scripts/hello.sh

권한 문자열에 x가 표시되어 실행 권한이 추가되었음을 나타냅니다.

플레이북 다시 실행

이제 스크립트에 실행 권한을 추가했으므로 Ansible 플레이북을 다시 실행해 보겠습니다.

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini playbooks/run_script.yml

이번에는 플레이북이 성공적으로 실행되어야 합니다.

PLAY [Run a script] ******************************************

TASK [Gathering Facts] ***************************************
ok: [localhost]

TASK [Execute the hello script] *****************************
changed: [localhost]

PLAY RECAP *************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

스크립트 출력 보기

스크립트의 출력을 확인해 보겠습니다. Ansible 은 스크립트의 출력을 캡처하여 작업 결과에 포함합니다. 자세한 출력을 보려면 플레이북을 수정하여 출력을 등록하고 표시해 보겠습니다.

cd ~/project/ansible-lab/playbooks

run_script.yml 파일을 편집하여 register 및 debug 작업을 포함합니다.

---
- name: Run a script
  hosts: local
  tasks:
    - name: Execute the hello script
      script: ../scripts/hello.sh
      register: script_output

    - name: Display script output
      debug:
        var: script_output.stdout_lines

이제 플레이북을 다시 실행해 보겠습니다.

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini playbooks/run_script.yml

다음과 같은 출력을 볼 수 있습니다.

PLAY [Run a script] ******************************************

TASK [Gathering Facts] ***************************************
ok: [localhost]

TASK [Execute the hello script] *****************************
changed: [localhost]

TASK [Display script output] ********************************
ok: [localhost] => {
    "script_output.stdout_lines": [
        "Hello from localhost!",
        "Current time: Wed Jun 10 12:34:56 UTC 2023",
        "Current user: labex"
    ]
}

PLAY RECAP *************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

이제 스크립트의 전체 출력을 볼 수 있습니다. 스크립트는 현재 사용자 인 labex 사용자로 실행되었습니다.

chmod +x를 사용하여 실행 권한을 추가함으로써 "Permission denied" 오류를 성공적으로 해결했으며 이제 Ansible 을 통해 스크립트를 실행할 수 있습니다.

권한 상승을 위한 Become 사용

때로는 root 액세스가 필요한 명령을 실행하는 등, 권한이 상승된 상태로 스크립트를 실행해야 할 수 있습니다. 이러한 경우, 스크립트에 실행 권한을 추가하는 것만으로는 충분하지 않을 수 있습니다. Ansible 은 권한 상승과 함께 작업을 실행하기 위해 become 지시문을 제공합니다.

Become 지시문 이해

Ansible 의 become 지시문을 사용하면 다른 사용자, 일반적으로 권한이 상승된 사용자로 작업을 실행할 수 있습니다. 이는 명령줄에서 sudo를 사용하는 것과 유사합니다.

become 지시문의 주요 옵션은 다음과 같습니다.

  • become: yes: 권한 상승을 활성화합니다.
  • become_user: <username>: 어떤 사용자가 될지 지정합니다 (기본값은 root).
  • become_method: <method>: 사용자가 되는 방법을 지정합니다 (기본값은 sudo).

Root 권한이 필요한 스크립트 생성

성공적으로 실행하려면 root 권한이 필요한 스크립트를 만들어 보겠습니다.

cd ~/project/ansible-lab/scripts
touch system_info.sh

system_info.sh 파일에 다음 내용을 추가합니다.

#!/bin/bash
echo "System information - requires root privileges"
echo "Hostname: $(hostname)"
echo "Kernel version: $(uname -r)"
echo "Available disk space:"
df -h /
echo "User executing the script: $(whoami)"

스크립트를 실행 가능하게 만듭니다.

chmod +x ~/project/ansible-lab/scripts/system_info.sh

Become 을 사용하는 플레이북 생성

이제 become 지시문을 사용하는 플레이북을 만들어 보겠습니다.

cd ~/project/ansible-lab/playbooks
touch root_script.yml

root_script.yml 파일에 다음 내용을 추가합니다.

---
- name: Run a script as root
  hosts: local
  tasks:
    - name: Execute the system info script
      script: ../scripts/system_info.sh
      become: yes
      register: script_output

    - name: Display script output
      debug:
        var: script_output.stdout_lines

become: yes 지시문은 Ansible 에게 권한이 상승된 상태로 스크립트를 실행하도록 지시합니다.

Become 을 사용하여 플레이북 실행

새 플레이북을 실행해 보겠습니다.

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini playbooks/root_script.yml

플레이북이 성공적으로 실행되어야 하며, 다음과 유사한 출력을 볼 수 있습니다.

PLAY [Run a script as root] *********************************

TASK [Gathering Facts] **************************************
ok: [localhost]

TASK [Execute the system info script] **********************
changed: [localhost]

TASK [Display script output] *******************************
ok: [localhost] => {
    "script_output.stdout_lines": [
        "System information - requires root privileges",
        "Hostname: localhost",
        "Kernel version: 5.15.0-1015-aws",
        "Available disk space:",
        "Filesystem      Size  Used Avail Use% Mounted on",
        "/dev/root        59G   17G   42G  29% /",
        "User executing the script: root"
    ]
}

PLAY RECAP ************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

스크립트 출력에서 "User executing the script"가 이제 labex가 아닌 root임을 알 수 있습니다. 이는 become: yes 지시문으로 인해 스크립트가 권한이 상승된 상태로 실행되었음을 보여줍니다.

Become 을 사용해야 하는 경우 이해

다음과 같은 상황에서 become 지시문을 사용해야 합니다.

  1. 스크립트가 root 권한이 필요한 시스템 파일 또는 디렉토리에 액세스해야 하는 경우
  2. 스크립트가 패키지를 설치하거나 시스템 구성을 수정해야 하는 경우
  3. 스크립트가 명령줄에서 일반적으로 sudo가 필요한 명령을 실행해야 하는 경우

become 지시문을 적절하게 사용하면 스크립트가 성공적으로 실행하는 데 필요한 권한을 갖도록 하여 'permission denied' 오류를 방지할 수 있습니다.

권한 문제를 피하기 위한 모범 사례

chmodbecome을 사용하여 권한 문제를 해결하는 방법을 이해했으므로, 처음부터 권한 문제가 발생하지 않도록 하기 위한 몇 가지 모범 사례를 살펴보겠습니다.

1. 스크립트를 사용하기 전에 항상 실행 가능하게 만들기

Ansible 에서 스크립트를 사용하기 전에 항상 실행 권한이 있는지 확인하십시오.

chmod +x path/to/script.sh

스크립트 생성 프로세스의 일부로 이 작업을 수행하는 것이 좋습니다.

2. 적절한 파일 모드와 함께 버전 관리 사용

Git 또는 다른 버전 관리 시스템을 사용하는 경우 파일 모드 (권한) 를 유지하는지 확인하십시오. Git 에서는 다음과 같이 구성할 수 있습니다.

git config core.fileMode true

기존 저장소의 경우 파일 모드를 업데이트해야 할 수 있습니다.

git update-index --chmod=+x path/to/script.sh

3. 권한을 확인하고 수정하는 스크립트 만들기

프로젝트의 모든 스크립트에 대한 권한을 확인하고 수정하는 유틸리티 스크립트를 만들어 보겠습니다.

cd ~/project/ansible-lab
touch fix_permissions.sh

fix_permissions.sh 파일에 다음 내용을 추가합니다.

#!/bin/bash
echo "Fixing permissions for scripts in ansible-lab"

## Find all .sh files and make them executable
find ~/project/ansible-lab -name "*.sh" -type f -exec chmod +x {} \;

echo "Done. All script files now have execute permissions."

스크립트를 실행 가능하게 만듭니다.

chmod +x ~/project/ansible-lab/fix_permissions.sh

프로젝트의 모든 스크립트에 실행 권한이 있는지 확인하려면 스크립트를 실행하십시오.

./fix_permissions.sh

4. Ansible 의 File 모듈을 사용하여 권한 설정

Ansible 의 file 모듈을 사용하여 스크립트 파일에 올바른 권한이 있는지 확인할 수도 있습니다. 이를 수행하는 플레이북을 만들어 보겠습니다.

cd ~/project/ansible-lab/playbooks
touch set_permissions.yml

set_permissions.yml 파일에 다음 내용을 추가합니다.

---
- name: Set correct permissions for scripts
  hosts: local
  tasks:
    - name: Find all script files
      find:
        paths: /home/labex/project/ansible-lab
        patterns: "*.sh"
        recurse: yes
      register: script_files

    - name: Make script files executable
      file:
        path: "{{ item.path }}"
        mode: "0755"
      loop: "{{ script_files.files }}"

모든 스크립트에 올바른 권한이 있는지 확인하려면 이 플레이북을 실행하십시오.

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini playbooks/set_permissions.yml

5. 사전 검사 플레이북 만들기

마지막으로, 주요 플레이북을 실행하기 전에 모든 것이 올바르게 설정되었는지 확인하기 위해 실행되는 사전 검사 플레이북을 만들어 보겠습니다.

cd ~/project/ansible-lab/playbooks
touch preflight_check.yml

preflight_check.yml 파일에 다음 내용을 추가합니다.

---
- name: Pre-flight checks
  hosts: local
  tasks:
    - name: Check if scripts are executable
      find:
        paths: /home/labex/project/ansible-lab
        patterns: "*.sh"
        recurse: yes
      register: script_files

    - name: Verify script permissions
      stat:
        path: "{{ item.path }}"
      register: stat_results
      loop: "{{ script_files.files }}"
      failed_when: not stat_results.stat.executable
      ignore_errors: yes

이 플레이북은 모든 .sh 파일이 실행 가능한지 확인하고 실행 가능하지 않은 파일을 보고합니다.

사전 검사를 실행해 보겠습니다.

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini playbooks/preflight_check.yml

모든 스크립트에 올바른 권한이 있으면 플레이북이 오류 없이 완료되어야 합니다. 실행 권한이 없는 스크립트가 있으면 알림이 표시됩니다.

이러한 모범 사례를 따르면 Ansible 스크립트에서 'permission denied' 오류를 방지하고 자동화가 원활하게 실행되도록 할 수 있습니다.

요약

이 Lab 에서는 Ansible 스크립트 모듈을 사용할 때 'Permission denied' 오류를 식별하고 해결하는 방법을 배웠습니다.

이 Lab 의 주요 내용은 다음과 같습니다.

  1. Linux 에서 파일 권한의 중요성과 Ansible 에서 스크립트 실행에 미치는 영향 이해
  2. chmod 명령을 사용하여 스크립트 파일에 실행 권한 추가
  3. root 액세스가 필요한 스크립트를 실행할 때 권한 상승을 위해 Ansible 의 become 지시문 활용
  4. 권한 문제를 방지하기 위한 모범 사례 구현, 다음 포함:
    • 스크립트를 사용하기 전에 실행 가능하게 만들기
    • 버전 관리에서 적절한 파일 모드 유지
    • 권한을 확인하고 수정하는 유틸리티 스크립트 생성
    • Ansible 의 file 모듈을 사용하여 권한 설정
    • 사전 검사를 구현하여 환경 확인

이러한 기술을 적용하면 Ansible 스크립트가 권한 오류 없이 원활하게 실행되도록 하여 자동화 워크플로우의 안정성을 향상시킬 수 있습니다.

이 Lab 에서 배운 기술은 Ansible 을 효과적으로 사용하기 위한 기본이며 광범위한 자동화 시나리오에 적용할 수 있습니다.