본문 바로가기

리눅스

[draft] Ansible에서 사용자 정의 Facts 정의하고 사용하는 방법

Ansible에서 사용자 정의 Facts(Local Facts) 정의하고 사용하는 방법

Ansible은 기본적으로 다양한 시스템 정보를 Facts 형태로 수집합니다.

여기에 사용자 정의 Facts(Local Facts)를 추가하면 환경별 설정이나 애플리케이션 정보를 플레이북과 템플릿에서 변수처럼 재사용할 수 있습니다.

테스트 환경

node Server  
Control node control1  
Managed nodes centos7  
Managed nodes ubuntu22  

1. 관리 대상 노드에서 facts.d 디렉터리 생성

Local Facts는 관리 대상 노드의 /etc/ansible/facts.d 디렉터리에 위치해야 합니다.

sudo mkdir -p /etc/ansible/facts.d

2. 사용자 정의 Facts 파일 생성

Facts 파일은 보통 .fact 확장자를 사용하며 INI 형식 또는 JSON 형식을 지원합니다.

 

INI 형식 예제 (test.fact)

cat <<EOF | sudo tee /etc/ansible/facts.d/test.fact
[web_server]
web_name=nginx
web_version=1.24.0

[was_server]
was_name=php-fpm
was_version=8.1.27
EOF

확인

cat /etc/ansible/facts.d/test.fact

3. Control Node에서 사용자 정의 Facts 확인 (Ad-hoc)

Facts는 setup 모듈로 수집되며 Local Facts는 ansible_local 하위에 포함됩니다.

 

centos7

ansible -i inventory centos7 -m setup -a 'filter=ansible_local'
centos7 | SUCCESS => {
    "ansible_facts": {
        "ansible_local": {
            "test": {
                "was_server": {
                    "was_name": "php-fpm",
                    "was_version": "8.1.27"
                },
                "web_server": {
                    "web_name": "nginx",
                    "web_version": "1.24.0"
                }
            }
        },
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false
}

ubuntu22

ansible -i inventory ubuntu22 -m setup -a 'filter=ansible_local'
ubuntu22 | SUCCESS => {
    "ansible_facts": {
        "ansible_local": {
            "test": {
                "was_server": {
                    "was_name": "php-fpm",
                    "was_version": "8.1.27"
                },
                "web_server": {
                    "web_name": "nginx",
                    "web_version": "1.24.0"
                }
            }
        },
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false
}

4. 플레이북에서 사용자 정의 Facts 사용하기 (조회)

플레이북 작성

vim local_facts_get.yml
---
- name: 그룹 변수가 있는 플레이북 예제(Group Variables)
  hosts: zdocker
  gather_facts: true

  tasks:
    - name: Print local facts
      debug:
        msg: "{{ ansible_local }}"

    - name: "Web Server"
      debug:
        msg: "{{ ansible_local['test']['web_server']['web_name'] }} {{ ansible_local['test']['web_server']['web_version'] }}"

    - name: "Middleware Server"
      debug:
        msg: "{{ ansible_local.test.was_server.was_name }} {{ ansible_local.test.was_server.was_version }}"


### Ansible Playbook Execute
# ansible-inventory -i inventory --graph
#
# ansible-playbook -i inventory tmp/ansible_local.yml

플레이북 실행

ansible-playbook -i inventory tmp/local_facts_get.yml
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details

PLAY [그룹 변수가 있는 플레이북 예제(Group Variables)] ****************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [ubuntu22]
ok: [centos7]

TASK [Print local facts] *******************************************************************************************
ok: [centos7] => {
    "msg": {
        "test": {
            "was_server": {
                "was_name": "php-fpm",
                "was_version": "8.1.27"
            },
            "web_server": {
                "web_name": "nginx",
                "web_version": "1.24.0"
            }
        }
    }
}
ok: [ubuntu22] => {
    "msg": {
        "test": {
            "was_server": {
                "was_name": "php-fpm",
                "was_version": "8.1.27"
            },
            "web_server": {
                "web_name": "nginx",
                "web_version": "1.24.0"
            }
        }
    }
}

TASK [Web Server] **************************************************************************************************
ok: [centos7] => {
    "msg": "nginx 1.24.0"
}
ok: [ubuntu22] => {
    "msg": "nginx 1.24.0"
}

TASK [Middleware Server] *******************************************************************************************
ok: [centos7] => {
    "msg": "php-fpm 8.1.27"
}
ok: [ubuntu22] => {
    "msg": "php-fpm 8.1.27"
}

PLAY RECAP *********************************************************************************************************
centos7                    : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
ubuntu22                   : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

5. 플레이북으로 사용자 정의 Facts 생성 & 관리하기

운영 환경에서는 수동 생성 대신 플레이북으로 Facts를 관리하는 것이 좋습니다.

 

사용자 정의 Facts 생성 플레이북

vim local_facts_set.yml
---
- name: 예제 플레이북 (그룹 변수 포함)
  hosts: zdocker
  become: yes
  gather_facts: true

  tasks:
    - name: Create facts directory
      file:
        state: directory
        dest: "/etc/ansible/facts.d/"
        recurse: yes
      tags: debug_facts_set

    - name: Create facts file
      file:
        state: touch
        dest: "/etc/ansible/facts.d/test.fact"
      tags: debug_facts_set

    - name: Edit facts file
      copy:
        content: |
          [web_server]
          web_name=nginx
          web_version=1.24.0
          [was_server]
          was_name=php-fpm
          was_version=8.1.27
          [cache_server]
          cache_name=redis
          cache_version=6.1.27
        dest: "/etc/ansible/facts.d/test.fact"
      tags: debug_facts_set

    - name: Print local facts
      debug:
        msg: "{{ ansible_local | safe }}"
      tags: debug_facts_get

    - name: "Web Server"
      debug:
        msg: "{{ ansible_local['test']['web_server']['web_name'] }} {{ ansible_local['test']['web_server']['web_version'] }}"
      tags: debug_facts_get

    - name: "Middleware Server"
      debug:
        msg: "{{ ansible_local.test.was_server.was_name }} {{ ansible_local.test.was_server.was_version }}"
      tags: debug_facts_get

    - name: "Cache Server"
      debug:
        msg: "{{ ansible_local.test.cache_server.cache_name }} {{ ansible_local.test.cache_server.cache_version }}"
      tags: debug_facts_get

플레이북 실행

ansible-playbook -i inventory tmp/local_facts_set.yml
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details

PLAY [예제 플레이북 (그룹 변수 포함)] *******************************************************************************

TASK [Gathering Facts] **********************************************************************************************
ok: [ubuntu22]
ok: [centos7]

TASK [Create facts directory] ***************************************************************************************
ok: [ubuntu22]
ok: [centos7]

TASK [Create facts file] ********************************************************************************************
changed: [ubuntu22]
changed: [centos7]

TASK [Edit facts file] **********************************************************************************************
ok: [ubuntu22]
ok: [centos7]

TASK [Print local facts] ********************************************************************************************
ok: [centos7] => {
    "msg": {
        "test": {
            "cache_server": {
                "cache_name": "redis",
                "cache_version": "6.1.27"
            },
            "was_server": {
                "was_name": "php-fpm",
                "was_version": "8.1.27"
            },
            "web_server": {
                "web_name": "nginx",
                "web_version": "1.24.0"
            }
        }
    }
}
ok: [ubuntu22] => {
    "msg": {
        "test": {
            "cache_server": {
                "cache_name": "redis",
                "cache_version": "6.1.27"
            },
            "was_server": {
                "was_name": "php-fpm",
                "was_version": "8.1.27"
            },
            "web_server": {
                "web_name": "nginx",
                "web_version": "1.24.0"
            }
        }
    }
}

TASK [Web Server] ***************************************************************************************************
ok: [centos7] => {
    "msg": "nginx 1.24.0"
}
ok: [ubuntu22] => {
    "msg": "nginx 1.24.0"
}

TASK [Middleware Server] ********************************************************************************************
ok: [ubuntu22] => {
    "msg": "php-fpm 8.1.27"
}
ok: [centos7] => {
    "msg": "php-fpm 8.1.27"
}

TASK [Cache Server] *************************************************************************************************
ok: [centos7] => {
    "msg": "redis 6.1.27"
}
ok: [ubuntu22] => {
    "msg": "redis 6.1.27"
}

PLAY RECAP **********************************************************************************************************
centos7                    : ok=8    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
ubuntu22                   : ok=8    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

6. 사용자 정의 Facts의 핵심 포인트 정리

Facts 로딩 구조

/etc/ansible/facts.d/test.fact
        ↓
ansible_local.test.web_server.web_name

조건 분기

when: ansible_local.test.web_server.web_name == "nginx"

템플릿 활용

{{ ansible_local.test.cache_server.cache_name }}

Facts 갱신 주의사항

Facts는 플레이북 시작 시 수집

Facts 파일을 변경한 경우

  • 다음 플레이북 실행 시 반영
  • 또는 setup 모듈 재실행 필요