RHEL 에서의 Ansible 역할 및 컬렉션

AnsibleBeginner
지금 연습하기

소개

이 랩에서는 Ansible 역할 (Roles) 및 컬렉션 (Collections) 의 강력함과 재사용성을 활용하여 Red Hat Enterprise Linux (RHEL) 웹 서버 구성을 자동화하는 방법을 배우게 됩니다. 특정 구성을 배포하기 위한 사용자 정의 역할을 생성하고, Git 저장소에서 외부 역할을 종속성으로 통합하며, SELinux 와 같은 시스템 서비스를 관리하기 위해 사전 구축된 RHEL 시스템 역할을 Ansible 컬렉션에서 활용하여 포괄적인 자동화 워크플로우를 구축할 것입니다.

프로세스는 ansible-galaxy init을 사용하여 표준화된 역할 구조를 생성하는 것으로 시작됩니다. 그런 다음 requirements.yml 파일을 사용하여 Git 저장소에서 역할 종속성을 정의하고 설치합니다. RHEL 시스템 역할을 통합한 후, 사용자 정의 역할, Git 기반 역할, 컬렉션 기반 역할의 세 가지 유형의 역할을 단일 마스터 플레이북으로 조립합니다. 마지막으로 플레이북을 실행하고 Apache 웹 서버 및 SELinux 설정이 대상 RHEL 서버에 올바르게 적용되었는지 확인하여 완전하고 모듈화된 자동화 솔루션을 시연합니다.

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

ansible-galaxy init 으로 사용자 정의 Ansible 역할 생성

이 단계에서는 ansible-galaxy init 명령을 사용하여 새 Ansible 역할에 대한 표준화된 디렉터리 구조를 생성하는 것으로 시작합니다. Ansible 역할은 재사용 가능하고 체계적인 자동화 콘텐츠를 구축하는 데 기본적인 개념입니다. 역할을 통해 작업 (tasks), 핸들러 (handlers), 변수 (variables) 및 기타 구성 요소를 자체 포함되고 이식 가능한 단위로 패키징할 수 있습니다. 표준 구조를 사용하는 것은 자동화를 더 쉽게 이해하고 관리하며 공유할 수 있도록 하는 모범 사례입니다.

먼저 올바른 작업 디렉터리에 있는지 확인합니다. 이 랩의 모든 작업은 ~/project 디렉터리 내에서 수행됩니다.

cd ~/project

역할을 생성하기 전에 Ansible 명령줄 도구가 설치되어 있는지 확인해야 합니다. ansible-core 패키지는 ansible-galaxy를 포함한 필수 도구를 제공합니다.

dnf 패키지 관리자를 사용하여 ansible-core를 설치합니다. -y 플래그는 확인 프롬프트에 자동으로 "yes"로 응답합니다.

sudo dnf install -y ansible-core

패키지가 설치되고 종속성이 해결되고 있음을 나타내는 출력이 표시되어야 합니다.

...
Installed:
  ansible-core-2.16.x-1.el9.x86_64
  ...
Complete!

모든 프로젝트 역할을 전용 roles 디렉터리 내에 구성하는 것이 일반적인 관행입니다. 지금 이 디렉터리를 생성합니다.

mkdir roles

이제 새로 생성된 roles 디렉터리로 이동합니다. 이곳에서 새 사용자 정의 역할을 초기화합니다.

cd roles

이제 ansible-galaxy init 명령을 사용하여 apache.developer_configs라는 역할의 골격을 생성합니다. 이 명령은 표준 디렉터리와 파일 세트를 자동으로 생성하여 역할 개발을 위한 깔끔한 시작점을 제공합니다.

ansible-galaxy init apache.developer_configs

명령을 실행한 후 확인 메시지가 표시됩니다.

- Role apache.developer_configs was created successfully

방금 생성된 구조를 보려면 ls -R 명령을 사용할 수 있습니다. 이 명령은 디렉터리와 모든 하위 디렉터리의 내용을 재귀적으로 나열합니다.

ls -R apache.developer_configs

출력은 Ansible 역할의 표준 디렉터리 구조를 보여줍니다.

apache.developer_configs:
defaults  files  handlers  meta  README.md  tasks  templates  tests  vars

apache.developer_configs/defaults:
main.yml

apache.developer_configs/files:

apache.developer_configs/handlers:
main.yml

apache.developer_configs/meta:
main.yml

apache.developer_configs/tasks:
main.yml

apache.developer_configs/templates:

apache.developer_configs/tests:
inventory  test.yml

apache.developer_configs/vars:
main.yml

가장 중요한 디렉터리에 대한 간략한 개요는 다음과 같습니다.

  • tasks: 역할에 의해 실행될 작업의 주요 목록을 포함합니다.
  • handlers: 다른 작업에 의해 알림을 받을 때만 실행되는 작업인 핸들러를 포함합니다.
  • vars: 역할에 대한 변수를 포함합니다.
  • templates: Jinja2 템플릿 엔진을 사용하는 파일 템플릿을 포함합니다.
  • meta: 다른 역할에 대한 종속성을 포함하여 역할에 대한 메타데이터를 포함합니다.

이제 사용자 정의 Ansible 역할의 기본 구조를 성공적으로 생성했습니다. 다음 단계에서는 웹 서버를 구성하기 위해 이러한 디렉터리에 콘텐츠를 채울 것입니다.

requirements.yml 을 사용하여 Git 리포지토리에서 역할 종속성 설치

이 단계에서는 Git 저장소와 같은 외부 소스의 역할 종속성을 관리하는 방법을 배우게 됩니다. 이는 커뮤니티 또는 다른 팀에서 개발한 역할을 재사용하는 대규모 Ansible 프로젝트에서 일반적인 관행입니다. Ansible 은 일반적으로 requirements.yml이라는 파일을 사용하여 설치할 역할 목록을 정의합니다.

사용자 정의 역할인 apache.developer_configs는 웹 서버가 설치되고 실행되도록 보장하기 위해 기본적인 Apache 역할에 종속됩니다. 이 종속성을 정의하고 설치할 것입니다.

먼저 메인 프로젝트 디렉터리에 있는지 확인합니다. 이전 단계에서 roles 하위 디렉터리에 아직 있다면 ~/project로 돌아갑니다.

cd ~/project

이제 roles 디렉터리 안에 requirements.yml 파일을 생성합니다. 이 파일에는 프로젝트에 필요한 모든 외부 역할이 나열됩니다. nano 편집기를 사용하여 파일을 생성하고 편집합니다.

nano roles/requirements.yml

파일에 다음 내용을 추가합니다. 이 항목은 ansible-galaxy에게 공개 Git 저장소에서 특정 버전의 Apache 역할을 다운로드하여 로컬에서 infra.apache라는 이름으로 지정하도록 지시합니다.

- name: infra.apache
  src: https://github.com/geerlingguy/ansible-role-apache.git
  scm: git
  version: 3.2.0

이 정의를 자세히 살펴보겠습니다.

  • name: 역할의 로컬 이름입니다. 소스 저장소의 이름이 다르더라도 infra.apache라는 디렉터리에 설치됩니다.
  • src: Git 저장소의 소스 URL 입니다.
  • scm: 이 경우 git인 소스 제어 관리 도구를 지정합니다.
  • version: 사용할 특정 Git 브랜치, 태그 또는 커밋 해시입니다. 버전을 고정하는 것은 자동화의 안정성과 예측 가능성을 보장하는 데 중요합니다.

Ctrl+X를 누른 다음 Y를 누르고 Enter를 눌러 파일을 저장하고 nano를 종료합니다.

requirements.yml 파일이 준비되었으므로 이제 ansible-galaxy install 명령을 사용하여 역할을 다운로드하고 설치할 수 있습니다.

  • -r 플래그는 요구 사항 파일을 가리킵니다.
  • -p 플래그는 역할이 설치될 경로를 지정합니다.
ansible-galaxy install -r roles/requirements.yml -p roles

다운로드 및 설치 프로세스를 확인하는 출력이 표시됩니다.

Starting galaxy role install process
- downloading role 'ansible-role-apache', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-apache/archive/3.2.0.tar.gz
- extracting infra.apache to /home/labex/project/roles/infra.apache
- infra.apache (3.2.0) was installed successfully

역할이 올바르게 설치되었는지 확인하려면 roles 디렉터리의 내용을 나열합니다.

ls -l roles

이전 단계에서 생성한 apache.developer_configs 역할과 함께 infra.apache 디렉터리가 표시되어야 합니다.

total 12
drwxr-xr-x. 9 labex labex 4096 Nov 10 10:10 apache.developer_configs
drwxr-xr-x. 9 labex labex 4096 Nov 10 10:15 infra.apache
-rw-r--r--. 1 labex labex  118 Nov 10 10:12 requirements.yml

이제 외부 Git 저장소를 종속성으로 성공적으로 선언하고 프로젝트에 설치했습니다. 다음 단계는 이 종속성을 사용자 정의 역할의 메타데이터에 통합하는 것입니다.

Ansible 컬렉션에서 RHEL 시스템 역할 통합

이 단계에서는 역할, 모듈 및 플러그인을 포함한 Ansible 콘텐츠를 배포하는 표준 방식인 Ansible 컬렉션 (Collections) 을 사용합니다. SELinux 관리와 같은 일반적인 관리 작업을 자동화하는 데 유용한 모듈 세트를 제공하는 Community General 컬렉션을 설치합니다.

웹 서버 시나리오에서는 Apache 서비스가 비표준 포트에서 수신 대기할 수 있도록 SELinux 를 올바르게 구성해야 합니다. community.general 컬렉션에는 이 작업을 위한 완벽한 SELinux 모듈이 포함되어 있습니다.

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

cd ~/project

프로젝트를 자체 포함되도록 하려면 컬렉션을 프로젝트 디렉토리 내에 유지하는 것이 좋습니다. 이를 저장할 collections라는 디렉토리를 생성합니다.

mkdir collections

이제 ansible-galaxy collection install 명령을 사용하여 필요한 컬렉션을 설치합니다. -p 플래그는 방금 생성한 collections 디렉토리에 컬렉션을 설치하도록 명령에 지시합니다.

ansible-galaxy collection install community.general:7.5.0 ansible.posix:1.5.4 -p collections

이 명령은 컬렉션과 해당 종속성을 다운로드합니다. 다음과 유사한 출력이 표시됩니다.

Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'community.general:7.5.0' to '/home/labex/project/collections/ansible_collections/community/general'
Installing 'ansible.posix:1.5.4' to '/home/labex/project/collections/ansible_collections/ansible/posix'
...
community.general:7.5.0 was installed successfully
ansible.posix:1.5.4 was installed successfully

컬렉션이 이제 프로젝트에서 사용 가능한지 확인하려면 컬렉션 경로를 지정하여 설치된 모든 컬렉션을 나열할 수 있습니다.

ansible-galaxy collection list -p collections

출력에는 설치된 컬렉션과 프로젝트 내의 설치 경로가 표시됩니다.

## /home/labex/project/collections/ansible_collections
Collection              Version
----------------------- -------
ansible.posix           1.5.4
community.general       7.5.0

플레이북에서 컬렉션의 모듈을 사용할 때는 해당 모듈의 완전한 컬렉션 이름 (Fully Qualified Collection Name, FQCN) 으로 참조해야 합니다. SELinux 관리를 위해서는 SELinux 상태 관리에 ansible.posix.selinux를, SELinux 포트 관리에 community.general.seport를 사용합니다.

이제 SELinux 관리 모듈을 포함하는 강력한 컬렉션을 성공적으로 설치했습니다. 다음 단계에서는 사용자 정의 역할, Git 의 역할 및 이러한 컬렉션의 SELinux 모듈을 사용하여 개발 웹 서버를 완전히 구성하는 플레이북을 조립합니다.

사용자 정의, Git 및 시스템 역할을 사용하여 플레이북 조립 및 실행

이 단계에서는 준비한 모든 구성 요소, 즉 사용자 정의 역할, Git 의 종속성 및 RHEL 시스템 역할을 통합합니다. 이러한 역할을 오케스트레이션하여 개발 웹 서버를 완전히 구성하는 메인 플레이북을 생성합니다.

이 단계를 다양한 부품으로 복잡한 기계를 조립하는 것으로 생각하십시오. 각 역할은 특정 목적을 수행하며 함께 작동하여 완전한 웹 서버 환경을 만듭니다. 이를 관리 가능한 조각으로 나누어 보겠습니다.

먼저 메인 프로젝트 디렉토리에 있는지 확인하십시오.

cd ~/project

구성에 들어가기 전에 무엇을 만들고 있는지 이해해 봅시다.

  • Ansible 구성: Ansible 의 동작 방식과 파일 위치를 설정합니다.
  • 인벤토리: 관리할 서버를 정의합니다 (이 경우 localhost).
  • 변수: 역할에서 사용할 데이터를 저장합니다 (개발자 정보, SELinux 설정).
  • 사용자 정의 역할 콘텐츠: 개발자 환경을 구성할 실제 작업입니다.
  • 메인 플레이북: 모든 것을 올바른 순서로 실행하는 오케스트레이터입니다.

1. Ansible 구성 및 인벤토리 생성

ansible.cfg 파일은 Ansible 의 동작 방식을 알려주는 구성 파일과 같습니다. 이 파일이 없으면 모든 명령에서 경로와 옵션을 지정해야 합니다. 이 파일을 사용하면 Ansible 은 역할, 컬렉션 및 인벤토리의 위치를 자동으로 알게 됩니다.

nano를 사용하여 ansible.cfg 파일을 생성합니다. 이 파일은 Ansible 에 역할, 컬렉션 및 인벤토리의 위치를 알려줍니다.

nano ansible.cfg

다음 내용을 추가하십시오. 각 줄을 이해해 봅시다.

[defaults]
inventory = inventory
roles_path = roles
collections_paths = collections
host_key_checking = False

[privilege_escalation]
become = True

각 설정의 기능:

  • inventory = inventory: 매번 -i inventory를 입력하는 대신 Ansible 이 이 파일을 자동으로 사용합니다.
  • roles_path = roles: Ansible 은 roles 디렉토리에서 역할을 찾습니다.
  • collections_paths = collections: Ansible 은 설치된 컬렉션을 여기서 찾습니다.
  • host_key_checking = False: 실험실 환경에서 SSH 키 확인 오류를 방지합니다.
  • become = True: 필요한 경우 권한이 상승된 상태로 작업을 자동으로 실행합니다.

nano를 저장하고 종료합니다 (Ctrl+X를 누른 다음 Y를 누르고 Enter를 누릅니다).

인벤토리 파일은 Ansible 이 관리할 머신을 알려줍니다. 이 경우 로컬 머신을 구성합니다.

nano inventory

다음 줄을 추가하십시오.

localhost ansible_connection=local

이것의 의미:

  • localhost: 대상 호스트의 이름입니다.
  • ansible_connection=local: SSH 대신 로컬 연결을 사용합니다 (Ansible 을 실행하는 동일한 머신을 관리하는 경우).

nano를 저장하고 종료합니다.

2. 역할 변수 정의

Ansible 의 변수는 역할에서 사용할 수 있는 설정과 같습니다. 작업에 사용자 이름이나 포트 번호와 같은 값을 하드코딩하는 대신 변수 파일에 정의합니다. 이렇게 하면 자동화가 유연하고 재사용 가능해집니다.

group_vars/all 디렉토리는 모든 호스트에 적용되는 변수를 Ansible 이 자동으로 로드하는 특별한 위치입니다. 이 디렉토리의 모든 YAML 파일은 플레이북 및 역할에서 사용할 수 있습니다.

모든 호스트에 적용되는 변수에 대한 디렉토리 구조를 생성합니다.

mkdir -p group_vars/all

이제 개발자 정보를 정의하는 파일을 생성합니다. 이 데이터는 사용자 정의 역할에서 사용자 계정 및 웹 구성을 만드는 데 사용됩니다.

nano group_vars/all/developers.yml

다음 내용을 추가하십시오.

---
web_developers:
  - username: jdoe ## 첫 번째 개발자
    port: 9081 ## 이 개발자의 웹사이트에 대한 사용자 정의 포트
  - username: jdoe2 ## 두 번째 개발자
    port: 9082 ## 이 개발자의 웹사이트에 대한 사용자 정의 포트

이 데이터 구조의 의미:

  • web_developers: 개발자 정보를 포함하는 목록입니다.
  • 각 개발자에는 usernameport가 있습니다.
  • 사용자 정의 역할은 이 목록을 반복하여 각 개발자에 대한 구성을 생성합니다.

저장하고 종료합니다.

다음으로 SELinux 구성에 대한 변수 파일을 생성합니다. SELinux (Security-Enhanced Linux) 는 애플리케이션이 수행할 수 있는 작업을 제어하는 보안 모듈입니다.

nano group_vars/all/selinux.yml

다음 내용을 추가하십시오.

---
selinux_state: enforcing ## SELinux 를 enforcing 모드로 설정 (최고 보안)
selinux_ports: ## Apache 가 사용할 수 있도록 허용할 포트 목록
  - ports: "9081" ## 포트 9081 허용
    proto: "tcp" ## 프로토콜: TCP
    setype: "http_port_t" ## SELinux 유형: HTTP 포트
    state: "present" ## 이 규칙 추가
  - ports: "9082" ## 포트 9082 허용
    proto: "tcp" ## 프로토콜: TCP
    setype: "http_port_t" ## SELinux 유형: HTTP 포트
    state: "present" ## 이 규칙 추가

SELinux 설정 이해:

  • selinux_state: enforcing: SELinux 는 승인되지 않은 작업을 적극적으로 차단합니다.
  • selinux_ports: 포트 구성 목록입니다.
  • http_port_t: Apache 가 포트에 바인딩할 수 있도록 허용하는 SELinux 유형입니다.
  • 기본적으로 Apache 는 포트 80 및 443 만 사용할 수 있습니다. 9081 및 9082 를 명시적으로 허용해야 합니다.

저장하고 종료합니다.

3. 사용자 정의 역할 채우기

apache.developer_configs 역할에는 현재 디렉토리 구조는 있지만 실제 콘텐츠는 없습니다. 다음을 추가해야 합니다.

  • 템플릿: 변수를 포함할 수 있는 파일 (Jinja2 구문 사용).
  • 작업: Ansible 이 수행할 실제 작업입니다.
  • 핸들러: 알림을 받을 때만 실행되는 특수 작업입니다 (서비스 다시 시작 등).
  • 메타데이터: 역할 종속성에 대한 정보입니다.

템플릿을 사용하면 변수에 따라 조정되는 구성 파일을 만들 수 있습니다. .j2 확장자는 Jinja2 템플릿임을 나타냅니다.

nano roles/apache.developer_configs/templates/developer.conf.j2

다음 내용을 추가하십시오.

{% for dev in web_developers %}
Listen {{ dev.port }}
<VirtualHost *:{{ dev.port }}>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/{{ dev.username }}

    <Directory /var/www/{{ dev.username }}>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>
</VirtualHost>
{% endfor %}

템플릿 구문 이해:

  • {% for dev in web_developers %}: 개발자 목록을 반복합니다.
  • {{ dev.port }}: 이 개발자의 포트 번호를 삽입합니다.
  • {{ dev.username }}: 이 개발자의 사용자 이름을 삽입합니다.
  • {% endfor %}: 루프를 종료합니다.
  • 결과는 각 개발자에 대한 별도의 가상 호스트 구성이 됩니다.

이것이 만드는 것: 두 개발자의 경우 이 템플릿은 다음과 같은 Apache 구성을 생성합니다.

  1. Apache 가 포트 9081 및 9082 에서 수신 대기하도록 합니다.
  2. /var/www/jdoe/var/www/jdoe2에서 콘텐츠를 제공하는 가상 호스트를 생성합니다.
  3. 각 디렉토리에 대한 적절한 권한을 설정합니다.

저장하고 종료합니다.

작업은 Ansible 이 수행하는 실제 작업입니다. 각 작업은 특정 작업을 수행하기 위해 Ansible 모듈을 사용합니다.

nano roles/apache.developer_configs/tasks/main.yml

다음 내용을 추가하고 각 작업을 이해해 봅시다.

---
## 작업 1: 각 개발자에 대한 사용자 계정 생성
- name: Create developer user accounts
  ansible.builtin.user: ## 'user' 모듈 사용
    name: "{{ item.username }}" ## 이 이름으로 사용자 생성
    state: present ## 사용자가 존재하는지 확인
  loop: "{{ web_developers }}" ## 목록의 각 개발자에 대해 이 작업 수행

## 작업 2: 각 개발자에 대한 웹 디렉토리 생성
- name: Create developer web root directories
  ansible.builtin.file: ## 'file' 모듈 사용
    path: "/var/www/{{ item.username }}" ## 이 디렉토리 생성
    state: directory ## 디렉토리인지 확인
    owner: "{{ item.username }}" ## 소유자 설정
    group: "{{ item.username }}" ## 그룹 설정
    mode: "0755" ## 권한 설정 (rwxr-xr-x)
  loop: "{{ web_developers }}"

## 작업 3: 각 개발자에 대한 샘플 웹페이지 생성
- name: Create a sample index.html for each developer
  ansible.builtin.copy: ## 'copy' 모듈 사용
    content: "Welcome to {{ item.username }}'s dev space\n" ## 파일 내용
    dest: "/var/www/{{ item.username }}/index.html" ## 파일 위치
    owner: "{{ item.username }}" ## 파일 소유자
    group: "{{ item.username }}" ## 파일 그룹
    mode: "0644" ## 파일 권한 (rw-r--r--)
  loop: "{{ web_developers }}"

## 작업 4: Apache 구성 파일 배포
- name: Deploy developer apache configs
  ansible.builtin.template: ## 'template' 모듈 사용
    src: developer.conf.j2 ## 소스 템플릿 파일
    dest: /etc/httpd/conf.d/developer.conf ## 서버의 대상
    mode: "0644" ## 파일 권한
  notify: restart apache ## 변경 시 restart apache 핸들러 트리거

주요 개념 이해:

  • loop: 목록의 각 항목에 대해 작업을 반복합니다.
  • {{ item.username }}: 루프에서 현재 항목의 사용자 이름을 참조합니다.
  • notify: restart apache: 이 작업이 변경되면 "restart apache"라는 핸들러를 트리거합니다.
  • 파일 권한: 0755는 소유자가 읽기/쓰기/실행 가능하고 다른 사용자는 읽기/실행 가능함을 의미합니다. 0644는 소유자가 읽기/쓰기 가능하고 다른 사용자는 읽기만 가능함을 의미합니다.

저장하고 종료합니다.

핸들러는 다른 작업에서 알림을 받을 때만 실행되는 특수 작업입니다. 일반적으로 서비스 다시 시작과 같은 작업에 사용됩니다.

nano roles/apache.developer_configs/handlers/main.yml

다음 내용을 추가하십시오.

---
- name: restart apache ## 이 이름은 notify: 문과 일치해야 합니다.
  ansible.builtin.service: ## 'service' 모듈 사용
    name: httpd ## 서비스 이름 (Apache 는 RHEL 에서 'httpd'라고 합니다)
    state: restarted ## 서비스 다시 시작

핸들러를 사용하는 이유:

  • 효율성: 구성이 실제로 변경된 경우에만 서비스가 다시 시작됩니다.
  • 순서: 모든 작업이 먼저 실행된 다음 모든 핸들러가 마지막에 실행됩니다.
  • 멱등성: 여러 작업이 동일한 핸들러를 알릴 수 있지만 한 번만 실행됩니다.

저장하고 종료합니다.

마지막으로 사용자 정의 역할이 이전에 설치한 infra.apache 역할에 종속된다는 것을 Ansible 에 알려야 합니다.

nano roles/apache.developer_configs/meta/main.yml

파일의 내용을 다음으로 바꾸십시오.

---
dependencies:
  - role: infra.apache ## 이 역할은 사용자 정의 역할보다 먼저 실행되어야 합니다.

이것이 하는 일:

  • Ansible 이 apache.developer_configs를 실행하면 infra.apache를 먼저 자동으로 실행합니다.
  • 이렇게 하면 사용자 정의 구성을 추가하기 전에 Apache 가 설치되고 구성됩니다.
  • 종속성은 나열된 순서대로 실행됩니다.

저장하고 종료합니다.

4. 메인 플레이북 조립 및 실행

플레이북은 Ansible 에 무엇을 해야 하는지, 어떤 순서로 해야 하는지를 알려주는 레시피와 같습니다. 플레이북은 다음을 수행합니다.

  1. SELinux 설정 구성 (pre_tasks).
  2. 역할 실행 (종속성 체인 포함).

메인 플레이북 파일을 생성합니다.

nano web_dev_server.yml

자세한 설명과 함께 다음 내용을 추가하십시오.

---
- name: Configure Dev Web Server ## 플레이북 이름
  hosts: localhost ## localhost 에서 실행
  pre_tasks: ## 역할 전에 실행되는 작업
    ## 작업 1: SELinux 모드 구성
    - name: Set SELinux to enforcing mode
      ansible.posix.selinux: ## ansible.posix 컬렉션의 모듈
        policy: targeted ## 'targeted' SELinux 정책 사용
        state: "{{ selinux_state }}" ## 정의한 변수 사용
      when: selinux_state is defined ## 변수가 정의된 경우에만 실행

    ## 작업 2: SELinux 포트 구성
    - name: Configure SELinux ports for Apache
      community.general.seport: ## community.general 컬렉션의 모듈
        ports: "{{ item.ports }}" ## 포트 번호
        proto: "{{ item.proto }}" ## 프로토콜 (tcp)
        setype: "{{ item.setype }}" ## SELinux 유형 (http_port_t)
        state: "{{ item.state }}" ## present 또는 absent
      loop: "{{ selinux_ports }}" ## 포트 목록 반복
      when: selinux_ports is defined ## 변수가 정의된 경우에만 실행

  roles: ## 실행할 역할
    - apache.developer_configs ## 사용자 정의 역할 (infra.apache 트리거)

실행 순서 이해:

  1. pre_tasks: SELinux 구성이 먼저 실행됩니다.
  2. roles: 역할 종속성이 실행되고 (infra.apache), 사용자 정의 역할이 실행됩니다.
  3. handlers: 알림을 받은 핸들러가 마지막에 실행됩니다.

이 순서가 중요한 이유:

  • Apache 가 사용자 정의 포트에 바인딩을 시도하기 전에 SELinux 를 구성해야 합니다.
  • 가상 호스트를 구성하기 전에 Apache 를 설치해야 합니다.
  • 모든 구성이 완료된 후에 서비스 다시 시작이 발생합니다.

저장하고 종료합니다.

이제 완전한 자동화를 실행할 준비가 되었습니다.

ansible-playbook web_dev_server.yml

플레이북이 실행되고 자세한 출력이 표시됩니다. 예상되는 내용은 다음과 같습니다 (예시).

PLAY [Configure Dev Web Server] *************************************************

TASK [Gathering Facts] **********************************************************
ok: [localhost]                     ## Ansible이 시스템 정보를 수집합니다.

TASK [Set SELinux to enforcing mode] *******************************************
changed: [localhost]                ## SELinux 모드가 변경되었습니다.

TASK [Configure SELinux ports for Apache] **************************************
changed: [localhost] => (item={'ports': '9081', 'proto': 'tcp', 'setype': 'http_port_t', 'state': 'present'})
changed: [localhost] => (item={'ports': '9082', 'proto': 'tcp', 'setype': 'http_port_t', 'state': 'present'})

TASK [infra.apache : Ensure Apache is installed.] *******************************
changed: [localhost]                ## Apache 패키지가 설치되었습니다.

TASK [apache.developer_configs : Create developer user accounts] ****************
changed: [localhost] => (item={'username': 'jdoe', 'port': 9081})
changed: [localhost] => (item={'username': 'jdoe2', 'port': 9082})

TASK [apache.developer_configs : Create developer web root directories] *********
changed: [localhost] => (item={'username': 'jdoe', 'port': 9081})
changed: [localhost] => (item={'username': 'jdoe2', 'port': 9082})

TASK [apache.developer_configs : Create a sample index.html for each developer] *
changed: [localhost] => (item={'username': 'jdoe', 'port': 9081})
changed: [localhost] => (item={'username': 'jdoe2', 'port': 9082})

TASK [apache.developer_configs : Deploy developer apache configs] ***************
changed: [localhost]                ## 구성 파일이 생성되었습니다.

RUNNING HANDLER [apache.developer_configs : restart apache] *********************
changed: [localhost]                ## Apache가 다시 시작되었습니다.

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

다양한 소스의 여러 역할을 결합하여 완전한 웹 개발 환경을 만들기 위해 복잡한 플레이북을 성공적으로 조립하고 실행했습니다!

RHEL 서버에서 SELinux 및 Apache 구성 확인

이 마지막 단계에서는 Ansible 자동화가 시스템을 올바르게 구성했는지 확인합니다. 서비스가 예상대로 실행되고 있는지, 보안 정책 (SELinux) 이 올바르게 적용되었는지 확인하는 것이 중요합니다. 표준 RHEL 명령줄 도구를 사용하여 시스템 상태를 검사합니다.

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

cd ~/project

1. SELinux 구성 확인

컬렉션의 SELinux 모듈은 SELinux 모드를 enforcing으로 설정하고 http_port_t 유형에 새 포트를 허용하도록 구성되었습니다.

sestatus 명령을 사용하여 현재 SELinux 상태를 확인합니다.

sestatus

출력에는 SELinux 가 활성화되어 있고 enforcing 모드에 있음을 표시해야 합니다.

SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      33

다음으로 semanage port 명령을 사용하여 포트 90819082http_port_t 컨텍스트에 추가되었는지 확인합니다. 출력을 grep으로 파이프하여 관련 줄을 찾을 수 있습니다.

sudo semanage port -l | grep http_port_t

기본 HTTP 포트 중에서 사용자 정의 포트가 나열된 것을 볼 수 있어야 합니다. 정확한 출력은 다를 수 있지만 정의한 포트가 포함됩니다.

http_port_t                    tcp      9082, 9081, 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988

이는 SELinux 모듈이 정책을 성공적으로 업데이트했음을 확인합니다.

2. Apache 서비스 및 구성 확인

infra.apache 역할은 httpd 서비스를 설치하고 시작했습니다. 이 컨테이너 환경에서는 systemctl을 사용할 수 없으므로 ps를 사용하여 실행 중인 프로세스를 확인할 수 있습니다.

ps aux | grep httpd

여러 httpd 프로세스가 실행 중인 것을 볼 수 있으며, 이는 서비스가 활성 상태임을 나타냅니다.

root        8851  0.2  0.4  25652 16228 ?        Ss   09:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache      8852  0.0  0.1  25308  6044 ?        S    09:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache      8853  0.0  0.3 1443348 11364 ?       Sl   09:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache      8854  0.0  0.3 1443348 11480 ?       Sl   09:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache      8855  0.0  0.4 1574484 15848 ?       Sl   09:31   0:00 /usr/sbin/httpd -DFOREGROUND
labex       9298  0.0  0.0   6408  2176 pts/3    S+   09:31   0:00 grep --color=auto httpd

3. 웹 콘텐츠 접근성 확인

마지막으로 가장 중요한 테스트는 개발자 웹사이트에 액세스할 수 있는지 확인하는 것입니다. apache.developer_configs 역할은 포트 90819082에 가상 호스트를 설정했습니다. curl 명령을 사용하여 각 엔드포인트의 콘텐츠를 요청합니다.

먼저 포트 9081에서 사용자 jdoe의 사이트를 테스트합니다.

curl http://localhost:9081

예상되는 출력은 이 사용자를 위해 생성한 index.html 파일의 내용입니다.

Welcome to jdoe's dev space

다음으로 포트 9082에서 사용자 jdoe2의 사이트를 테스트합니다.

curl http://localhost:9082

해당 환영 메시지가 표시되어야 합니다.

Welcome to jdoe2's dev space

이러한 성공적인 curl 명령은 Apache 가 올바르게 구성되었고, 가상 호스트가 작동 중이며, SELinux 정책이 사용자 정의 포트의 트래픽을 허용하고 있음을 확인합니다.

축하합니다! 사용자 정의 역할, Git 리포지토리의 역할 및 Ansible 컬렉션의 SELinux 모듈을 결합하여 안전한 멀티 테넌트 개발 웹 서버를 구성하는 완전한 Ansible 자동화 프로젝트를 성공적으로 구축했습니다.

요약

이 랩에서는 Ansible 역할 (Roles) 및 컬렉션 (Collections) 의 강력함과 구조를 활용하여 RHEL 웹 서버 구성을 자동화하는 방법을 배웁니다. 재사용 가능한 자동화 콘텐츠를 위한 표준화된 디렉터리 구조를 설정하는 ansible-galaxy init 명령을 사용하여 처음부터 사용자 정의 역할을 생성하는 것으로 시작합니다. 이 기초 단계는 더 복잡한 자동화 작업을 위한 기반을 마련합니다.

사용자 정의 역할을 기반으로, requirements.yml 파일을 통해 Git 리포지토리의 역할과 Ansible 컬렉션의 공식 RHEL 시스템 역할을 포함한 외부 종속성을 통합합니다. 마지막으로 이러한 다양한 유형의 역할 (사용자 정의, Git 기반, 시스템) 을 단일 플레이북으로 조립하고, 서버를 구성하기 위해 실행하며, 결과적인 Apache 및 SELinux 설정을 확인하여 자동화가 성공했는지 확인합니다.