Ansible 을 이용한 RHEL 파일 배포 및 관리

AnsibleBeginner
지금 연습하기

소개

이 실습에서는 Ansible 을 사용하여 Red Hat Enterprise Linux (RHEL) 시스템에 파일을 배포하고 관리하는 기본적인 기술을 배우게 됩니다. 파일 작업에 설계된 가장 일반적이고 강력한 Ansible 모듈을 직접 사용해 보면서 기본적인 파일 배포부터 고급 콘텐츠 조작 및 상태 관리까지 경험하게 됩니다.

먼저 ansible.builtin.copy 모듈을 사용하여 정적 파일을 전송하고 속성을 설정합니다. 다음으로 lineinfileblockinfile을 사용하여 파일 내용을 수정하고, ansible.builtin.template 모듈을 사용하여 사용자 지정 MOTD 를 생성합니다. 또한 이 실습에서는 심볼릭 링크 생성, stat을 사용한 파일 상태 확인, fetch를 사용한 로그 검색, 관리 파일 정리 등을 다루며 Ansible 의 파일 관리 기능을 포괄적으로 살펴봅니다.

이것은 가이드 실험입니다. 학습과 실습을 돕기 위한 단계별 지침을 제공합니다.각 단계를 완료하고 실무 경험을 쌓기 위해 지침을 주의 깊게 따르세요. 과거 데이터에 따르면, 이것은 초급 레벨의 실험이며 완료율은 83%입니다.학습자들로부터 100%의 긍정적인 리뷰율을 받았습니다.

ansible.builtin.copy 모듈을 사용하여 정적 파일 복사 및 속성 설정

이 단계에서는 가장 기본적인 Ansible 모듈 중 하나인 ansible.builtin.copy를 사용하는 방법을 배우게 됩니다. 이 모듈은 제어 노드 (LabEx VM) 에서 관리 대상 호스트의 지정된 위치로 파일을 전송하는 데 사용됩니다. 이 경우 관리 대상 호스트는 localhost 자체입니다. 단순히 복사하는 것 외에도 copy 모듈을 사용하면 파일의 소유자, 그룹 및 권한 모드와 같은 파일 속성을 정확하게 제어할 수 있으며, 이는 올바른 시스템 구성을 위해 필수적입니다.

먼저 프로젝트 환경을 설정하겠습니다. 모든 작업은 ~/project 디렉토리 내에서 수행됩니다.

  1. 프로젝트 디렉토리로 이동하여 소스 파일용 하위 디렉토리를 생성합니다. 이는 프로젝트를 체계적으로 관리하기 위한 일반적인 관행입니다.

    ansible-core 패키지를 설치합니다.

    sudo dnf install -y ansible-core

    그런 다음 프로젝트 디렉토리로 이동하여 소스 파일용 하위 디렉토리를 생성합니다.

    cd ~/project
    mkdir files
  2. 다음으로 복사할 간단한 텍스트 파일을 생성합니다. "here document"와 함께 cat 명령을 사용하여 files 디렉토리 내에 info.txt 파일을 생성합니다.

    cat << EOF > ~/project/files/info.txt
    This file was deployed by Ansible.
    It contains important system information.
    EOF
  3. 이제 Ansible 인벤토리 파일을 생성합니다. 인벤토리는 Ansible 이 관리할 호스트를 알려줍니다. 이 실습에서는 로컬 머신을 관리합니다. inventory.ini라는 파일을 생성합니다.

    cat << EOF > ~/project/inventory.ini
    localhost ansible_connection=local
    EOF

    이 인벤토리에서 localhost는 대상 호스트입니다. ansible_connection=local 변수는 Ansible 에 SSH 를 사용하지 않고 제어 노드에서 직접 작업을 실행하도록 지시합니다.

  4. 첫 번째 Ansible 플레이북을 생성합니다. 이 플레이북에는 파일 복사 지침이 포함됩니다. nano 또는 cat을 사용하여 copy_file.yml이라는 파일을 생성합니다.

    nano ~/project/copy_file.yml

    파일에 다음 내용을 추가합니다. 이 플레이북은 하나의 작업을 정의합니다. info.txt/tmp/ 디렉토리로 복사하고 속성을 설정하는 것입니다.

    ---
    - name: Deploy a static file to localhost
      hosts: localhost
      tasks:
        - name: Copy info.txt and set attributes
          ansible.builtin.copy:
            src: files/info.txt
            dest: /tmp/info.txt
            owner: labex
            group: labex
            mode: "0640"

    copy 작업의 매개변수를 자세히 살펴보겠습니다.

    • src: files/info.txt: 플레이북 위치에 상대적인 제어 노드에 있는 소스 파일의 경로입니다.
    • dest: /tmp/info.txt: 관리 대상 호스트에서 파일이 배치될 절대 경로입니다.
    • owner: labex: 파일의 소유자를 labex 사용자로 설정합니다.
    • group: labex: 파일의 그룹을 labex 그룹으로 설정합니다.
    • mode: '0640': 파일의 권한을 설정합니다. 0640은 소유자는 읽기/쓰기가 가능하고, 그룹은 읽기가 가능하며, 다른 사용자는 권한이 없음을 의미합니다.
  5. -i 플래그를 사용하여 인벤토리 파일을 지정하는 ansible-playbook 명령으로 플레이북을 실행합니다.

    ansible-playbook -i inventory.ini copy_file.yml

    플레이북이 성공적으로 실행되었음을 나타내는 다음과 유사한 출력이 표시됩니다.

    PLAY [Deploy a static file to localhost] ***************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Copy info.txt and set attributes] ****************************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  6. 마지막으로 파일이 올바르게 복사되었는지와 올바른 속성을 가지고 있는지 확인합니다. ls -l 명령을 사용하여 권한, 소유자 및 그룹을 확인합니다.

    ls -l /tmp/info.txt

    출력에는 labex가 소유자 및 그룹이고 권한이 -rw-r-----로 표시되어야 합니다.

    -rw-r----- 1 labex labex 72 Jul 10 14:30 /tmp/info.txt

    파일의 내용을 확인하여 완전히 복사되었는지 확인할 수도 있습니다.

    cat /tmp/info.txt
    This file was deployed by Ansible.
    It contains important system information.

ansible.builtin.copy 모듈을 사용하여 로컬 시스템에 파일을 배포하고 속성을 구성하는 데 성공했습니다.

lineinfileblockinfile 을 사용하여 파일 내용 수정

이 단계에서는 관리 대상 호스트의 기존 파일을 전체 파일을 교체하지 않고 수정하는 방법을 배우게 됩니다. Ansible 은 이러한 목적을 위해 강력한 모듈을 제공합니다. 단일 줄을 관리하기 위한 ansible.builtin.lineinfile과 여러 줄의 텍스트 블록을 관리하기 위한 ansible.builtin.blockinfile입니다. 이 모듈들은 구성 설정을 변경하거나 로그 파일에 항목을 추가하는 작업에 매우 유용합니다.

이전 단계에서 생성한 info.txt 파일 (/tmp/info.txt에 위치) 을 계속 사용하겠습니다.

  1. 먼저 프로젝트 디렉토리에 있는지 확인합니다.

    cd ~/project
  2. modify_file.yml이라는 새 플레이북을 생성합니다. 이 플레이북에는 두 개의 작업이 포함됩니다. 하나는 단일 줄을 추가하는 작업이고 다른 하나는 기존 파일에 텍스트 블록을 추가하는 작업입니다.

    nano ~/project/modify_file.yml
  3. modify_file.yml 플레이북에 다음 내용을 추가합니다. 이 플레이북은 localhost를 대상으로 하며 lineinfileblockinfile을 모두 사용하여 /tmp/info.txt에 내용을 추가합니다.

    ---
    - name: Modify an existing file
      hosts: localhost
      tasks:
        - name: Add a single line of text to a file
          ansible.builtin.lineinfile:
            path: /tmp/info.txt
            line: This line was added by the lineinfile module.
            state: present
    
        - name: Add a block of text to an existing file
          ansible.builtin.blockinfile:
            path: /tmp/info.txt
            block: |
              ## BEGIN ANSIBLE MANAGED BLOCK
              This block of text consists of two lines.
              They have been added by the blockinfile module.
              ## END ANSIBLE MANAGED BLOCK
            state: present

    사용된 모듈을 살펴보겠습니다.

    • ansible.builtin.lineinfile: 이 모듈은 특정 줄이 파일에 있는지 확인합니다. 줄이 이미 존재하면 Ansible 은 아무 작업도 수행하지 않아 작업이 멱등성 (idempotent) 을 갖게 됩니다.
    • path: 수정할 파일입니다.
    • line: 파일에 있어야 하는 텍스트 줄입니다.
    • state: present: 줄이 존재하도록 합니다. 제거하려면 state: absent를 사용할 수 있습니다.
    • ansible.builtin.blockinfile: 이 모듈은 마커 줄 (예: ## BEGIN ANSIBLE MANAGED BLOCK) 로 둘러싸인 텍스트 블록을 관리합니다. 이는 구성 섹션을 관리하는 데 이상적입니다.
    • path: 수정할 파일입니다.
    • block: 삽입할 여러 줄 문자열입니다. |는 리터럴 블록에 대한 YAML 구문으로, 줄 바꿈을 유지합니다.
    • state: present: 블록이 존재하도록 합니다.
  4. ansible-playbook 명령과 inventory.ini 파일을 사용하여 플레이북을 실행합니다.

    ansible-playbook -i inventory.ini modify_file.yml

    출력에서는 두 작업 모두 파일에 변경 사항을 적용했음을 보여줍니다.

    PLAY [Modify an existing file] *************************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Add a single line of text to a file] *************************************
    changed: [localhost]
    
    TASK [Add a block of text to an existing file] *********************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  5. 마지막으로 /tmp/info.txt의 내용을 확인하여 변경 사항을 확인합니다.

    cat /tmp/info.txt

    원본 내용 뒤에 새 줄과 새 텍스트 블록이 표시되어야 합니다.

    This file was deployed by Ansible.
    It contains important system information.
    This line was added by the lineinfile module.
    ## BEGIN ANSIBLE MANAGED BLOCK
    This block of text consists of two lines.
    They have been added by the blockinfile module.
    ## END ANSIBLE MANAGED BLOCK

    플레이북을 다시 실행하면 내용이 이미 존재하므로 Ansible 은 ok=3changed=0을 보고합니다. 이는 이러한 모듈의 멱등성을 보여줍니다.

ansible.builtin.template 모듈을 사용하여 사용자 지정 MOTD 생성

이 단계에서는 정적 파일을 복사하는 것에서 나아가 ansible.builtin.template 모듈을 사용하여 동적 파일을 생성하는 방법을 배우게 됩니다. 이 모듈은 Jinja2 템플릿 엔진을 활용하여 Ansible 이 관리 대상 호스트에서 수집한 "팩트 (facts)"와 변수를 사용하여 사용자 지정된 파일을 생성합니다. 시스템별 정보를 표시하는 동적 메시지 오브 더 데이 (MOTD) 를 생성해 보겠습니다.

  1. 먼저 ~/project 디렉토리에 있는지 확인하고 템플릿을 위한 전용 하위 디렉토리를 생성합니다. Jinja2 템플릿을 templates 디렉토리에 저장하는 것은 Ansible 의 표준 모범 사례입니다.

    cd ~/project
    mkdir templates
  2. 다음으로 Jinja2 템플릿 파일을 생성합니다. 이 파일인 motd.j2는 동적 데이터를 위한 자리 표시자를 포함하여 MOTD 의 구조를 담게 됩니다. .j2 확장자는 Jinja2 템플릿에 대한 일반적인 규칙입니다.

    nano ~/project/templates/motd.j2

    파일에 다음 내용을 추가합니다. 변수나 팩에 대한 자리 표시자를 나타내는 {{ ... }} 구문에 주목하십시오.

    #################################################################
    ##          Welcome to {{ ansible_facts['fqdn'] }}
    #
    ## This is a {{ ansible_facts['distribution'] }} system.
    ## System managed by Ansible.
    #
    ## For support, contact: {{ admin_email }}
    #################################################################

    이 템플릿에서:

    • {{ ansible_facts['fqdn'] }}은 호스트의 정규화된 도메인 이름 (Fully Qualified Domain Name) 으로 대체됩니다.
    • {{ ansible_facts['distribution'] }}은 Linux 배포판 이름 (예: RedHat) 으로 대체됩니다.
    • {{ admin_email }}은 플레이북에서 정의할 사용자 지정 변수입니다.
  3. 이제 template_motd.yml이라는 새 플레이북을 생성합니다. 이 플레이북은 템플릿을 사용하여 /etc/motd를 생성합니다.

    nano ~/project/template_motd.yml

    다음 내용을 추가합니다. 이 플레이북은 /etc 디렉토리에 쓰기 위해 관리자 권한 (become: true) 이 필요합니다. 또한 사용자 지정 admin_email 변수를 정의합니다.

    ---
    - name: Deploy a custom MOTD from a template
      hosts: localhost
      become: true
      vars:
        admin_email: admin@labex.io
      tasks:
        - name: Generate /etc/motd from template
          ansible.builtin.template:
            src: templates/motd.j2
            dest: /etc/motd
            owner: root
            group: root
            mode: "0644"

    이 플레이북의 주요 매개변수는 다음과 같습니다.

    • become: true: Ansible 에 sudo를 사용하여 작업을 실행하도록 지시합니다. 이는 /etc/motd에 쓰기 위해 필요합니다.
    • vars: 이 섹션은 admin_email과 같은 사용자 지정 변수를 정의하는 곳입니다.
    • ansible.builtin.template: Jinja2 템플릿을 처리하는 모듈입니다. src.j2 파일을 가리키고 dest는 관리 대상 호스트의 대상 파일입니다.
  4. 플레이북을 실행합니다.

    ansible-playbook -i inventory.ini template_motd.yml

    출력에서 작업이 성공했음을 확인할 수 있습니다.

    PLAY [Deploy a custom MOTD from a template] ************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Generate /etc/motd from template] ****************************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  5. 결과를 확인합니다. 새로 생성된 /etc/motd 파일의 내용을 확인합니다.

    cat /etc/motd

    Jinja2 자리 표시자가 실제 시스템 팩트와 정의한 사용자 지정 변수로 대체된 렌더링된 출력을 볼 수 있습니다. fqdn은 실험 환경의 호스트 이름과 일치할 것입니다.

    #################################################################
    ##          Welcome to host.labex.io
    #
    ## This is a RedHat system.
    ## System managed by Ansible.
    #
    ## For support, contact: admin@labex.io
    #################################################################

이제 템플릿을 사용하여 사용자 지정 파일을 성공적으로 생성했습니다. 이는 인프라 자동화의 핵심 기술입니다.

copyfile 모듈을 사용하여 지원 파일 배포 및 심볼릭 링크 생성

이 단계에서는 copy 모듈에 대한 지식을 새로운 다목적 모듈인 ansible.builtin.file과 결합하게 됩니다. copy는 콘텐츠 전송에 사용되는 반면, file은 관리 대상 호스트의 파일, 디렉토리 및 심볼릭 링크의 상태를 관리하는 데 사용됩니다. 이를 사용하여 디렉토리를 생성하고, 권한을 설정하며, 이 연습에서 가장 중요한 심볼릭 링크를 생성합니다.

시나리오는 시스템에서 표시되는 로그인 전 메시지를 구성하는 것입니다. 많은 Linux 시스템에서 /etc/issue는 로컬 터미널 사용자에게 표시되고, /etc/issue.net은 원격 사용자 (SSH 등) 에게 표시됩니다. 단일 issue 파일을 배포한 다음 심볼릭 링크를 생성하여 /etc/issue.net/etc/issue를 가리키도록 하여 항상 동일한 메시지를 표시하도록 하겠습니다.

  1. 먼저 ~/project 디렉토리에 있는지 확인하고 이슈 메시지에 대한 소스 파일을 생성합니다. 이 파일은 이전에 생성한 files 하위 디렉토리에 배치합니다.

    cd ~/project
    cat << EOF > ~/project/files/issue
    Authorized access only.
    All connections are logged and monitored.
    EOF
  2. deploy_issue.yml이라는 새 플레이북을 생성합니다. 이 플레이북에는 두 개의 작업이 포함됩니다. 하나는 issue 파일을 복사하는 작업이고 다른 하나는 심볼릭 링크를 생성하는 작업입니다.

    nano ~/project/deploy_issue.yml
  3. deploy_issue.yml 플레이북에 다음 내용을 추가합니다. 이 플레이북은 /etc/ 디렉토리의 파일을 관리하기 위해 관리자 권한 (become: true) 이 필요합니다.

    ---
    - name: Configure system issue files
      hosts: localhost
      become: true
      tasks:
        - name: Copy custom /etc/issue file
          ansible.builtin.copy:
            src: files/issue
            dest: /etc/issue
            owner: root
            group: root
            mode: "0644"
    
        - name: Ensure /etc/issue.net is a symlink to /etc/issue
          ansible.builtin.file:
            src: /etc/issue
            dest: /etc/issue.net
            state: link
            force: yes

    새로운 ansible.builtin.file 작업을 분석해 보겠습니다.

    • src: /etc/issue: statelink일 때 src는 심볼릭 링크가 가리켜야 하는 파일을 지정합니다.
    • dest: /etc/issue.net: 이것은 심볼릭 링크 자체가 생성될 경로입니다.
    • state: link: 이 중요한 매개변수는 file 모듈에 일반 파일이나 디렉토리가 아닌 심볼릭 링크를 생성하도록 지시합니다.
    • force: yes: 이것은 멱등성 (idempotency) 을 보장하는 유용한 옵션입니다. /etc/issue.net이 이미 일반 파일로 존재하는 경우 Ansible 은 이를 제거하고 링크를 생성합니다. force: yes가 없으면 해당 상황에서 플레이북이 실패합니다.
  4. 플레이북을 실행합니다.

    ansible-playbook -i inventory.ini deploy_issue.yml

    출력에서 두 작업 모두 성공적으로 변경 사항을 적용했음을 보여줍니다.

    PLAY [Configure system issue files] ********************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Copy custom /etc/issue file] *********************************************
    changed: [localhost]
    
    TASK [Ensure /etc/issue.net is a symlink to /etc/issue] ************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  5. ls -l 명령을 사용하여 결과를 확인합니다. 이 명령은 심볼릭 링크를 명확하게 보여주는 자세한 목록을 제공합니다.

    ls -l /etc/issue /etc/issue.net

    출력에서 /etc/issue는 일반 파일이고 /etc/issue.net은 이를 가리키는 심볼릭 링크임을 보여야 합니다. /etc/issue.net의 권한 시작 부분에 있는 l은 링크임을 나타냅니다.

    -rw-r--r--. 1 root root 65 Jul 10 15:00 /etc/issue
    lrwxrwxrwx. 1 root root 10 Jul 10 15:00 /etc/issue.net -> /etc/issue

이제 구성 파일을 성공적으로 배포하고 ansible.builtin.file 모듈을 사용하여 심볼릭 링크를 생성했습니다. 이는 시스템 구성을 관리하는 일반적이고 강력한 패턴입니다.

stat 으로 파일 상태 확인 및 fetch 로 로그 가져오기

이 단계에서는 두 가지 중요한 데이터 수집 모듈인 ansible.builtin.statansible.builtin.fetch에 대해 배우게 됩니다. stat 모듈은 관리 대상 호스트의 파일 또는 디렉토리 상태를 확인하는 데 사용됩니다. 예를 들어, 파일이 존재하는지, 권한은 무엇인지, 마지막으로 수정된 시간 등을 확인할 수 있습니다. 이 모듈은 아무것도 변경하지 않으므로 확인 및 조건부 논리에 완벽합니다. fetch 모듈은 copy와 반대되는 역할을 합니다. 즉, 관리 대상 호스트에서 파일을 가져와 제어 노드에 저장합니다. 이는 구성을 백업하거나 분석을 위해 로그 파일을 수집하는 데 이상적입니다.

이전 단계에서 생성한 /etc/motd 파일의 존재 여부를 확인한 다음, DNF 패키지 관리자 로그 파일 (/var/log/dnf.log) 을 LabEx VM 의 로컬 디렉토리로 가져오는 플레이북을 생성합니다.

  1. 먼저 ~/project 디렉토리에 있는지 확인하고 가져올 파일을 저장할 새 하위 디렉토리를 생성합니다.

    cd ~/project
    mkdir fetched_logs
  2. check_and_fetch.yml이라는 새 플레이북을 생성합니다. 이 플레이북에는 파일 확인 및 로그 검색 작업이 포함됩니다.

    nano ~/project/check_and_fetch.yml
  3. check_and_fetch.yml 플레이북에 다음 내용을 추가합니다. 이 플레이북은 stat을 사용하여 파일 세부 정보를 가져오고, register를 사용하여 해당 세부 정보를 변수에 저장하며, debug를 사용하여 변수를 표시하고, fetch를 사용하여 로그 파일을 검색합니다.

    ---
    - name: Check file status and fetch logs
      hosts: localhost
      become: true
      tasks:
        - name: Check if /etc/motd exists
          ansible.builtin.stat:
            path: /etc/motd
          register: motd_status
    
        - name: Display stat results
          ansible.builtin.debug:
            var: motd_status.stat
    
        - name: Fetch the dnf log file from managed host
          ansible.builtin.fetch:
            src: /var/log/dnf.log
            dest: fetched_logs/
            flat: yes

    주요 개념을 자세히 살펴보겠습니다.

    • register: motd_status: 이것은 중요한 Ansible 기능입니다. 작업의 전체 출력을 가져와 motd_status라는 새 변수에 저장합니다.
    • ansible.builtin.debug: 이 모듈은 플레이북 실행 중에 값을 출력하는 데 사용됩니다. 여기서는 등록된 변수 (motd_status.stat) 내의 stat 객체를 출력하여 파일 속성을 확인합니다.
    • ansible.builtin.fetch: 이 모듈은 관리 대상 호스트에서 파일을 검색합니다.
    • src: 관리 대상 호스트에서 검색할 파일의 경로입니다.
    • dest: 파일이 저장될 제어 노드 (LabEx VM) 의 디렉토리입니다.
    • flat: yes: 기본적으로 fetch는 호스트 및 소스 경로와 일치하는 하위 디렉토리 구조를 생성합니다. flat: yes는 추가 하위 디렉토리 없이 파일을 dest 디렉토리로 직접 복사하여 이를 단순화합니다.
  4. 플레이북을 실행합니다. 시스템 로그 파일을 읽기 때문에 필요한 권한을 얻기 위해 become: true가 사용됩니다.

    ansible-playbook -i inventory.ini check_and_fetch.yml

    출력에서는 디버그 작업의 stat 확인 결과와 fetch 작업 결과가 표시됩니다.

    PLAY [Check file status and fetch logs] ****************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Check if /etc/motd exists] ***********************************************
    ok: [localhost]
    
    TASK [Display stat results] ****************************************************
    ok: [localhost] => {
        "motd_status.stat": {
            "exists": true,
            "gid": 0,
            "isreg": true,
            "mode": "0644",
            "path": "/etc/motd",
            ...
        }
    }
    
    TASK [Fetch the dnf log file from managed host] ********************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  5. 로그 파일이 성공적으로 가져와졌는지 확인합니다. fetched_logs 디렉토리의 내용을 나열합니다.

    ls -l ~/project/fetched_logs/

    이제 제어 노드에 로컬로 저장된 dnf.log 파일이 표시되어야 합니다.

    total 4
    -rw-r--r--. 1 labex labex 1234 Jul 10 15:30 dnf.log

이제 변경하지 않고 파일 속성을 검사하는 방법과 관리 대상 시스템에서 제어 노드로 중요한 파일을 검색하는 방법을 배웠습니다.

file 모듈을 사용하여 관리 호스트 파일 정리

마지막 단계에서는 ansible.builtin.file 모듈을 사용하여 시스템에 파일과 디렉토리가 존재하지 않도록 하는 방법을 배우게 됩니다. 구성 관리의 중요한 부분은 리소스를 생성하고 수정하는 것뿐만 아니라 정리하는 것입니다. state 매개변수를 absent로 설정하면 Ansible 이 파일, 심볼릭 링크 또는 전체 디렉토리까지 제거하도록 지시할 수 있습니다.

이 실습을 마무리하기 위해 이전 단계에서 생성한 모든 아티팩트인 /tmp/info.txt, /etc/motd, /etc/issue, 그리고 /etc/issue.net 심볼릭 링크를 제거하는 단일 "정리" 플레이북을 작성합니다.

  1. 먼저 ~/project 디렉토리에 있는지 확인합니다.

    cd ~/project
  2. cleanup.yml이라는 새 플레이북을 생성합니다. 이 플레이북에는 변경 사항을 되돌리는 데 필요한 모든 작업이 포함됩니다.

    nano ~/project/cleanup.yml
  3. cleanup.yml 플레이북에 다음 내용을 추가합니다. 이 플레이북은 생성한 각 파일에 대한 작업을 포함하는 작업 목록을 사용합니다. become: true는 플레이 수준에서 설정되므로 모든 작업은 상승된 권한으로 실행됩니다.

    ---
    - name: Clean up managed files from the system
      hosts: localhost
      become: true
      tasks:
        - name: Remove the temporary info file
          ansible.builtin.file:
            path: /tmp/info.txt
            state: absent
    
        - name: Remove the custom MOTD file
          ansible.builtin.file:
            path: /etc/motd
            state: absent
    
        - name: Remove the custom issue file
          ansible.builtin.file:
            path: /etc/issue
            state: absent
    
        - name: Remove the issue.net symbolic link
          ansible.builtin.file:
            path: /etc/issue.net
            state: absent

    이 플레이북의 핵심은 각 작업에 있는 state: absent 매개변수입니다. 이는 file 모듈에 지정된 path의 항목이 존재하지 않도록 보장하도록 지시합니다. 파일을 찾으면 제거합니다. 파일이 이미 없으면 아무 작업도 수행하지 않아 멱등성 (idempotency) 을 유지합니다.

  4. 정리 플레이북을 실행합니다.

    ansible-playbook -i inventory.ini cleanup.yml

    출력에서는 각 작업이 파일을 제거하여 성공적으로 변경했음을 보여줍니다.

    PLAY [Clean up managed files from the system] **********************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Remove the temporary info file] ******************************************
    changed: [localhost]
    
    TASK [Remove the custom MOTD file] *********************************************
    changed: [localhost]
    
    TASK [Remove the custom issue file] ********************************************
    changed: [localhost]
    
    TASK [Remove the issue.net symbolic link] **************************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=5    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  5. 파일이 제거되었는지 확인합니다. ls 명령을 사용하여 존재 여부를 확인할 수 있습니다. 명령은 파일이 사라졌기 때문에 액세스할 수 없다는 오류를 보고합니다.

    ls /tmp/info.txt /etc/motd /etc/issue /etc/issue.net

    예상되는 출력은 일련의 오류 메시지로, 정리가 성공했음을 확인합니다.

    ls: cannot access '/tmp/info.txt': No such file or directory
    ls: cannot access '/etc/motd': No such file or directory
    ls: cannot access '/etc/issue': No such file or directory
    ls: cannot access '/etc/issue.net': No such file or directory

이제 Ansible 을 사용하여 파일을 제거하고 시스템을 정리하는 방법을 성공적으로 배웠으며, 생성부터 삭제까지 파일 관리의 전체 수명 주기를 완료했습니다.

요약

이 실습에서는 Ansible 을 사용하여 RHEL 시스템에서 파일 관리의 기본 사항을 배웠습니다. ansible.builtin.copy 모듈을 사용하여 특정 소유권 및 권한을 설정하면서 관리 대상 호스트로 정적 파일을 전송하는 것부터 시작했습니다. 그런 다음 lineinfile을 사용하여 특정 줄이 존재하도록 하고 blockinfile로 여러 줄의 텍스트 블록을 관리하여 기존 파일을 수정하는 방법을 탐색했습니다. 다룬 핵심 기술은 Jinja2 구문을 사용하여 시스템 정보 (facts) 로 채워진 사용자 지정 오늘의 메시지 (MOTD) 를 생성하는 ansible.builtin.template 모듈을 사용하여 동적 파일 콘텐츠를 생성하는 것이었습니다.

또한 ansible.builtin.file 모듈을 사용하여 지원 파일을 배포하고 심볼릭 링크를 생성하는 연습을 했습니다. 배포가 성공했는지 확인하기 위해 stat 모듈을 사용하여 파일의 상태 및 속성을 확인하고, fetch 모듈을 사용하여 로그와 같은 파일을 관리 대상 호스트에서 제어 노드로 다시 검색했습니다. 마지막으로, 실습 전반에 걸쳐 생성된 파일과 디렉토리를 제거하기 위해 state: absent와 함께 file 모듈을 사용하여 정리 작업을 수행하는 방법을 배웠으며, 관리 대상 호스트의 깨끗한 상태를 보장했습니다.