Ansible 조건문 및 루프

AnsibleBeginner
지금 연습하기

소개

이 랩에서는 Ansible 의 두 가지 강력한 기능인 조건문 (conditionals) 과 루프 (loops) 를 탐구합니다. 이러한 개념을 통해 특정 조건에 따라 작업 실행을 제어하고 여러 항목에 대해 작업을 반복함으로써 더욱 동적이고 효율적인 플레이북을 만들 수 있습니다. 이 랩을 마치면 플레이북에서 결정을 내리기 위해 조건문을 사용하는 방법과 반복적인 작업을 효율적으로 수행하기 위해 루프를 구현하는 방법을 이해하게 됩니다. 이 지식을 통해 인프라 관리를 위한 더욱 유연하고 강력한 Ansible 플레이북을 만들 수 있습니다.

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

환경 설정

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 를 종료하려면 다음을 수행합니다.

  1. Ctrl + X를 누릅니다.
  2. 수정된 버퍼를 저장할지 묻는 메시지가 표시됩니다. 예를 선택하려면 Y를 누릅니다.
  3. 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"

자세히 살펴보겠습니다.

  1. 파일 상단의 ---는 YAML 문서의 시작을 나타냅니다.
  2. name: Conditional Example은 플레이북에 이름을 지정합니다.
  3. hosts: localhost는 이 플레이북이 로컬 머신에서 실행됨을 지정합니다.
  4. gather_facts: yes는 작업을 실행하기 전에 시스템에 대한 정보를 수집하도록 Ansible 에 지시합니다. 이는 조건에서 이러한 팩트를 사용하기 때문에 중요합니다.
  5. 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

이 플레이북을 자세히 살펴보겠습니다.

  1. 플레이북 수준에서 check_memory 변수를 정의합니다. 이는 동적으로 설정되거나 플레이북을 실행할 때 추가 변수로 전달될 수 있습니다.

  2. 첫 번째 작업은 여러 조건을 사용합니다.

    • OS 패밀리가 Debian 인지 확인합니다.
    • 총 메모리가 1024MB(1GB) 이상인지 확인합니다.
    • check_memory 변수가 true 인지 확인합니다.

    작업이 실행되려면 이러한 모든 조건이 true 여야 합니다. check_memory | bool|는 값을 부울로 변환하는 필터입니다.

  3. 두 번째 작업은 or 연산자의 사용법을 보여줍니다. 배포판이 Ubuntu 이거나 총 메모리가 2048MB(2GB) 미만인 경우 실행됩니다.

  4. 여기서는 더 많은 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

자세히 살펴보겠습니다.

  1. fruits 변수를 과일 이름 목록으로 정의합니다.

  2. 첫 번째 작업은 fruits 목록을 반복하기 위해 루프를 사용합니다. 각 반복마다 현재 값은 {{ item }}으로 사용할 수 있습니다.

  3. 두 번째 작업은 file 모듈과 함께 루프를 사용하여 여러 디렉토리를 생성하는 방법을 보여줍니다. /tmp 폴더에 세 개의 디렉토리를 생성합니다.

  4. 두 번째 작업에서와 같이 루프를 작업에서 직접 사용할 수 있거나, 첫 번째 작업에서와 같이 변수를 참조할 수 있습니다.

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 }}"

이러한 고급 기술을 자세히 살펴보겠습니다.

  1. 딕셔너리 목록 반복:
    첫 번째 작업은 users 목록을 반복하며, 각 항목은 이름과 그룹 목록을 포함하는 딕셔너리입니다. 점 표기법 (item.name, item.groups) 을 사용하여 이러한 중첩된 요소에 액세스할 수 있습니다.

  2. loop_control 사용:
    두 번째 작업은 loop_control을 보여줍니다. 이를 통해 루프 변수 (기본값은 item) 의 이름을 변경하고 현재 루프 인덱스에 액세스할 수 있습니다. 여기서는 index_var: index를 사용하여 현재 반복 횟수를 추적하는 변수 index를 만듭니다.

  3. 딕셔너리 반복:
    마지막 작업은 딕셔너리를 반복하는 방법을 보여줍니다. dict2items 필터를 사용하여 딕셔너리를 반복할 수 있는 키 - 값 쌍 목록으로 변환합니다. 그런 다음 item.keyitem.value를 사용하여 딕셔너리의 키와 값에 액세스합니다.

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

이제 이 플레이북을 실행해 보겠습니다.

ansible-playbook -i ../inventory.ini advanced_loops.yml

이 플레이북을 실행하면 이러한 고급 루핑 기술이 어떻게 작동하는지 볼 수 있습니다. 출력은 다음을 표시합니다.

  • 해당 그룹과 함께 사용자 생성 메시지
  • 인덱스와 함께 처리되는 항목
  • 딕셔너리의 키 - 값 쌍

이러한 고급 기술을 사용하면 더 복잡한 데이터 구조로 작업하고 루프를 더 세밀하게 제어할 수 있습니다. 중첩된 데이터를 처리하거나, 루프 인덱스를 추적해야 하거나, 딕셔너리로 작업할 때 특히 유용합니다.

요약

이 랩에서는 Ansible 조건문과 루프에 대해 배웠습니다. 이 두 가지 강력한 기능을 사용하면 더 동적이고 효율적인 플레이북을 만들 수 있습니다. 주요 내용은 다음과 같습니다.

  1. 조건문 (when 절) 을 사용하면 대상 시스템에 대한 팩트 (fact) 또는 사용자 정의 변수와 같은 특정 조건에 따라 작업 실행을 제어할 수 있습니다.
  2. andor과 같은 논리 연산자를 사용하여 여러 조건을 결합하여 더 복잡한 조건문을 만들 수 있습니다.
  3. 루프 (loop 키워드) 를 사용하면 서로 다른 값으로 작업을 반복하여 효율성을 높이고 플레이북 복잡성을 줄일 수 있습니다.
  4. Ansible 은 목록, 딕셔너리 및 더 복잡한 데이터 구조를 반복하는 것을 포함하여 다양한 루프 유형을 지원합니다.
  5. loop_control 및 딕셔너리 반복과 같은 고급 루프 기술은 반복적인 작업을 처리하는 데 훨씬 더 많은 유연성을 제공합니다.

이러한 기능은 다양한 시나리오에 적응하고 여러 항목을 효율적으로 관리할 수 있는 유연하고 강력한 Ansible 플레이북을 만드는 데 필수적입니다. Ansible 로 계속 작업하면서 조건문과 루프를 플레이북에 통합하여 더 동적이고 효율적으로 만드는 연습을 하십시오.

이러한 기능을 사용할 때는 항상 플레이북의 가독성과 유지 관리성을 고려하십시오. 이러한 기능은 코드를 크게 단순화할 수 있지만, 과도한 사용 또는 지나치게 복잡한 조건 및 루프는 플레이북을 이해하고 유지 관리하기 어렵게 만들 수 있습니다.