소개
Ansible 은 시스템 관리자 및 DevOps 전문가들이 널리 사용하는 강력한 오픈 소스 자동화 도구입니다. Ansible 의 주요 기능 중 하나는 원격 호스트에서 셸 명령을 실행하고 해당 출력을 처리하는 것입니다. 이 실습 튜토리얼에서는 Ansible 플레이북에서 셸 명령의 출력을 효과적으로 캡처, 표시 및 처리하는 방법을 배우게 됩니다. 이 기술은 다양한 시스템 조건에 적응하고 유용한 피드백을 제공할 수 있는 강력한 자동화 워크플로우를 만드는 데 필수적입니다.
셸 명령을 사용한 첫 번째 Ansible 플레이북 설정
이 단계에서는 셸 명령을 실행하고 해당 출력을 캡처하는 기본적인 Ansible 플레이북을 설정합니다. 이는 이후 단계에서 더 고급 기술을 위한 기반을 제공합니다.
Ansible 설치
먼저, 시스템에 Ansible 을 설치해 보겠습니다.
sudo apt update
sudo apt install -y ansible
이제 Ansible 이 올바르게 설치되었는지 확인합니다.
ansible --version
다음과 유사한 출력이 표시되어야 합니다.
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 15 2022, 12:22:08) [GCC 11.2.0]
jinja version = 3.0.3
libyaml = True
인벤토리 파일 생성
Ansible 은 관리할 호스트를 알기 위해 인벤토리 파일을 사용합니다. 이 랩에서는 로컬 머신만 포함하는 간단한 인벤토리를 생성합니다.
- WebIDE 를 열고
/home/labex/project디렉토리에inventory.ini라는 새 파일을 만듭니다. - 파일에 다음 내용을 추가합니다.
[local]
localhost ansible_connection=local
이 인벤토리는 local이라는 그룹을 정의하며, 이 그룹에는 localhost 만 포함되어 있고 Ansible 에 SSH 없이 직접 연결하도록 지시합니다.
첫 번째 플레이북 생성
이제 셸 명령을 실행하는 간단한 플레이북을 만들어 보겠습니다.
/home/labex/project디렉토리에first_playbook.yml이라는 새 파일을 만듭니다.- 파일에 다음 YAML 내용을 추가합니다.
---
- name: Shell Command Example
hosts: local
gather_facts: no
tasks:
- name: Run a simple shell command
shell: echo "Hello from Ansible shell command"
register: hello_output
- name: Display the output
debug:
msg: "{{ hello_output.stdout }}"
이 플레이북은 다음을 수행합니다.
- 인벤토리에서 정의한
local그룹을 대상으로 합니다. - 팩트 (시스템 정보) 수집을 건너뛰어 간단하게 유지합니다.
- 인사 메시지를 에코하는 셸 명령을 실행합니다.
register키워드를 사용하여 출력을 변수에 저장합니다.debug모듈을 사용하여 출력을 표시합니다.
플레이북 실행
이제 플레이북을 실행해 보겠습니다.
ansible-playbook -i inventory.ini first_playbook.yml
다음과 유사한 출력이 표시되어야 합니다.
PLAY [Shell Command Example] **************************************************
TASK [Run a simple shell command] *********************************************
changed: [localhost]
TASK [Display the output] *****************************************************
ok: [localhost] => {
"msg": "Hello from Ansible shell command"
}
PLAY RECAP ********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
출력은 플레이북이 성공적으로 실행되어 셸 명령을 실행하고 해당 출력을 표시했음을 보여줍니다.
이해해야 할 주요 개념
이 연습에서 다음 중요한 개념에 유의하십시오.
shell모듈을 사용하면 셸 명령을 실행할 수 있습니다.register지시문은 작업의 출력을 변수에 캡처합니다.debug모듈은 변수 값을 표시하는 데 도움이 됩니다.- 셸 명령 출력에는
stdout(표준 출력) 과stderr(오류 출력) 이 모두 포함됩니다.
다음 단계에서는 셸 명령 출력을 보다 효과적으로 처리하고 형식화하는 방법을 살펴보겠습니다.
구조화된 셸 명령 출력 작업
이제 Ansible 에서 셸 명령을 실행하는 기본 사항을 이해했으므로 구조화된 명령 출력으로 작업하고 이를 다양한 형식으로 표시하는 방법을 살펴보겠습니다.
시스템 정보 처리
시스템 정보를 수집하고 구조화된 방식으로 표시하는 더 실용적인 플레이북을 만들어 보겠습니다.
/home/labex/project디렉토리에system_info.yml이라는 새 파일을 만듭니다.- 다음 내용을 추가합니다.
---
- name: Gather and Display System Information
hosts: local
gather_facts: no
tasks:
- name: Gather system information
shell: |
echo "OS Information: $(cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2)"
echo "Kernel Version: $(uname -r)"
echo "CPU Information: $(grep "model name" /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)"
echo "Memory Information: $(free -h | grep Mem | awk '{print $2}')"
register: system_info
- name: Display raw system information
debug:
msg: "{{ system_info.stdout }}"
- name: Display information as a list
debug:
msg: "{{ system_info.stdout_lines }}"
이 플레이북은 다음을 수행합니다.
- 다양한 시스템 세부 정보를 수집하는 여러 줄의 셸 스크립트를 실행합니다.
- 출력을
system_info변수에 저장합니다. - 출력을 먼저 원시 문자열로 표시한 다음 줄 목록으로 표시합니다.
플레이북을 실행합니다.
ansible-playbook -i inventory.ini system_info.yml
다음과 같은 출력이 표시되어야 합니다.
PLAY [Gather and Display System Information] **********************************
TASK [Gather system information] **********************************************
changed: [localhost]
TASK [Display raw system information] *****************************************
ok: [localhost] => {
"msg": "OS Information: \"Ubuntu 22.04.1 LTS\"\nKernel Version: 5.15.0-1023-azure\nCPU Information: Intel(R) Xeon(R) Platinum 8171M CPU @ 2.60GHz\nMemory Information: 4.0Gi"
}
TASK [Display information as a list] *****************************************
ok: [localhost] => {
"msg": [
"OS Information: \"Ubuntu 22.04.1 LTS\"",
"Kernel Version: 5.15.0-1023-azure",
"CPU Information: Intel(R) Xeon(R) Platinum 8171M CPU @ 2.60GHz",
"Memory Information: 4.0Gi"
]
}
PLAY RECAP ********************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
두 번째 표시 작업이 출력을 줄 바꿈이 있는 문자열 대신 목록으로 표시하는 방식을 확인하십시오. 이 목록 형식은 여러 줄의 출력을 더 쉽게 처리할 수 있도록 합니다.
명령 결과 및 반환 코드 작업
Linux 의 셸 명령은 성공 (0) 또는 실패 (0 이 아닌 값) 를 나타내기 위해 종료 코드를 반환합니다. Ansible 은 이러한 코드를 등록된 변수의 rc (반환 코드) 속성으로 캡처합니다.
반환 코드로 작업하는 방법을 보여주는 플레이북을 만들어 보겠습니다.
/home/labex/project디렉토리에command_results.yml이라는 새 파일을 만듭니다.- 다음 내용을 추가합니다.
---
- name: Working with Command Results
hosts: local
gather_facts: no
tasks:
- name: Check if a file exists
shell: test -f /etc/hosts
register: file_check
ignore_errors: yes
- name: Show command result details
debug:
msg: |
Return code: {{ file_check.rc }}
Succeeded: {{ file_check.rc == 0 }}
Failed: {{ file_check.rc != 0 }}
- name: Check if a non-existent file exists
shell: test -f /file/does/not/exist
register: missing_file
ignore_errors: yes
- name: Show command result for missing file
debug:
msg: |
Return code: {{ missing_file.rc }}
Succeeded: {{ missing_file.rc == 0 }}
Failed: {{ missing_file.rc != 0 }}
이 플레이북은 다음을 수행합니다.
- 파일이 있는지 확인하기 위해 두 개의 테스트 명령을 실행합니다.
- 명령이 실패할 경우 플레이북이 중지되지 않도록
ignore_errors: yes를 사용합니다. - 반환 코드 및 성공/실패 상태를 포함한 자세한 명령 결과 정보를 표시합니다.
플레이북을 실행합니다.
ansible-playbook -i inventory.ini command_results.yml
다음과 유사한 출력이 표시되어야 합니다.
PLAY [Working with Command Results] *******************************************
TASK [Check if a file exists] *************************************************
changed: [localhost]
TASK [Show command result details] ********************************************
ok: [localhost] => {
"msg": "Return code: 0\nSucceeded: True\nFailed: False\n"
}
TASK [Check if a non-existent file exists] ************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "test -f /file/does/not/exist", "delta": "0:00:00.003183", "end": "2023-07-14 15:24:33.931406", "msg": "non-zero return code", "rc": 1, "start": "2023-07-14 15:24:33.928223", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring
TASK [Show command result for missing file] ***********************************
ok: [localhost] => {
"msg": "Return code: 1\nSucceeded: False\nFailed: True\n"
}
PLAY RECAP ********************************************************************
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
기존 파일의 반환 코드는 0 이고 존재하지 않는 파일의 반환 코드는 1 임을 확인하십시오. 이는 플레이북에서 반환 코드를 사용하여 결정을 내리는 방법을 보여줍니다.
등록된 변수 구조 이해
셸 명령에서 등록된 변수에는 몇 가지 유용한 속성이 포함되어 있습니다.
stdout: 단일 문자열로 된 표준 출력stdout_lines: 줄 목록으로 분할된 표준 출력stderr: 단일 문자열로 된 표준 오류 출력stderr_lines: 줄 목록으로 분할된 표준 오류 출력rc: 반환 코드 (성공 시 0, 실패 시 0 이 아닌 값)cmd: 실행된 명령start및end: 명령이 시작 및 종료된 타임스탬프delta: 명령 실행 기간
Ansible 에서 셸 명령 출력을 효과적으로 처리하려면 이 구조를 이해하는 것이 중요합니다.
셸 출력 기반 조건부 실행
Ansible 의 가장 강력한 기능 중 하나는 셸 명령의 출력을 기반으로 결정을 내리는 기능입니다. 이 단계에서는 조건과 필터를 사용하여 셸 명령 출력을 처리하고 플레이북을 더 동적으로 만드는 방법을 배웁니다.
셸 출력과 함께 조건 사용
셸 명령 출력을 기반으로 결정을 내리는 플레이북을 만들어 보겠습니다.
/home/labex/project디렉토리에conditional_playbook.yml이라는 새 파일을 만듭니다.- 다음 내용을 추가합니다.
---
- name: Conditional Tasks Based on Command Output
hosts: local
gather_facts: no
tasks:
- name: Check disk space
shell: df -h / | grep -v Filesystem | awk '{print $5}' | sed 's/%//'
register: disk_usage
- name: Display disk usage
debug:
msg: "Current disk usage: {{ disk_usage.stdout }}%"
- name: Disk usage warning
debug:
msg: "WARNING: Disk usage is high"
when: disk_usage.stdout|int > 50
- name: Disk usage normal
debug:
msg: "Disk usage is normal"
when: disk_usage.stdout|int <= 50
이 플레이북은 다음을 수행합니다.
- 루트 파일 시스템의 디스크 사용량 백분율을 확인하기 위해 셸 명령을 실행합니다.
- 명령 출력을 기반으로
when조건을 사용합니다. - 비교를 위해 문자열 출력을 정수로 변환하기 위해
int필터를 사용합니다.
플레이북을 실행합니다.
ansible-playbook -i inventory.ini conditional_playbook.yml
출력은 실제 디스크 사용량에 따라 다르지만 다음과 유사하게 표시됩니다.
PLAY [Conditional Tasks Based on Command Output] ******************************
TASK [Check disk space] *******************************************************
changed: [localhost]
TASK [Display disk usage] *****************************************************
ok: [localhost] => {
"msg": "Current disk usage: 38%"
}
TASK [Disk usage warning] *****************************************************
skipped: [localhost]
TASK [Disk usage normal] ******************************************************
ok: [localhost] => {
"msg": "Disk usage is normal"
}
PLAY RECAP ********************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Ansible 이 실제 디스크 사용량 값을 기반으로 조건부 작업 중 하나만 실행하는 방식을 확인하십시오.
명령에서 JSON 출력 처리
많은 최신 CLI 도구는 JSON 형식으로 데이터를 반환합니다. Ansible 에는 JSON 출력을 처리하는 기능이 내장되어 있습니다.
/home/labex/project디렉토리에json_output.yml이라는 새 파일을 만듭니다.- 다음 내용을 추가합니다.
---
- name: Handling JSON Output
hosts: local
gather_facts: no
tasks:
- name: Create a JSON file for testing
copy:
dest: /tmp/services.json
content: |
{
"services": [
{
"name": "web",
"status": "running",
"port": 80
},
{
"name": "database",
"status": "stopped",
"port": 5432
},
{
"name": "cache",
"status": "running",
"port": 6379
}
]
}
- name: Read JSON file with shell
shell: cat /tmp/services.json
register: json_output
- name: Parse and display JSON content
debug:
msg: "{{ json_output.stdout | from_json }}"
- name: Extract and display service information
debug:
msg: "Service: {{ item.name }}, Status: {{ item.status }}, Port: {{ item.port }}"
loop: "{{ (json_output.stdout | from_json).services }}"
- name: Show only running services
debug:
msg: "Running service: {{ item.name }} on port {{ item.port }}"
loop: "{{ (json_output.stdout | from_json).services }}"
when: item.status == "running"
이 플레이북은 다음을 수행합니다.
- 데모용 샘플 JSON 파일을 만듭니다.
- 셸 명령으로 JSON 파일을 읽습니다.
from_json필터를 사용하여 JSON 문자열을 데이터 구조로 구문 분석합니다.- 데이터 구조를 반복하여 정보를 표시합니다.
- 조건부 로직을 사용하여 실행 중인 서비스만 필터링합니다.
플레이북을 실행합니다.
ansible-playbook -i inventory.ini json_output.yml
다음과 유사한 출력이 표시되어야 합니다.
PLAY [Handling JSON Output] ***************************************************
TASK [Create a JSON file for testing] *****************************************
changed: [localhost]
TASK [Read JSON file with shell] **********************************************
changed: [localhost]
TASK [Parse and display JSON content] *****************************************
ok: [localhost] => {
"msg": {
"services": [
{
"name": "web",
"port": 80,
"status": "running"
},
{
"name": "database",
"port": 5432,
"status": "stopped"
},
{
"name": "cache",
"port": 6379,
"status": "running"
}
]
}
}
TASK [Extract and display service information] ********************************
ok: [localhost] => (item={'name': 'web', 'status': 'running', 'port': 80}) => {
"msg": "Service: web, Status: running, Port: 80"
}
ok: [localhost] => (item={'name': 'database', 'status': 'stopped', 'port': 5432}) => {
"msg": "Service: database, Status: stopped, Port: 5432"
}
ok: [localhost] => (item={'name': 'cache', 'status': 'running', 'port': 6379}) => {
"msg": "Service: cache, Status: running, Port: 6379"
}
TASK [Show only running services] *********************************************
ok: [localhost] => (item={'name': 'web', 'status': 'running', 'port': 80}) => {
"msg": "Running service: web on port 80"
}
skipped: [localhost] => (item={'name': 'database', 'status': 'stopped', 'port': 5432})
ok: [localhost] => (item={'name': 'cache', 'status': 'running', 'port': 6379}) => {
"msg": "Running service: cache on port 6379"
}
PLAY RECAP ********************************************************************
localhost : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
플레이북이 JSON 을 구문 분석하고, 특정 정보를 추출하고, 조건을 기반으로 데이터를 필터링하는 방식을 확인하십시오.
셸 명령을 사용한 오류 처리
셸 명령을 실행할 때는 잠재적인 오류를 적절하게 처리하는 것이 중요합니다.
/home/labex/project디렉토리에error_handling.yml이라는 새 파일을 만듭니다.- 다음 내용을 추가합니다.
---
- name: Error Handling with Shell Commands
hosts: local
gather_facts: no
tasks:
- name: Run a potentially failing command
shell: grep "nonexistent_pattern" /etc/passwd
register: command_result
ignore_errors: yes
- name: Display success or failure
debug:
msg: "Command {{ 'succeeded' if command_result.rc == 0 else 'failed with return code ' + command_result.rc|string }}"
- name: Run a custom failing command
shell: exit 3
register: exit_command
ignore_errors: yes
- name: Display detailed error information
debug:
msg: |
Return code: {{ exit_command.rc }}
Error message: {{ exit_command.stderr if exit_command.stderr else 'No error message' }}
이 플레이북은 다음을 수행합니다.
- 실패할 것으로 예상되는 명령을 실행합니다.
- 명령이 실패하더라도 플레이북 실행을 계속하기 위해
ignore_errors: yes를 사용합니다. - 오류 정보를 처리하고 표시하는 다양한 방법을 보여줍니다.
플레이북을 실행합니다.
ansible-playbook -i inventory.ini error_handling.yml
다음과 유사한 출력이 표시되어야 합니다.
PLAY [Error Handling with Shell Commands] *************************************
TASK [Run a potentially failing command] **************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "grep \"nonexistent_pattern\" /etc/passwd", "delta": "0:00:00.002916", "end": "2023-07-14 16:10:23.671519", "msg": "non-zero return code", "rc": 1, "start": "2023-07-14 16:10:23.668603", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring
TASK [Display success or failure] *********************************************
ok: [localhost] => {
"msg": "Command failed with return code 1"
}
TASK [Run a custom failing command] *******************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "exit 3", "delta": "0:00:00.002447", "end": "2023-07-14 16:10:23.906121", "msg": "non-zero return code", "rc": 3, "start": "2023-07-14 16:10:23.903674", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring
TASK [Display detailed error information] *************************************
ok: [localhost] => {
"msg": "Return code: 3\nError message: No error message\n"
}
PLAY RECAP ********************************************************************
localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=2
이는 셸 명령을 실행할 때 다양한 오류 조건을 캡처하고 이에 대응하는 방법을 보여줍니다.
실용적인 셸 출력 처리 도구 만들기
이 마지막 단계에서는 지금까지 배운 모든 내용을 결합하여 시스템 정보를 수집하고, 처리하고, 보고서를 생성하는 실용적인 Ansible 플레이북을 만들 것입니다. 이는 Ansible 의 셸 명령 처리 기능이 매우 유용할 수 있는 실제 시나리오를 나타냅니다.
시스템 정보 보고서 도구 구축
포괄적인 시스템 정보 수집 도구를 만들어 보겠습니다.
/home/labex/project디렉토리에system_report.yml이라는 새 파일을 만듭니다.- 다음 내용을 추가합니다.
---
- name: Comprehensive System Report
hosts: local
gather_facts: no
vars:
report_file: /tmp/system_report.txt
tasks:
- name: Collect basic system information
shell: |
echo "SYSTEM REPORT" > {{ report_file }}
echo "=============" >> {{ report_file }}
echo "" >> {{ report_file }}
echo "HOSTNAME: $(hostname)" >> {{ report_file }}
echo "TIMESTAMP: $(date)" >> {{ report_file }}
echo "" >> {{ report_file }}
echo "SYSTEM INFORMATION" >> {{ report_file }}
echo "------------------" >> {{ report_file }}
echo "OS: $(cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2)" >> {{ report_file }}
echo "KERNEL: $(uname -r)" >> {{ report_file }}
echo "UPTIME: $(uptime -p)" >> {{ report_file }}
echo "" >> {{ report_file }}
echo "RESOURCE UTILIZATION" >> {{ report_file }}
echo "-------------------" >> {{ report_file }}
echo "CPU LOAD: $(uptime | awk -F'load average:' '{print $2}')" >> {{ report_file }}
echo "MEMORY USAGE:" >> {{ report_file }}
free -h >> {{ report_file }}
echo "" >> {{ report_file }}
echo "DISK USAGE:" >> {{ report_file }}
df -h >> {{ report_file }}
echo "" >> {{ report_file }}
echo "NETWORK INFORMATION" >> {{ report_file }}
echo "-------------------" >> {{ report_file }}
echo "IP ADDRESSES:" >> {{ report_file }}
ip addr | grep "inet " | awk '{print $2}' >> {{ report_file }}
echo "" >> {{ report_file }}
echo "PROCESS INFORMATION" >> {{ report_file }}
echo "-------------------" >> {{ report_file }}
echo "TOP 5 CPU CONSUMING PROCESSES:" >> {{ report_file }}
ps aux --sort=-%cpu | head -6 >> {{ report_file }}
echo "" >> {{ report_file }}
echo "TOP 5 MEMORY CONSUMING PROCESSES:" >> {{ report_file }}
ps aux --sort=-%mem | head -6 >> {{ report_file }}
register: report_generation
- name: Check if report was generated successfully
stat:
path: "{{ report_file }}"
register: report_stat
- name: Display report generation status
debug:
msg: "Report generated successfully at {{ report_file }}"
when: report_stat.stat.exists
- name: Display report content
shell: cat {{ report_file }}
register: report_content
when: report_stat.stat.exists
- name: Show report content
debug:
msg: "{{ report_content.stdout_lines }}"
when: report_stat.stat.exists
- name: Analyze disk usage
shell: df -h / | grep -v Filesystem | awk '{print $5}' | sed 's/%//'
register: disk_usage
when: report_stat.stat.exists
- name: Generate disk usage alert if needed
debug:
msg: "ALERT: Disk usage on / is {{ disk_usage.stdout }}% which exceeds the 80% threshold!"
when:
- report_stat.stat.exists
- disk_usage.stdout|int > 80
- name: Generate disk usage warning if needed
debug:
msg: "WARNING: Disk usage on / is {{ disk_usage.stdout }}% which exceeds the 60% threshold."
when:
- report_stat.stat.exists
- disk_usage.stdout|int > 60
- disk_usage.stdout|int <= 80
- name: Confirm normal disk usage
debug:
msg: "Disk usage on / is normal at {{ disk_usage.stdout }}%."
when:
- report_stat.stat.exists
- disk_usage.stdout|int <= 60
이 플레이북은 다음을 수행합니다.
- 일련의 셸 명령을 사용하여 포괄적인 시스템 정보를 수집합니다.
- 정보를 보고서 파일에 씁니다.
- 보고서가 성공적으로 생성되었는지 확인합니다.
- 보고서의 내용을 표시합니다.
- 디스크 사용량 데이터를 분석합니다.
- 분석을 기반으로 적절한 경고를 생성합니다.
플레이북을 실행합니다.
ansible-playbook -i inventory.ini system_report.yml
플레이북 실행 및 전체 시스템 보고서를 보여주는 포괄적인 출력을 볼 수 있습니다. 출력은 매우 길기 때문에 다음은 볼 수 있는 내용의 샘플입니다.
PLAY [Comprehensive System Report] ********************************************
TASK [Collect basic system information] ***************************************
changed: [localhost]
TASK [Check if report was generated successfully] *****************************
ok: [localhost]
TASK [Display report generation status] ***************************************
ok: [localhost] => {
"msg": "Report generated successfully at /tmp/system_report.txt"
}
TASK [Display report content] *************************************************
changed: [localhost]
TASK [Show report content] ****************************************************
ok: [localhost] => {
"msg": [
"SYSTEM REPORT",
"=============",
"",
"HOSTNAME: ubuntu-vm",
"TIMESTAMP: Fri Jul 14 16:35:42 UTC 2023",
"",
"SYSTEM INFORMATION",
"------------------",
"OS: \"Ubuntu 22.04.1 LTS\"",
"KERNEL: 5.15.0-1023-azure",
"UPTIME: up 3 hours, 25 minutes",
...
보고서 검토
생성된 시스템 보고서를 검토해 보겠습니다.
cat /tmp/system_report.txt
이렇게 하면 플레이북에서 생성된 전체 보고서가 표시됩니다.
사용자 지정 셸 스크립트 생성 및 Ansible 에서 호출
더 복잡한 작업의 경우 전용 셸 스크립트를 만들고 Ansible 에서 호출하는 것이 더 쉬울 수 있습니다.
/home/labex/project디렉토리에disk_analyzer.sh라는 새 파일을 만듭니다.- 다음 내용을 추가합니다.
#!/bin/bash
## disk_analyzer.sh - A simple script to analyze disk usage
echo "DISK USAGE ANALYSIS"
echo "------------------"
## Get overall disk usage
ROOT_USAGE=$(df -h / | grep -v Filesystem | awk '{print $5}' | sed 's/%//')
echo "Root filesystem usage: ${ROOT_USAGE}%"
## Categorize the usage
if [ $ROOT_USAGE -gt 80 ]; then
echo "STATUS: CRITICAL - Immediate action required"
elif [ $ROOT_USAGE -gt 60 ]; then
echo "STATUS: WARNING - Consider cleaning up disk space"
else
echo "STATUS: OK - Disk usage is within normal parameters"
fi
echo ""
## Find largest directories
echo "Top 5 largest directories in /var:"
du -h /var --max-depth=1 2> /dev/null | sort -hr | head -5
echo ""
## Find largest files
echo "Top 5 largest files in /var/log:"
find /var/log -type f -exec du -h {} \; 2> /dev/null | sort -hr | head -5
exit 0
- 스크립트를 실행 가능하게 만듭니다.
chmod +x /home/labex/project/disk_analyzer.sh
- 이 스크립트를 호출하는 새 플레이북을 만듭니다.
touch /home/labex/project/call_script.yml
- 플레이북에 다음 내용을 추가합니다.
---
- name: Call Custom Shell Script
hosts: local
gather_facts: no
tasks:
- name: Run disk analyzer script
shell: /home/labex/project/disk_analyzer.sh
register: script_output
- name: Display script output
debug:
msg: "{{ script_output.stdout_lines }}"
- name: Check for critical status
debug:
msg: "CRITICAL DISK USAGE DETECTED! Immediate action required."
when: script_output.stdout is search("STATUS: CRITICAL")
- 플레이북을 실행합니다.
ansible-playbook -i inventory.ini call_script.yml
다음과 유사한 출력이 표시되어야 합니다.
PLAY [Call Custom Shell Script] ***********************************************
TASK [Run disk analyzer script] ***********************************************
changed: [localhost]
TASK [Display script output] **************************************************
ok: [localhost] => {
"msg": [
"DISK USAGE ANALYSIS",
"------------------",
"Root filesystem usage: 38%",
"STATUS: OK - Disk usage is within normal parameters",
"",
"Top 5 largest directories in /var:",
"60M\t/var/lib",
"60M\t/var/cache",
"12M\t/var/log",
"4.0K\t/var/tmp",
"4.0K\t/var/mail",
"",
"Top 5 largest files in /var/log:",
"4.0M\t/var/log/journal/c75af53674ce472fb9654a1d5cf8cc37/system.journal",
"2.3M\t/var/log/auth.log",
"1.3M\t/var/log/syslog",
"724K\t/var/log/kern.log",
"428K\t/var/log/cloud-init.log"
]
}
TASK [Check for critical status] **********************************************
skipped: [localhost]
PLAY RECAP ********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
이 접근 방식은 셸 스크립트의 강력함과 Ansible 의 자동화 기능을 결합합니다. 셸 스크립트는 디스크 분석에 대한 복잡한 로직을 처리하는 반면, Ansible 은 결과의 실행 및 추가 처리를 관리합니다.
주요 내용
이 랩을 통해 Ansible 에서 셸 명령 출력을 처리하기 위한 몇 가지 중요한 기술을 배웠습니다.
- 셸 명령을 실행하고 출력을 캡처하는 방법
- 표시를 위해 명령 출력을 처리하고 형식화하는 방법
- 명령 결과를 기반으로 조건부 실행을 사용하는 방법
- JSON 출력 및 오류 조건을 처리하는 방법
- 셸 명령과 Ansible 의 자동화 기능을 결합하는 실용적인 도구를 만드는 방법
이러한 기술은 Ansible 로 더 복잡한 자동화 솔루션을 구축할 때 매우 유용할 것입니다.
요약
이 랩에서는 Ansible 플레이북에서 셸 명령 출력을 효과적으로 사용하는 방법을 배웠습니다. 셸 명령을 실행하고 출력을 캡처하는 기본 사항부터 시작하여 조건부 실행, 오류 처리, JSON 과 같은 구조화된 데이터 형식 처리와 같은 고급 기술로 발전했습니다.
다음과 같은 몇 가지 주요 기술을 습득했습니다.
shell모듈을 사용하여 Ansible 플레이북에서 셸 명령 실행register지시문을 사용하여 명령 출력 캡처debug모듈을 사용하여 출력 표시- Jinja2 필터 및 조건으로 출력 처리
- Ansible 과 셸 스크립트를 결합하는 실용적인 자동화 도구 만들기
이러한 기술을 통해 다양한 시스템 조건에 적응하고 수행되는 작업에 대한 유용한 피드백을 제공할 수 있는 보다 동적이고 반응적인 자동화 워크플로우를 만들 수 있습니다.
Ansible 여정을 계속 진행하면서 셸 명령이 훌륭한 유연성을 제공하지만 Ansible 의 내장 모듈은 일반적인 작업에 대해 더 강력하고 이식 가능한 솔루션인 경우가 많다는 점을 기억하십시오. 기존 셸 스크립트를 활용하거나 Ansible 모듈로 쉽게 처리할 수 없는 복잡한 작업을 수행해야 할 때 셸 명령을 사용하십시오.


