소개
이 랩에서는 Ansible 의 두 가지 강력한 기능인 조건문 (conditionals) 과 루프 (loops) 를 탐구합니다. 이러한 개념을 통해 특정 조건에 따라 작업 실행을 제어하고 여러 항목에 대해 작업을 반복함으로써 더욱 동적이고 효율적인 플레이북을 만들 수 있습니다. 이 랩을 마치면 플레이북에서 결정을 내리기 위해 조건문을 사용하는 방법과 반복적인 작업을 효율적으로 수행하기 위해 루프를 구현하는 방법을 이해하게 됩니다. 이 지식을 통해 인프라 관리를 위한 더욱 유연하고 강력한 Ansible 플레이북을 만들 수 있습니다.
환경 설정
Ansible 조건문과 루프를 살펴보기 전에 작업 환경을 설정해 보겠습니다. 이 단계는 모든 후속 작업의 기반을 마련하므로 매우 중요합니다.
먼저, 프로젝트 디렉토리로 이동해 보겠습니다. 터미널에서 다음을 입력합니다.
cd ~/project
이 명령은 현재 디렉토리를 ~/project로 변경합니다. 이곳은 이 랩을 위한 지정된 작업 공간입니다.
이제 인벤토리 파일을 생성합니다. Ansible 에서 인벤토리 파일은 플레이북의 명령, 모듈 및 작업이 작동하는 호스트와 호스트 그룹을 정의합니다. 이 랩에서는 localhost 만 포함하는 간단한 인벤토리를 사용합니다.
inventory.ini라는 새 파일을 만듭니다.
nano inventory.ini
이 명령은 nano 텍스트 편집기를 엽니다. nano 에 익숙하지 않더라도 걱정하지 마세요. 간단하고 사용자 친화적인 텍스트 편집기입니다. 커서는 파일을 입력할 준비가 된 상태로 배치됩니다.
이제 다음 내용을 파일에 추가해 보겠습니다.
[local]
localhost ansible_connection=local
자세히 살펴보겠습니다.
[local]은 "local"이라는 그룹을 정의합니다.localhost는 호스트의 이름입니다.ansible_connection=local은 Ansible 에게 SSH 를 통해 실행하는 대신 로컬에서 명령을 실행하도록 지시합니다.
파일을 저장하고 nano 를 종료하려면 다음을 수행합니다.
Ctrl + X를 누릅니다.- 수정된 버퍼를 저장할지 묻는 메시지가 표시됩니다. 예를 선택하려면
Y를 누릅니다. Enter를 눌러 파일 이름을 확인합니다.
다음으로, 플레이북을 위한 디렉토리를 만들어 보겠습니다.
mkdir playbooks
cd playbooks
mkdir 명령은 "playbooks"라는 새 디렉토리를 만들고, cd를 사용하여 이 새 디렉토리로 이동합니다.
왜 이렇게 하는 걸까요? Ansible 파일을 디렉토리로 구성하는 것은 모범 사례입니다. 특히 프로젝트가 커지고 복잡해짐에 따라 프로젝트를 정리된 상태로 유지합니다.
이러한 단계를 따르면 이제 기본적인 Ansible 환경을 설정했습니다. Ansible 에게 작업할 호스트를 알려주는 인벤토리 파일과 플레이북을 위한 전용 디렉토리가 있습니다. 이 구조는 더 복잡한 기능을 배우고 실험하면서 Ansible 프로젝트를 더 쉽게 관리할 수 있도록 해줍니다.
조건문 소개
Ansible 의 조건문 (conditionals) 을 사용하면 특정 조건에 따라 작업 실행을 제어할 수 있습니다. 이는 시스템의 상태 또는 특정 변수의 값에 따라 다른 작업을 수행해야 할 때 매우 유용합니다.
조건문의 사용법을 보여주는 간단한 플레이북을 만들어 보겠습니다.
nano conditional_example.yml
이 명령은 conditional_example.yml이라는 새 파일을 만들기 위해 nano 텍스트 편집기를 엽니다. 이제 다음 내용을 추가해 보겠습니다.
---
- name: Conditional Example
hosts: localhost
gather_facts: yes
tasks:
- name: Check OS family
debug:
msg: "This is a Debian-based system"
when: ansible_os_family == "Debian"
- name: Check OS family (alternative)
debug:
msg: "This is not a Debian-based system"
when: ansible_os_family != "Debian"
자세히 살펴보겠습니다.
- 파일 상단의
---는 YAML 문서의 시작을 나타냅니다. name: Conditional Example은 플레이북에 이름을 지정합니다.hosts: localhost는 이 플레이북이 로컬 머신에서 실행됨을 지정합니다.gather_facts: yes는 작업을 실행하기 전에 시스템에 대한 정보를 수집하도록 Ansible 에 지시합니다. 이는 조건에서 이러한 팩트를 사용하기 때문에 중요합니다.tasks:는 실행할 작업 목록을 시작합니다.
각 작업은 debug 모듈을 사용하여 메시지를 출력하지만, 실행은 when 절에 의해 제어됩니다.
- 첫 번째 작업은 시스템이 Debian 기반인 경우에만 실행됩니다 (
ansible_os_family == "Debian"). - 두 번째 작업은 시스템이 Debian 기반이 아닌 경우에만 실행됩니다 (
ansible_os_family != "Debian").
ansible_os_family는 대상 시스템에 대해 Ansible 이 수집한 팩트입니다. 여기서는 조건문이 어떻게 작동하는지 보여주기 위해 사용됩니다.
nano 편집기를 저장하고 종료합니다 (Ctrl+X, Y, Enter).
이제 플레이북을 실행해 보겠습니다.
ansible-playbook -i ../inventory.ini conditional_example.yml
이 명령은 Ansible 에게 플레이북을 실행하도록 지시합니다. -i ../inventory.ini 옵션은 앞서 생성한 인벤토리 파일을 지정합니다.
시스템이 Debian 기반인지 여부를 나타내는 출력을 볼 수 있습니다. 시스템의 OS 패밀리에 따라 디버그 메시지 중 하나만 표시됩니다.
이 예제는 조건문을 사용하여 플레이북을 다양한 환경에 적응시키는 방법을 보여줍니다. 실제 시나리오에서는 조건문을 사용하여 서로 다른 OS 유형에 서로 다른 패키지를 설치하거나, 파일이 이미 존재하는 경우 특정 작업을 건너뛸 수 있습니다.
기억하세요. 조건문의 강력함은 각 경우에 대해 별도의 플레이북이 필요 없이 플레이북을 유연하게 만들고 다양한 시나리오를 처리할 수 있는 능력에 있습니다.
다중 조건 사용
실제 시나리오에서는 작업을 실행하기 전에 여러 조건을 확인해야 하는 경우가 많습니다. Ansible 을 사용하면 논리 연산자를 사용하여 여러 조건을 결합할 수 있습니다. 조건문의 이 더 발전된 사용법을 보여주기 위해 다른 플레이북을 만들어 보겠습니다.
multiple_conditions.yml이라는 새 파일을 만듭니다.
nano multiple_conditions.yml
이제 다음 내용을 파일에 추가해 보겠습니다.
---
- name: Multiple Conditions Example
hosts: localhost
gather_facts: yes
vars:
check_memory: true
tasks:
- name: Check OS and Memory
debug:
msg: "This is a Debian-based system with more than 1GB of memory"
when:
- ansible_os_family == "Debian"
- ansible_memtotal_mb > 1024
- check_memory | bool
- name: Print System Information
debug:
msg: "OS: {{ ansible_distribution }}, Memory: {{ ansible_memtotal_mb }} MB"
when: ansible_distribution == "Ubuntu" or ansible_memtotal_mb < 2048
이 플레이북을 자세히 살펴보겠습니다.
플레이북 수준에서
check_memory변수를 정의합니다. 이는 동적으로 설정되거나 플레이북을 실행할 때 추가 변수로 전달될 수 있습니다.첫 번째 작업은 여러 조건을 사용합니다.
- OS 패밀리가 Debian 인지 확인합니다.
- 총 메모리가 1024MB(1GB) 이상인지 확인합니다.
check_memory변수가 true 인지 확인합니다.
작업이 실행되려면 이러한 모든 조건이 true 여야 합니다.
check_memory | bool의|는 값을 부울로 변환하는 필터입니다.두 번째 작업은
or연산자의 사용법을 보여줍니다. 배포판이 Ubuntu 이거나 총 메모리가 2048MB(2GB) 미만인 경우 실행됩니다.여기서는 더 많은 ansible 팩트를 사용하고 있습니다.
ansible_distribution은 특정 배포판 이름을 제공하고,ansible_memtotal_mb는 총 시스템 메모리를 메가바이트 단위로 제공합니다.
nano 편집기를 저장하고 종료합니다.
이제 이 플레이북을 실행해 보겠습니다.
ansible-playbook -i ../inventory.ini multiple_conditions.yml
출력을 관찰합니다. 시스템의 특성에 따라 디버그 메시지 중 하나 또는 둘 다를 볼 수 있습니다.
이 예제는 플레이북을 다양한 시나리오에 매우 적응 가능하게 만들기 위해 복잡한 조건을 생성하는 방법을 보여줍니다. 다양한 시스템 팩트, 사용자 지정 변수 및 논리 연산자를 결합하여 작업이 실행되어야 하는 시기를 미세 조정할 수 있습니다.
루프 소개
Ansible 의 루프를 사용하면 서로 다른 값으로 작업을 여러 번 반복할 수 있습니다. 이는 여러 사용자를 생성하거나, 여러 패키지를 설치하거나, 여러 디렉토리를 생성하는 등 여러 항목에 대해 동일한 작업을 수행해야 할 때 매우 유용합니다.
루프의 사용법을 보여주는 플레이북을 만들어 보겠습니다. loop_example.yml이라는 새 파일을 만듭니다.
nano loop_example.yml
이제 다음 내용을 추가합니다.
---
- name: Loop Example
hosts: localhost
vars:
fruits:
- apple
- banana
- cherry
tasks:
- name: Print fruit names
debug:
msg: "Current fruit: {{ item }}"
loop: "{{ fruits }}"
- name: Create directories
file:
path: "/tmp/{{ item }}"
state: directory
loop:
- dir1
- dir2
- dir3
자세히 살펴보겠습니다.
fruits변수를 과일 이름 목록으로 정의합니다.첫 번째 작업은
fruits목록을 반복하기 위해 루프를 사용합니다. 각 반복마다 현재 값은{{ item }}으로 사용할 수 있습니다.두 번째 작업은
file모듈과 함께 루프를 사용하여 여러 디렉토리를 생성하는 방법을 보여줍니다./tmp폴더에 세 개의 디렉토리를 생성합니다.두 번째 작업에서와 같이 루프를 작업에서 직접 사용할 수 있거나, 첫 번째 작업에서와 같이 변수를 참조할 수 있습니다.
nano 편집기를 저장하고 종료합니다.
이제 이 플레이북을 실행해 보겠습니다.
ansible-playbook -i ../inventory.ini loop_example.yml
이 플레이북을 실행하면 첫 번째 작업이 각 과일 이름을 출력하고, 두 번째 작업이 /tmp에 세 개의 디렉토리를 생성하는 것을 볼 수 있습니다.
루프는 Ansible 의 강력한 기능으로, 플레이북에서 반복적인 코드의 양을 크게 줄일 수 있습니다. 사용자, 패키지 또는 파일과 같은 항목 목록으로 작업할 때 특히 유용합니다.
고급 루프 기법
Ansible 은 복잡한 데이터 구조로 작업하고 루프 프로세스를 더 잘 제어할 수 있는 더 발전된 루핑 기술을 제공합니다. 새로운 플레이북을 만들어 이러한 기술 중 일부를 살펴보겠습니다.
advanced_loops.yml이라는 새 파일을 만듭니다.
nano advanced_loops.yml
이제 다음 내용을 추가합니다.
---
- name: Advanced Loop Techniques
hosts: localhost
vars:
users:
- name: alice
groups: ["developers", "testers"]
- name: bob
groups: ["managers", "developers"]
tasks:
- name: Create users with groups
debug:
msg: "Creating user {{ item.name }} with groups: {{ item.groups | join(', ') }}"
loop: "{{ users }}"
- name: Demonstrate loop_control
debug:
msg: "Processing item {{ index }} - {{ item }}"
loop: ["a", "b", "c", "d"]
loop_control:
index_var: index
- name: Loop over dictionary
debug:
msg: "{{ key }}: {{ value }}"
loop: "{{ {'x': 1, 'y': 2, 'z': 3} | dict2items }}"
vars:
key: "{{ item.key }}"
value: "{{ item.value }}"
이러한 고급 기술을 자세히 살펴보겠습니다.
딕셔너리 목록 반복: 첫 번째 작업은
users목록을 반복하며, 각 항목은 이름과 그룹 목록을 포함하는 딕셔너리입니다. 점 표기법 (item.name,item.groups) 을 사용하여 이러한 중첩된 요소에 액세스할 수 있습니다.loop_control사용: 두 번째 작업은loop_control을 보여줍니다. 이를 통해 루프 변수 (기본값은item) 의 이름을 변경하고 현재 루프 인덱스에 액세스할 수 있습니다. 여기서는index_var: index를 사용하여 현재 반복 횟수를 추적하는 변수index를 만듭니다.딕셔너리 반복: 마지막 작업은 딕셔너리를 반복하는 방법을 보여줍니다.
dict2items필터를 사용하여 딕셔너리를 반복할 수 있는 키 - 값 쌍 목록으로 변환합니다. 그런 다음item.key및item.value를 사용하여 딕셔너리의 키와 값에 액세스합니다.
nano 편집기를 저장하고 종료합니다.
이제 이 플레이북을 실행해 보겠습니다.
ansible-playbook -i ../inventory.ini advanced_loops.yml
이 플레이북을 실행하면 이러한 고급 루핑 기술이 어떻게 작동하는지 볼 수 있습니다. 출력은 다음을 표시합니다.
- 해당 그룹과 함께 사용자 생성 메시지
- 인덱스와 함께 처리되는 항목
- 딕셔너리의 키 - 값 쌍
이러한 고급 기술을 사용하면 더 복잡한 데이터 구조로 작업하고 루프를 더 세밀하게 제어할 수 있습니다. 중첩된 데이터를 처리하거나, 루프 인덱스를 추적해야 하거나, 딕셔너리로 작업할 때 특히 유용합니다.
요약
이 랩에서는 Ansible 조건문과 루프에 대해 배웠습니다. 이 두 가지 강력한 기능을 사용하면 더 동적이고 효율적인 플레이북을 만들 수 있습니다. 주요 내용은 다음과 같습니다.
- 조건문 (
when절) 을 사용하면 대상 시스템에 대한 팩트 (fact) 또는 사용자 정의 변수와 같은 특정 조건에 따라 작업 실행을 제어할 수 있습니다. and및or과 같은 논리 연산자를 사용하여 여러 조건을 결합하여 더 복잡한 조건문을 만들 수 있습니다.- 루프 (
loop키워드) 를 사용하면 서로 다른 값으로 작업을 반복하여 효율성을 높이고 플레이북 복잡성을 줄일 수 있습니다. - Ansible 은 목록, 딕셔너리 및 더 복잡한 데이터 구조를 반복하는 것을 포함하여 다양한 루프 유형을 지원합니다.
loop_control및 딕셔너리 반복과 같은 고급 루프 기술은 반복적인 작업을 처리하는 데 훨씬 더 많은 유연성을 제공합니다.
이러한 기능은 다양한 시나리오에 적응하고 여러 항목을 효율적으로 관리할 수 있는 유연하고 강력한 Ansible 플레이북을 만드는 데 필수적입니다. Ansible 로 계속 작업하면서 조건문과 루프를 플레이북에 통합하여 더 동적이고 효율적으로 만드는 연습을 하십시오.
이러한 기능을 사용할 때는 항상 플레이북의 가독성과 유지 관리성을 고려하십시오. 이러한 기능은 코드를 크게 단순화할 수 있지만, 과도한 사용 또는 지나치게 복잡한 조건 및 루프는 플레이북을 이해하고 유지 관리하기 어렵게 만들 수 있습니다.


