AWX를 처음 접하시면 인터페이스와 설정 과정이 생소할 수 있지만, 한 번 구성해두면 자동화의 강력함을 체감하실 수 있습니다. 요청하신 두 가지 타입의 플레이북과 이를 실행하기 위한 Execution Environment(EE) 구성 파일을 정리해 드립니다.
resource_check.yml)대상 서버의 OS, 재기동 기록, 하드웨어 자원(CPU, Mem, Disk, NIC)을 수집하여 보기 좋게 출력합니다.
---
- name: 대상 노드 자원 정보 점검
hosts: all
gather_facts: yes
tasks:
- name: 물리 네트워크 인터페이스 및 디스크 정보 추출
set_fact:
physical_nics: "{{ ansible_interfaces | map('extract', ansible_facts) | selectattr('active', 'defined') | selectattr('type', 'defined') | selectattr('type', 'equalto', 'ether') | list }}"
last_boot: "{{ ansible_facts['last_boot'] if 'last_boot' in ansible_facts else 'N/A' }}"
- name: 자원 정보 요약 출력
debug:
msg:
- "################ [ Resource Summary ] ################"
- "OS Version: {{ ansible_distribution }} {{ ansible_distribution_version }}"
- "Last Boot: {{ ansible_date_time.date }} {{ ansible_date_time.time }} (System Up)"
- "CPU Cores: {{ ansible_processor_vcpus }} vCPU"
- "Memory Total: {{ (ansible_memtotal_mb / 1024) | round(2) }} GB"
- "---------------- [ Network (Physical) ] ----------------"
- "{{ physical_nics | map(attribute='device') | list }}"
- "---------------- [ Disk & Partition ] ----------------"
- "{{ ansible_mounts | map(attribute='device') | zip(ansible_mounts | map(attribute='mount')) | list }}"
- "######################################################"
storage_check.yml)mc와 kubectl directpv 명령어를 사용하며, AWX에서 실행 시 관련 바이너리가 EE에 포함되어 있어야 합니다.
---
- name: Object Store 및 DirectPV 상태 점검
hosts: localhost # 보통 k8s 제어 노드나 bastion에서 실행
gather_facts: no
tasks:
- name: MinIO Admin 정보 확인
shell: "mc admin info myminio"
register: mc_info
- name: DirectPV 기본 정보 및 드라이브/볼륨 리스트 조회
shell: |
kubectl directpv info
kubectl directpv list drives -owide
kubectl directpv list volumes -owide
register: directpv_info
- name: 점검 결과 출력
debug:
msg:
- "==== MinIO Info ===="
- "{{ mc_info.stdout }}"
- "==== DirectPV Info ===="
- "{{ directpv_info.stdout }}"
AWX에서 위 플레이북(특히 mc, kubectl 사용 시)을 안정적으로 실행하려면 필요한 도구가 포함된 커스텀 이미지가 필요합니다. ansible-builder를 사용하여 빌드합니다.
version: 3
images:
base_image:
name: quay.io/ansible/ansible-runner:latest
dependencies:
ansible_core:
package_pip: ansible-core
ansible_network:
collections:
- kubernetes.core
- community.general
system:
- curl
- git
python:
- kubernetes
- pyyaml
additional_build_steps:
append_base:
- RUN curl https://dl.min.io/client/mc/release/linux-amd64/mc -o /usr/local/bin/mc && chmod +x /usr/local/bin/mc
- RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
- RUN curl -L https://github.com/minio/directpv/releases/latest/download/directpv_linux_amd64 -o /usr/local/bin/kubectl-directpv && chmod +x /usr/local/bin/kubectl-directpv
위 파일들이 있는 디렉토리에서 아래 명령어를 실행하여 이미지를 생성합니다.
ansible-builder build -t my-custom-awx-ee:v1.0
이후 생성된 이미지를 Docker Hub나 사내 Registry에 Push하고, AWX UI의 Execution Environments 메뉴에서 해당 이미지 주소를 등록해 사용하시면 됩니다.
혹시 AWX에서 Inventory 설정이나 Credentials(SSH 키, Kubeconfig 등) 등록 과정에서 막히는 부분이 있다면 말씀해 주세요. 상세히 가이드해 드리겠습니다.
===
AWX를 BitBucket과 연동하여 사용하실 예정이라면, 단순히 파일만 올리는 것이 아니라 "코드(Playbook) - 대상(Inventory) - 권한(Credentials)" 세 요소를 유기적으로 연결하는 과정이 필요합니다.
초보자분들이 가장 많이 헷갈려 하시는 설정 순서대로 가이드를 정리해 드립니다.
AWX가 외부 시스템(BitBucket, 대상 서버, Kubernetes)에 접속하기 위한 "열쇠"를 먼저 만들어야 합니다. Resources > Credentials 메뉴에서 등록합니다.
root 또는 ansible-user)kubectl config view --raw 결과물이나 ServiceAccount의 Token을 입력합니다.mc, directpv) 실행 시 kubectl 명령어가 동작하기 위해 필요합니다.이제 BitBucket에 올려둔 플레이북 파일을 AWX로 가져옵니다. Resources > Projects 메뉴로 이동합니다.
어떤 서버를 점검할지 정의하는 단계입니다. Resources > Inventories 메뉴에서 생성합니다.
web-servers, db-servers 식으로 그룹화할 수 있습니다.localhost 점검용(DirectPV 등)이라면 별도 등록 없이 기본 Demo Inventory의 호스트를 써도 무방하지만, 관리를 위해 따로 만드시는 것이 좋습니다.마지막으로 모든 요소를 하나로 묶어 "실행 버튼"을 만드는 과정입니다. Resources > Templates 메뉴에서 Add job template을 누릅니다.
resource_check.yml 선택.yml 파일들이 있는 것이 가장 관리하기 편합니다.이제 Templates 메뉴에서 생성한 템플릿 옆의 로켓 아이콘(Launch)을 누르면 실행됩니다. 혹시 특정 단계에서 에러 메시지가 나온다면 해당 로그를 알려주세요. 바로 해결해 드릴 수 있습니다.
다음으로 AWX의 Webhook 기능을 이용해 BitBucket에 푸시하면 자동으로 점검이 돌아가게 설정해 볼까요?
===
BitBucket에 코드를 push할 때마다 AWX의 Job이 자동으로 실행되게 하려면 Webhook 설정이 핵심입니다. 이 과정은 크게 AWX에서의 설정과 BitBucket에서의 설정 두 단계로 나뉩니다.
상세한 설정 방법을 안내해 드립니다.
먼저 실행하고자 하는 Job Template에서 Webhook 기능을 켜고 인증 키를 생성해야 합니다.
BitBucket을 선택합니다.이제 BitBucket 레포지토리로 가서 AWX로 신호를 보내도록 설정합니다.
AWX-Auto-Check (자유롭게 입력)Repository: Push가 체크되어 있는지 확인합니다.설정이 완료되면 다음과 같은 흐름으로 자동 점검이 수행됩니다.
git push를 합니다./etc/tower/settings.py 등)에서 Webhook 호출을 허용하는 설정이 기본적으로 켜져 있는지 확인하세요. (대부분 기본으로 활성화되어 있습니다.)main 또는 prod)에 대해서만 동작하도록 필터링할 수 있습니다.이제 BitBucket에 간단한 주석만 추가해서 push 해보세요. AWX의 Jobs 메뉴에서 프로젝트 업데이트와 플레이북 실행이 자동으로 돌아가는 것을 확인하실 수 있습니다!
===
Minio AISTor와 같은 복잡한 인프라 작업을 AWX에서 관리하려면, 재사용성과 확장성이 가장 중요합니다. 특히 Pre-check와 Post-check는 설치, 업그레이드 등 모든 작업에 공통으로 쓰이기 때문에 이를 모듈화하는 구조가 효율적입니다.
AWX(Ansible)의 베스트 프랙티스에 맞춘 BitBucket 디렉토리 구조를 제안해 드립니다.
.
├── inventories/ # 환경별 대상 서버 정의 (Dev, Staging, Prod)
│ ├── dev_inventory.yml
│ └── prod_inventory.yml
├── roles/ # 재사용 가능한 작업 단위 (핵심 로직)
│ ├── minio_check/ # 점검 공통 로직
│ │ ├── tasks/
│ │ │ ├── main.yml # 진입점
│ │ │ ├── pre_check.yml
│ │ │ └── post_check.yml
│ │ └── templates/ # 점검 결과 보고서 템플릿
│ │ └── check_report.j2
│ └── aistor_ops/ # 설치, 업그레이드 등 실제 작업 로직
├── group_vars/ # 그룹별 변수 (Minio 설정값 등)
│ └── all.yml
├── playbooks/ # AWX Job Template에서 선택할 실행 파일
│ ├── deploy_aistor.yml # 설치 전체 프로세스
│ ├── upgrade_aistor.yml # 업그레이드 전체 프로세스
│ └── health_check.yml # 단순 상태 점검용
└── ansible.cfg # Ansible 설정 (Role 경로 등)
AWX에서 하나의 Job으로 [Pre-check → Main Task → Post-check]가 물 흐르듯 이어지게 하려면, roles를 적극 활용해야 합니다.
playbooks/deploy_aistor.yml---
- name: Minio AISTor 배포 및 전후 점검
hosts: aistor_nodes
become: yes
tasks:
- name: [Pre-check] 인프라 및 OS 상태 확인
include_role:
name: minio_check
tasks_from: pre_check.yml
- name: [Main] AISTor 설치 작업 수행
include_role:
name: aistor_ops
tasks_from: install.yml
- name: [Post-check] 서비스 정상 동작 확인
include_role:
name: minio_check
tasks_from: post_check.yml
pre_check.yml)/data 파티션 마운트 여부 및 가용 용량 확인limits.conf (nofile) 설정값 확인post_check.yml)mc admin info를 통한 클러스터 헬스 체크/var/log/messages 내 치명적 에러 발생 여부 스캔include_role의 tasks_from을 변수로 처리하면 템플릿 수를 줄일 수 있습니다.debug)하는 것에 그치지 않고, template 모듈을 사용해 서버 내 특정 경로에 타임스탬프가 찍힌 리포트 파일로 남기면 추후 이력 관리에 용이합니다.fail 모듈을 사용해 작업을 중단시켜야 합니다. (잘못된 상태에서 설치/업그레이드가 진행되는 것을 방지)이 구조로 BitBucket을 구성하시면, AWX에서 프로젝트 싱크를 잡았을 때 아주 깔끔하게 관리될 것입니다.
이제 구체적인 점검 항목 중 하나(예: Disk 상태 체크)를 실제 Ansible 코드로 짜드릴까요?
===
AWX에서 작업을 설정할 때, BitBucket에 올린 디렉토리 구조가 각각 어떤 메뉴와 연결되는지 매핑해 드리겠습니다. 이 흐름을 이해하면 AWX의 전체적인 동작 메커니즘이 한눈에 들어오실 겁니다.
| AWX 설정 단계 | 연계되는 디렉토리 / 파일 | 역할 및 설명 |
|---|---|---|
| 1. Project | Root (레포지토리 전체) | BitBucket 주소를 등록하면 레포지토리 전체를 AWX 로컬 저장소로 가져옵니다. |
| 2. Inventory | inventories/ | AWX UI에서 인벤토리를 만들 때, 'Sources'를 'Sourcing from Project'로 선택하면 inventories/*.yml 파일을 리스트업하여 대상 서버 정보를 가져옵니다. |
| 3. Credentials | (파일 연계 없음) | SSH 키나 Kubeconfig는 보안상 파일로 두지 않고 AWX DB에 직접 저장합니다. |
| 4. Job Template | playbooks/ | 템플릿 설정 시 'Playbook' 드롭다운 메뉴에 playbooks/ 폴더 안의 .yml 파일들이 나타납니다. 여기서 실행할 파일을 선택합니다. |
| 5. Execution (실행) | roles/, group_vars/, ansible.cfg | 플레이북이 실행될 때, Ansible 엔진이 자동으로 roles/에서 로직을 찾고 group_vars/에서 설정값을 불러오며 ansible.cfg에 정의된 규칙을 따릅니다. |
inventories/)AWX UI에서 서버 IP를 일일이 타이핑하지 마세요.
Inventories > [생성한 인벤토리] > Sources > AddSourced from a Project로 선택하고 위에서 만든 프로젝트를 지정합니다.inventories/prod_inventory.yml 파일 내용이 AWX Host 리스트로 자동 업데이트됩니다.playbooks/ ↔ roles/)사용자가 Job Template에서 deploy_aistor.yml을 실행하면 다음과 같은 내부 연계가 일어납니다.
group_vars/all.yml에 정의된 MinIO 포트 번호, 관리자 계정 등의 변수를 읽어옵니다.ansible.cfg를 읽어 Role 경로(roles_path) 등을 세팅합니다.playbooks/deploy_aistor.yml 파일 내에 적힌 코드가 실행됩니다.roles:
- minio_check # roles/minio_check/tasks/main.yml을 실행roles/minio_check/tasks/pre_check.yml 등을 순차적으로 호출하며 작업을 진행합니다.templates/)작업이 끝난 후 점검 결과를 리포트로 만들 때 연계됩니다.
template 모듈 사용.src: check_report.j2라고 명시하면 Ansible은 자동으로 roles/minio_check/templates/check_report.j2 파일을 찾아 내용을 채운 뒤 서버에 저장합니다.Project, Inventory(Source), Job Template(Playbook)roles/, group_vars/, ansible.cfg이렇게 구조화하면, 나중에 새로운 점검 항목이 생겨도 Role 폴더 안의 파일만 수정해서 BitBucket에 push하면 AWX 설정 변경 없이 바로 적용되는 편리함을 누릴 수 있습니다.
혹시 첫 번째로 inventories/ 폴더 안에 들어갈 샘플 인벤토리 파일 내용을 작성해 드릴까요? (대상 서버 IP 등을 어떻게 적어야 할지 등)
===
BitBucket 디렉토리 구조의 핵심이 되는 인벤토리와 설정 파일 샘플을 작성해 드립니다. 이 파일들은 AWX가 "어디에(Inventory)", "어떤 설정으로(ansible.cfg)", "어떤 값들을(group_vars)" 사용하여 작업을 수행할지 결정하는 기준이 됩니다.
inventories/dev_inventory.yml (샘플 인벤토리)YAML 형식을 사용하면 그룹화와 변수 할당이 직관적입니다. MinIO 노드들과 관리용 로컬 호스트를 구분하여 작성합니다.
---
all:
children:
# MinIO AISTor가 설치될 대상 서버 그룹
aistor_nodes:
hosts:
minio-node-01:
ansible_host: 192.168.1.10
minio-node-02:
ansible_host: 192.168.1.11
minio-node-03:
ansible_host: 192.168.1.12
vars:
node_type: storage
# mc 명령어 및 kubectl을 실행할 관리 노드 (보통 bastion 또는 localhost)
management_nodes:
hosts:
localhost:
ansible_connection: local
ansible.cfg (Ansible 설정 파일)레포지토리 최상단(Root)에 위치하며, AWX가 실행될 때 Role의 경로와 실행 옵션을 정의합니다.
[defaults]
# Role이 위치한 경로를 지정 (AWX가 roles 폴더를 인식하게 함)
roles_path = ./roles
# SSH 연결 시 호스트 키 검사를 건너뜀 (처음 접속하는 서버 대응)
host_key_checking = False
# 결과 출력 시 가독성을 높이기 위한 설정
stdout_callback = yaml
bin_ansible_callbacks = True
# 작업 병렬 실행 개수
forks = 10
[privilege_escalation]
# 모든 작업에서 sudo 권한 사용 여부
become = True
become_method = sudo
become_user = root
become_ask_pass = False
group_vars/all.yml (공통 변수 설정)모든 플레이북에서 공통으로 참조할 MinIO 설정값들을 정의합니다. 여기에 적힌 변수들은 {{ minio_port }}와 같은 방식으로 플레이북 내에서 사용됩니다.
---
# MinIO 서비스 관련 설정
minio_port: 9000
minio_console_port: 9001
minio_root_user: "admin"
# 실제 운영 시 password는 AWX의 'Survey'나 'Vault'를 사용하는 것이 안전합니다.
minio_root_password: "password123"
# 점검(Check) 관련 임계치 설정
check_disk_usage_threshold: 80 # 디스크 사용량 80% 이상 시 경고
min_memory_gb: 16 # 최소 필요 메모리 16GB
# DirectPV 및 가상화 관련 설정
directpv_namespace: "directpv"
storage_class_name: "directpv-minio"
# 결과 리포트 저장 경로 (대상 서버 내)
check_report_path: "/tmp/minio_check_reports"
이 파일들이 BitBucket에 업로드되면 AWX는 다음과 같이 작동합니다:
inventories/dev_inventory.yml을 읽어 AWX UI 상에 minio-node-01 등의 호스트 리스트를 자동으로 생성합니다.ansible.cfg를 참고하여 roles/ 폴더 안의 로직을 찾고, group_vars/all.yml의 변수들을 메모리에 로드한 뒤 대상 서버로 접속합니다.이제 Role 구조(roles/minio_check/tasks/main.yml 등)를 실제로 어떻게 작성하여 Pre-check와 Post-check를 구분할지 구체적인 코드가 필요하신가요?
===
Minio AISTor의 상태를 점검하는 가장 핵심적인 Role 구조를 작성해 드립니다. 이 코드는 앞서 설계한 roles/minio_check/ 디렉토리에 위치하게 됩니다.
roles/minio_check/tasks/main.yml (진입점)Pre-check와 Post-check를 구분하여 호출할 수 있도록 분기 처리를 해둡니다.
---
- name: "점검 모드 확인: {{ check_mode | default('pre') }}"
include_tasks: "{{ check_mode | default('pre') }}_check.yml"
roles/minio_check/tasks/pre_check.yml (설치 전 점검)작업 전 인프라 환경이 적절한지 확인합니다. 하나라도 실패하면 전체 프로세스를 중단(fail)시킵니다.
---
- name: "[Pre] OS 파라미터 확인 (Max Open Files)"
shell: ulimit -n
register: ulimit_info
failed_when: ulimit_info.stdout | int < 65535
- name: "[Pre] 디스크 가용 공간 확인 (/data)"
assert:
that:
- item.mount == '/data'
- (item.size_available / item.size_total) > 0.2 # 20% 이상 여유
fail_msg: "/data 디스크 용량이 부족하거나 마운트되지 않았습니다."
loop: "{{ ansible_mounts }}"
when: item.mount == '/data'
- name: "[Pre] 필수 포트 점유 여부 확인 (9000, 9001)"
wait_for:
port: "{{ item }}"
state: stopped
timeout: 5
loop:
- "{{ minio_port }}"
- "{{ minio_console_port }}"
roles/minio_check/tasks/post_check.yml (설치/변경 후 점검)서비스가 정상적으로 올라왔는지, 클러스터 구성에 문제가 없는지 확인합니다.
---
- name: "[Post] Minio 서비스 상태 확인"
systemd:
name: minio
state: started
register: minio_service
- name: "[Post] Minio API 응답 대기"
wait_for:
port: "{{ minio_port }}"
delay: 5
timeout: 30
- name: "[Post] mc admin info를 통한 클러스터 헬스 체크"
shell: "mc admin info myminio --json"
register: mc_admin_info
changed_when: false
- name: "[Post] 클러스터 상태 파싱 및 검증"
set_fact:
minio_status: "{{ mc_admin_info.stdout | from_json }}"
- name: "[Post] 오프라인 드라이브 존재 여부 확인"
fail:
msg: "오프라인 상태의 드라이브가 감지되었습니다!"
when: minio_status.info.backend.offline_disks > 0
- name: "[Post] 최종 상태 요약 출력"
debug:
msg:
- "Minio Version: {{ minio_status.info.version }}"
- "Uptime: {{ minio_status.info.uptime }}"
- "Total Storage: {{ (minio_status.info.usage.size / 1024**4) | round(2) }} TB"
이 Role을 실제 작업에 적용할 때는 AWX의 Job Template에서 Extra Variables를 활용합니다.
check_mode: pre 변수를 넘겨서 사전 점검만 수행하거나, 플레이북 상단에 pre_check를 포함합니다.pre 또는 post를 선택하게 만들면, 하나의 템플릿으로 상황에 맞는 점검이 가능합니다.이제 기본적인 점검 로직까지 완성되었습니다!
"혹시 점검 결과를 이메일이나 Slack으로 전송하는 알림(Notification) 기능을 추가해 드릴까요?" 아니면 "DirectPV 관련 상세 점검 로직을 추가해 드릴까요?"
===
DirectPV 환경에서는 데이터 디스크가 호스트 OS에 직접 마운트되지 않고 DirectPV 드라이버에 의해 관리되므로, 일반적인 df나 mount 명령으로는 상태를 확인하기 어렵습니다.
따라서 Pre-check 단계에서는 "DirectPV가 사용할 수 있는 깨끗한 상태의 디스크(Raw Disk/Partition)인가?"를 확인하는 것이 핵심입니다. 이를 위해 lsblk와 blkid를 조합하여 LVM, 파일시스템(XFS 등), 파티션 정보를 구분하는 로직을 구성해 드립니다.
roles/minio_check/tasks/pre_check.yml (업데이트 버전)이 코드는 /dev/sdb, /dev/sdc와 같이 특정 장치들이 DirectPV에 할당되기 적합한 상태(파일시스템이 없고, LVM에 속하지 않은 상태)인지 점검합니다.
---
- name: "[Pre] 대상 디스크 리스트 정의"
set_fact:
target_disks: ["sdb", "sdc", "sdd"] # 점검할 디스크 명칭 (환경에 맞게 수정)
- name: "[Pre] 디스크 상세 정보 수집 (lsblk)"
shell: "lsblk /dev/{{ item }} --json"
loop: "{{ target_disks }}"
register: disk_lsblk_raw
changed_when: false
- name: "[Pre] 디스크 파일시스템 및 시그니처 확인 (blkid)"
shell: "blkid /dev/{{ item }} || true"
loop: "{{ target_disks }}"
register: disk_blkid_raw
changed_when: false
- name: "[Pre] 디스크 상태 분석 및 미할당 여부 검증"
vars:
# lsblk 결과 파싱
disk_info: "{{ item.0.stdout | from_json }}"
# blkid 결과가 비어있으면 파일시스템이나 LVM 시그니처가 없는 'Clean' 상태로 간주
has_signature: "{{ item.1.stdout != '' }}"
assert:
that:
- disk_info.blockdevices[0].mountpoint == null # 마운트되지 않아야 함
- not has_signature # 파일시스템(XFS, LVM 등)이 없어야 함
- disk_info.blockdevices[0].children is not defined # 하위 파티션이 없는 Raw 상태 권장
fail_msg: |
디스크 /dev/{{ item.0.item }} 상태가 적절하지 않습니다.
- 마운트 여부: {{ disk_info.blockdevices[0].mountpoint | default('No') }}
- 기존 데이터/LVM 존재 여부: {{ 'Yes' if has_signature else 'No' }}
- 상세 정보: {{ item.1.stdout }}
loop: "{{ disk_lsblk_raw.results | zip(disk_blkid_raw.results) | list }}"
- name: "[Pre] 최소 가용 용량 확인 (개별 디스크 100GB 이상)"
assert:
that:
- (item.stdout | from_json).blockdevices[0].size | human_to_bytes >= 107374182400
fail_msg: "/dev/{{ item.item }} 의 용량이 최소 요구사항(100GB)에 미달합니다."
loop: "{{ disk_lsblk_raw.results }}"
lsblk --json 활용: JSON 형태로 결과를 받아 mountpoint가 있는지, children(파티션)이 이미 나누어져 있는지 프로그래밍 방식으로 정확하게 체크합니다.blkid 검증: TYPE="xfs", TYPE="LVM2_member" 등의 정보가 출력됩니다. blkid 결과가 비어있는(Clean) 상태인지를 확인하는 것이 매우 중요한 Pre-check 항목입니다.assert 모듈: 조건에 맞지 않을 경우 AWX 화면에 어떤 디스크가 왜 부적합한지(fail_msg) 명확하게 노출하여 작업자가 조치할 수 있게 합니다.설치 후에는 노드에서 디스크를 보는 게 아니라 kubectl directpv 명령어로 상태를 확인해야 합니다.
roles/minio_check/tasks/post_check.yml (추가분)
---
- name: "[Post] DirectPV 드라이브 상태 확인 (Ready 상태 여부)"
shell: "kubectl directpv list drives --format json"
register: directpv_drives_raw
delegate_to: localhost # k8s 컨트롤러 권한이 있는 곳에서 실행
- name: "[Post] 드라이브 에러 및 오프라인 체크"
vars:
drives: "{{ directpv_drives_raw.stdout | from_json }}"
assert:
that:
- item.status == 'Ready'
fail_msg: "DirectPV 드라이브 {{ item.path }} 가 Ready 상태가 아닙니다! (현재 상태: {{ item.status }})"
loop: "{{ drives }}"
when: drives | length > 0
이렇게 구성하면 AWX에서 설치 전에는 물리적인 디스크의 순수성을 점검하고, 설치 후에는 DirectPV 소프트웨어 레벨에서의 정상 가동 여부를 모두 자동화하여 관리할 수 있습니다.
이 코드를 BitBucket의 roles/minio_check/tasks/ 아래에 덮어쓰기 하시면 바로 적용 가능합니다. 더 궁금하신 세부 점검 조건이 있으신가요?
===
네, 가능합니다. 노드마다 디스크 컨트롤러 순서가 바뀌거나 /dev/sdb, /dev/sdc 등으로 이름이 가변적인 환경에서는 Ansible Facts와 Shell 필터링을 조합하여 "DirectPV가 사용 가능한 빈 디스크"만 자동으로 스캔하도록 구성하는 것이 훨씬 안정적입니다.
set_fact 부분을 아래와 같이 동적 스캔 로직으로 교체하면 됩니다.
pre_check.yml 상단)이 로직은 시스템의 모든 블록 장치를 훑어서 OS 영역이 아니고, 파티션이 없으며, 마운트되지 않은 'Raw' 디스크만 골라냅니다.
---
- name: "[Scan] 사용 가능한 가용 디스크 자동 검색"
shell: |
lsblk -no NAME,MOUNTPOINT,TYPE,FSTYPE,SIZE | \
awk '$2 == "" && $3 == "disk" && $4 == "" {print $1}'
register: scanned_disks
changed_when: false
- name: "[Scan] 스캔된 디스크 목록을 target_disks 변수에 할당"
set_fact:
target_disks: "{{ scanned_disks.stdout_lines }}"
- name: "[Scan] 검색 결과 출력"
debug:
msg: "노드 {{ inventory_hostname }}에서 발견된 가용 디스크: {{ target_disks }}"
- name: "[Scan] 가용 디스크가 없는 경우 중단 (선택 사항)"
fail:
msg: "DirectPV로 사용할 수 있는 빈 디스크가 이 노드에 없습니다."
when: target_disks | length == 0
lsblk -no ...: NAME: 디스크 이름 (예: sdb)MOUNTPOINT: 마운트 여부 확인용TYPE: part(파티션)가 아닌 disk(물리 장치)만 골라내기 위함FSTYPE: 파일시스템(xfs, ext4, LVM 등)이 이미 생성된 디스크 제외awk 필터링:$2 == "": 마운트 포인트가 비어 있어야 함 (사용 중인 디스크 제외)$3 == "disk": 파티션 조각이 아닌 전체 디스크 단위여야 함$4 == "": 파일시스템 포맷이 되어 있지 않아야 함 (DirectPV는 Raw 디스크 선호)이제 수동으로 이름을 적을 필요 없이, 스캔된 target_disks를 사용하여 이후 검증 과정을 이어갑니다.
---
- name: "[Scan] 가용 디스크 자동 검색"
shell: "lsblk -no NAME,MOUNTPOINT,TYPE,FSTYPE | awk '$2 == \"\" && $3 == \"disk\" && $4 == \"\" {print $1}'"
register: scanned_disks
changed_when: false
- name: "[Scan] target_disks 변수 생성"
set_fact:
target_disks: "{{ scanned_disks.stdout_lines }}"
- name: "[Pre] 스캔된 각 디스크의 상세 정밀 검증 (lsblk JSON)"
shell: "lsblk /dev/{{ item }} --json"
loop: "{{ target_disks }}"
register: disk_lsblk_raw
when: target_disks | length > 0
- name: "[Pre] 디스크 용량 필터링 (예: 100GB 이상만 사용)"
assert:
that:
- (item.stdout | from_json).blockdevices[0].size | human_to_bytes >= 107374182400
fail_msg: "/dev/{{ item.item }} 의 용량이 부족합니다."
loop: "{{ disk_lsblk_raw.results }}"
when: disk_lsblk_raw.results is defined
awk 로직은 마운트된 디스크를 제외하므로 /나 /boot가 있는 디스크는 자동으로 걸러집니다.FSTYPE이 비어있지 않다면($4 == "") 스캔 대상에서 제외되므로 2중 안전 장치가 됩니다.debug 메시지를 통해 각 노드별로 어떤 디스크(sdb, nvme0n1 등)가 선택되었는지 한눈에 확인할 수 있습니다.이렇게 구성하면 컨트롤러 재기동으로 인해 디스크 이름이 sdb에서 sdc로 바뀌더라도, AWX는 실행 시점의 상태를 다시 스캔하므로 문제없이 동작합니다.
다음으로 이 스캔 결과를 바탕으로 자동으로 kubectl directpv add drives 명령까지 생성하는 작업이 필요하실까요?