Ansible Hostvars

AnsibleBeginner
지금 연습하기

소개

Ansible hostvars 는 인프라 내 각 관리 호스트에 대한 정보를 저장하는 필수 변수입니다. 이러한 변수를 통해 다양한 서버 및 환경에 적응하는 동적이고 유연한 자동화 워크플로우를 만들 수 있습니다.

이 실습에서는 Ansible hostvars 를 처음부터 다루는 방법을 배우게 됩니다. 간단한 인벤토리를 설정하고, 플레이북에서 hostvars 에 액세스하고, 템플릿에서 사용하며, 실제 사용 사례를 탐색합니다. 이 실습이 끝나면 hostvars 를 활용하여 Ansible 자동화를 더욱 강력하고 적응력 있게 만드는 방법을 이해하게 될 것입니다.

이것은 단계별 지침을 제공하여 학습하고 연습하는 데 도움이 되는 Guided Lab 입니다. 각 단계를 완료하고 실습 경험을 얻으려면 지침을 주의 깊게 따르십시오. 과거 데이터에 따르면 이 실습은 고급 레벨이며 완료율은 50%입니다. 학습자로부터 100% 긍정적인 리뷰율을 받았습니다.

실습 환경 설정

Ansible hostvars 를 자세히 살펴보기 전에 작업 환경을 설정해야 합니다. 이 단계에서는 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 2023, 11:42:32) [GCC 11.3.0]
  jinja version = 3.0.3
  libyaml = True

프로젝트 구조 생성

이제 Ansible 프로젝트에 대한 적절한 디렉토리 구조를 생성해 보겠습니다.

mkdir -p ~/project/ansible_hostvars/inventory
mkdir -p ~/project/ansible_hostvars/group_vars
mkdir -p ~/project/ansible_hostvars/playbooks
mkdir -p ~/project/ansible_hostvars/templates
cd ~/project/ansible_hostvars

인벤토리 파일 생성

Ansible 은 관리할 호스트와 그룹을 정의하기 위해 인벤토리 파일을 사용합니다. 몇 가지 예시 호스트로 간단한 인벤토리 파일을 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/inventory/hosts << 'EOF'
[webservers]
web01 ansible_host=192.168.1.10 http_port=80 max_connections=100
web02 ansible_host=192.168.1.11 http_port=8080 max_connections=200

[dbservers]
db01 ansible_host=192.168.1.20 db_port=3306 backup_dir=/var/backups
db02 ansible_host=192.168.1.21 db_port=5432 backup_dir=/opt/backups

[all:vars]
ansible_connection=local
ansible_user=labex
environment=development
EOF

이 인벤토리 파일에서:

  • webserversdbservers라는 두 개의 그룹을 정의했습니다.
  • 각 호스트에는 http_port 또는 db_port와 같은 특정 변수가 있습니다.
  • [all:vars] 아래의 모든 호스트에 대해 전역 변수를 설정했습니다.
  • 이 실습 환경이므로 ansible_connection=local을 사용하고 있습니다.

프로젝트 디렉토리에 간단한 ansible.cfg 파일도 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/ansible.cfg << 'EOF'
[defaults]
inventory = ./inventory/hosts
host_key_checking = False
EOF

이제 인벤토리를 확인해 보겠습니다.

cd ~/project/ansible_hostvars
ansible-inventory --list

인벤토리의 모든 호스트와 해당 변수를 표시하는 JSON 출력이 표시되어야 합니다.

축하합니다! Ansible 환경 설정을 성공적으로 완료하고 호스트 변수가 포함된 인벤토리를 만들었습니다. 다음 단계에서는 hostvars 를 사용하여 이러한 변수에 액세스하는 방법을 살펴보겠습니다.

Ansible Hostvars 탐색

이제 환경 설정을 마쳤으므로 Ansible hostvars 를 탐색하고 플레이북에서 액세스하는 방법을 배워보겠습니다.

Hostvars 이해

Ansible 에서 hostvars는 인벤토리의 모든 호스트에 대한 정보를 포함하는 특수 변수입니다. 이는 키가 호스트 이름이고 값이 각 호스트에 대해 정의된 모든 변수를 포함하는 사전인 사전입니다.

hostvars 를 탐색하는 간단한 플레이북을 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/playbooks/explore_hostvars.yml << 'EOF'
---
- name: Explore hostvars
  hosts: all
  gather_facts: no
  tasks:
    - name: Display host variables for the current host
      debug:
        msg: "Host: {{ inventory_hostname }} has the following variables: {{ hostvars[inventory_hostname] }}"
      
    - name: Display a specific variable for the current host
      debug:
        msg: "Host {{ inventory_hostname }} has environment: {{ hostvars[inventory_hostname]['environment'] }}"
EOF

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

cd ~/project/ansible_hostvars
ansible-playbook playbooks/explore_hostvars.yml

각 호스트의 변수가 포함된 출력이 표시되어야 합니다. 첫 번째 작업은 각 호스트의 모든 변수를 보여주고, 두 번째 작업은 특정 변수를 보여줍니다.

호스트별 변수 플레이북 생성

다양한 유형의 호스트 변수에 액세스하는 방법을 보여주는 또 다른 플레이북을 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/playbooks/host_specific_vars.yml << 'EOF'
---
- name: Working with host-specific variables
  hosts: all
  gather_facts: no
  tasks:
    - name: Display web server information
      debug:
        msg: "Web server {{ inventory_hostname }} running on port {{ hostvars[inventory_hostname]['http_port'] | default('N/A') }}"
      when: inventory_hostname in groups['webservers']
    
    - name: Display database server information
      debug:
        msg: "Database server {{ inventory_hostname }} running on port {{ hostvars[inventory_hostname]['db_port'] | default('N/A') }}"
      when: inventory_hostname in groups['dbservers']
EOF

이 플레이북을 실행합니다.

cd ~/project/ansible_hostvars
ansible-playbook playbooks/host_specific_vars.yml

각각의 변수에 따라 웹 서버와 데이터베이스 서버에 대한 다른 정보가 표시되는 출력을 볼 수 있습니다.

다른 호스트의 변수 액세스

hostvars 의 강력한 기능 중 하나는 인벤토리의 모든 호스트에서 변수에 액세스할 수 있다는 것입니다. 이를 보여주는 플레이북을 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/playbooks/cross_host_vars.yml << 'EOF'
---
- name: Access variables from other hosts
  hosts: web01
  gather_facts: no
  tasks:
    - name: Display information about web01 and db01
      debug:
        msg: |
          Web server: {{ inventory_hostname }}
          Web server port: {{ hostvars[inventory_hostname]['http_port'] }}
          
          Database server: db01
          Database port: {{ hostvars['db01']['db_port'] }}
          Backup directory: {{ hostvars['db01']['backup_dir'] }}
EOF

이 플레이북을 실행합니다.

cd ~/project/ansible_hostvars
ansible-playbook playbooks/cross_host_vars.yml

플레이북은 web01에서만 실행되지만 web01db01 모두의 정보가 포함된 출력을 볼 수 있습니다.

이는 hostvars 가 인벤토리의 모든 호스트에서 변수에 액세스할 수 있도록 하여 자동화에서 호스트 간의 복잡한 관계 및 종속성을 생성할 수 있음을 보여줍니다.

템플릿에서 Hostvars 사용하기

템플릿은 Ansible 의 가장 강력한 기능 중 하나이며, hostvars 와 결합하면 더욱 강력해집니다. 이 단계에서는 Jinja2 템플릿 내에서 hostvars 를 사용하여 동적 구성 파일을 생성하는 방법을 배웁니다.

Jinja2 템플릿 소개

Ansible 은 동적 콘텐츠를 생성하기 위해 Jinja2 템플릿 엔진을 사용합니다. 템플릿을 사용하면 다양한 호스트 및 시나리오에 맞게 조정되는 구성 파일을 만들 수 있습니다.

간단한 웹 서버 구성 템플릿을 만들어 보겠습니다.

mkdir -p ~/project/ansible_hostvars/templates
cat > ~/project/ansible_hostvars/templates/nginx.conf.j2 << 'EOF'
## Server configuration for {{ inventory_hostname }}
## Generated by Ansible

server {
    listen {{ hostvars[inventory_hostname]['http_port'] | default(80) }};
    server_name {{ inventory_hostname }};
    
    root /var/www/html;
    
    ## Environment: {{ hostvars[inventory_hostname]['environment'] }}
    
    ## Max connections: {{ hostvars[inventory_hostname]['max_connections'] | default(50) }}
    
    location / {
        index index.html index.htm;
    }
}
EOF

이제 데이터베이스 구성 템플릿을 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/templates/db.conf.j2 << 'EOF'
## Database configuration for {{ inventory_hostname }}
## Generated by Ansible

port = {{ hostvars[inventory_hostname]['db_port'] }}
backup_directory = {{ hostvars[inventory_hostname]['backup_dir'] }}
environment = {{ hostvars[inventory_hostname]['environment'] }}

## Database hosts in environment:
{% for host in groups['dbservers'] %}
## - {{ host }} ({{ hostvars[host]['ansible_host'] }})
{% endfor %}
EOF

템플릿 적용 플레이북 생성

이 템플릿을 적용하는 플레이북을 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/playbooks/apply_templates.yml << 'EOF'
---
- name: Apply configuration templates
  hosts: all
  gather_facts: no
  tasks:
    - name: Create output directory
      file:
        path: ~/project/ansible_hostvars/output
        state: directory
      run_once: true
    
    - name: Apply web server configuration template
      template:
        src: ../templates/nginx.conf.j2
        dest: ~/project/ansible_hostvars/output/{{ inventory_hostname }}-nginx.conf
      when: inventory_hostname in groups['webservers']
    
    - name: Apply database configuration template
      template:
        src: ../templates/db.conf.j2
        dest: ~/project/ansible_hostvars/output/{{ inventory_hostname }}-db.conf
      when: inventory_hostname in groups['dbservers']
EOF

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

cd ~/project/ansible_hostvars
ansible-playbook playbooks/apply_templates.yml

플레이북을 실행한 후 생성된 구성 파일을 확인합니다.

ls -l ~/project/ansible_hostvars/output/

각 호스트에 대해 생성된 구성 파일을 볼 수 있어야 합니다. 웹 서버 구성 중 하나를 살펴보겠습니다.

cat ~/project/ansible_hostvars/output/web01-nginx.conf

데이터베이스 구성 중 하나를 살펴보겠습니다.

cat ~/project/ansible_hostvars/output/db01-db.conf

템플릿이 hostvars 를 사용하여 각 호스트에 맞게 구성을 동적으로 생성하는 방법을 확인합니다.

템플릿에서 루프 및 조건문 사용하기

템플릿은 루프와 조건문을 사용하여 더욱 동적인 콘텐츠를 만들 수 있습니다. 포괄적인 호스트 파일 템플릿을 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/templates/hosts.j2 << 'EOF'
## Hosts file generated by Ansible
127.0.0.1 localhost

## Web servers
{% for host in groups['webservers'] %}
{{ hostvars[host]['ansible_host'] }} {{ host }}
{% endfor %}

## Database servers
{% for host in groups['dbservers'] %}
{{ hostvars[host]['ansible_host'] }} {{ host }}
{% endfor %}
EOF

플레이북에 이 템플릿을 적용하는 작업을 추가해 보겠습니다.

cat > ~/project/ansible_hostvars/playbooks/hosts_template.yml << 'EOF'
---
- name: Create hosts file from template
  hosts: localhost
  gather_facts: no
  tasks:
    - name: Create output directory
      file:
        path: ~/project/ansible_hostvars/output
        state: directory
    
    - name: Generate hosts file
      template:
        src: ../templates/hosts.j2
        dest: ~/project/ansible_hostvars/output/hosts
EOF

이 플레이북을 실행합니다.

cd ~/project/ansible_hostvars
ansible-playbook playbooks/hosts_template.yml

생성된 호스트 파일을 확인합니다.

cat ~/project/ansible_hostvars/output/hosts

인벤토리에서 동적으로 생성된 모든 웹 서버 및 데이터베이스 서버가 포함된 호스트 파일을 볼 수 있어야 합니다.

고급 Hostvars 기법

이제 hostvars 의 기본 사항을 익혔으니, Ansible 에서 hostvars 를 다루는 몇 가지 고급 기법을 살펴보겠습니다.

그룹 변수와 Hostvars 함께 사용하기

그룹 변수를 사용하면 전체 호스트 그룹에 적용되는 변수를 정의할 수 있습니다. 인벤토리 디렉토리 내의 올바른 위치에 그룹 변수 파일을 만들어 보겠습니다.

mkdir -p ~/project/ansible_hostvars/inventory/group_vars
cat > ~/project/ansible_hostvars/inventory/group_vars/webservers.yml << 'EOF'
---
web_server_type: nginx
default_document_root: /var/www/html
enable_ssl: true
ssl_cert_path: /etc/ssl/certs
EOF

데이터베이스 서버에 대한 다른 파일도 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/inventory/group_vars/dbservers.yml << 'EOF'
---
backup_frequency: daily
backup_retention: 7
monitoring_enabled: true
alert_email: admin@example.com
EOF

이제 이러한 그룹 변수를 hostvars 를 통해 액세스하는 플레이북을 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/playbooks/group_vars_demo.yml << 'EOF'
---
- name: Demonstrate group variables with hostvars
  hosts: all
  gather_facts: no
  tasks:
    - name: Display web server group variables
      debug:
        msg: |
          Host: {{ inventory_hostname }}
          Web Server Type: {{ hostvars[inventory_hostname]['web_server_type'] | default('N/A') }}
          Document Root: {{ hostvars[inventory_hostname]['default_document_root'] | default('N/A') }}
          SSL Enabled: {{ hostvars[inventory_hostname]['enable_ssl'] | default('N/A') }}
      when: inventory_hostname in groups['webservers']
    
    - name: Display database server group variables
      debug:
        msg: |
          Host: {{ inventory_hostname }}
          Backup Frequency: {{ hostvars[inventory_hostname]['backup_frequency'] | default('N/A') }}
          Backup Retention: {{ hostvars[inventory_hostname]['backup_retention'] | default('N/A') }}
          Monitoring Enabled: {{ hostvars[inventory_hostname]['monitoring_enabled'] | default('N/A') }}
      when: inventory_hostname in groups['dbservers']
EOF

이 플레이북을 실행합니다.

cd ~/project/ansible_hostvars
ansible-playbook playbooks/group_vars_demo.yml

hostvars 를 통해 그룹 변수가 어떻게 사용 가능한지 보여주는 출력을 볼 수 있어야 합니다.

동적 인벤토리 보고서 생성

인벤토리 데이터를 기반으로 보고서를 생성하는 플레이북을 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/playbooks/inventory_report.yml << 'EOF'
---
- name: Generate inventory reports
  hosts: localhost
  gather_facts: no
  tasks:
    - name: Create output directory
      file:
        path: ~/project/ansible_hostvars/output
        state: directory
    
    - name: Generate web servers report
      template:
        src: ../templates/web_report.j2
        dest: ~/project/ansible_hostvars/output/web_servers_report.txt
    
    - name: Generate database servers report
      template:
        src: ../templates/db_report.j2
        dest: ~/project/ansible_hostvars/output/db_servers_report.txt
EOF

이제 이러한 보고서에 대한 템플릿을 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/templates/web_report.j2 << 'EOF'
========================================
WEB SERVERS INVENTORY REPORT
========================================

{% for host in groups['webservers'] %}
HOST: {{ host }}
  IP Address: {{ hostvars[host]['ansible_host'] }}
  HTTP Port: {{ hostvars[host]['http_port'] }}
  Max Connections: {{ hostvars[host]['max_connections'] | default('Not specified') }}
  Web Server Type: {{ hostvars[host]['web_server_type'] | default('Not specified') }}
  Environment: {{ hostvars[host]['environment'] }}

{% endfor %}
EOF
cat > ~/project/ansible_hostvars/templates/db_report.j2 << 'EOF'
========================================
DATABASE SERVERS INVENTORY REPORT
========================================

{% for host in groups['dbservers'] %}
HOST: {{ host }}
  IP Address: {{ hostvars[host]['ansible_host'] }}
  DB Port: {{ hostvars[host]['db_port'] }}
  Backup Directory: {{ hostvars[host]['backup_dir'] }}
  Backup Frequency: {{ hostvars[host]['backup_frequency'] | default('Not specified') }}
  Backup Retention: {{ hostvars[host]['backup_retention'] | default('Not specified') }}
  Environment: {{ hostvars[host]['environment'] }}

{% endfor %}
EOF

이제 인벤토리 보고서 플레이북을 실행합니다.

cd ~/project/ansible_hostvars
ansible-playbook playbooks/inventory_report.yml

생성된 보고서를 확인합니다.

cat ~/project/ansible_hostvars/output/web_servers_report.txt
cat ~/project/ansible_hostvars/output/db_servers_report.txt

이 보고서는 hostvars 를 사용하여 인프라에 대한 포괄적인 보고서를 생성하는 방법을 보여줍니다.

누락된 변수 처리

hostvars 를 다룰 때는 변수가 누락될 수 있는 경우를 처리하는 것이 중요합니다. 안전한 변수 액세스를 시연하는 플레이북을 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/playbooks/safe_variable_access.yml << 'EOF'
---
- name: Demonstrate safe variable access
  hosts: all
  gather_facts: no
  tasks:
    - name: Using default filter
      debug:
        msg: "The value is: {{ hostvars[inventory_hostname]['nonexistent_variable'] | default('Not defined') }}"
    
    - name: Using conditional checks
      debug:
        msg: >
          {% if 'special_variable' in hostvars[inventory_hostname] %}
          The special variable is: {{ hostvars[inventory_hostname]['special_variable'] }}
          {% else %}
          The special variable is not defined for this host.
          {% endif %}
EOF

이 플레이북을 실행합니다.

cd ~/project/ansible_hostvars
ansible-playbook playbooks/safe_variable_access.yml

출력은 default 필터와 조건부 검사를 사용하여 누락된 변수를 안전하게 처리하는 방법을 보여줍니다.

모범 사례 및 실제 적용 사례

마지막 단계에서는 hostvars 를 사용하는 모범 사례를 살펴보고 실제 적용 사례를 살펴보겠습니다.

변수 구성 모범 사례

유지 관리하기 쉬운 Ansible 코드를 유지하려면 변수를 올바르게 구성하는 것이 중요합니다. 모범 사례를 시연하기 위해 더 구조화된 인벤토리 설정을 만들어 보겠습니다.

mkdir -p ~/project/ansible_hostvars/inventory/group_vars/all
mkdir -p ~/project/ansible_hostvars/inventory/group_vars/webservers
mkdir -p ~/project/ansible_hostvars/inventory/group_vars/dbservers
mkdir -p ~/project/ansible_hostvars/inventory/host_vars

이제 구성된 변수 파일을 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/inventory/group_vars/all/common.yml << 'EOF'
---
## Common variables for all hosts
ntp_servers:
  - ntp1.example.com
  - ntp2.example.com

timezone: UTC

monitoring_enabled: true
monitoring_server: monitor.example.com
EOF
cat > ~/project/ansible_hostvars/inventory/group_vars/webservers/web.yml << 'EOF'
---
## Web server specific variables
http_protocol: https
default_vhost: default.example.com
web_user: www-data
web_group: www-data

firewall_ports:
  - 80
  - 443
EOF
cat > ~/project/ansible_hostvars/inventory/host_vars/web01.yml << 'EOF'
---
## Host-specific variables for web01
server_role: primary
backup_server: web02
custom_vhosts:
  - name: site1.example.com
    docroot: /var/www/site1
  - name: site2.example.com
    docroot: /var/www/site2
EOF

이러한 구조화된 변수 액세스를 시연하는 플레이북을 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/playbooks/structured_vars.yml << 'EOF'
---
- name: Demonstrate structured variables
  hosts: localhost
  gather_facts: no
  tasks:
    - name: Display structured variables
      debug:
        msg: |
          Common variables:
          - NTP Servers: {{ hostvars['web01']['ntp_servers'] | default([]) }}
          - Timezone: {{ hostvars['web01']['timezone'] | default('Not set') }}
          
          Web server variables:
          - HTTP Protocol: {{ hostvars['web01']['http_protocol'] | default('Not set') }}
          - Default VHost: {{ hostvars['web01']['default_vhost'] | default('Not set') }}
          
          Host-specific variables for web01:
          - Server Role: {{ hostvars['web01']['server_role'] | default('Not set') }}
          - Backup Server: {{ hostvars['web01']['backup_server'] | default('Not set') }}
          - Custom VHosts: {{ hostvars['web01']['custom_vhosts'] | default([]) }}
EOF

이 플레이북을 실행합니다.

cd ~/project/ansible_hostvars
ANSIBLE_INVENTORY=~/project/ansible_hostvars/inventory ansible-playbook playbooks/structured_vars.yml

참고: 이 예제에서는 다른 인벤토리 경로를 지정하기 위해 ANSIBLE_INVENTORY 환경 변수를 사용하고 있습니다.

구성 생성기 만들기

여러 서비스에 대한 구성 파일을 생성하는 실용적인 애플리케이션을 만들어 보겠습니다.

mkdir -p ~/project/ansible_hostvars/templates/configs

다양한 서비스에 대한 템플릿 파일을 만듭니다.

cat > ~/project/ansible_hostvars/templates/configs/apache.conf.j2 << 'EOF'
## Apache configuration for {{ inventory_hostname }}
Listen {{ hostvars[inventory_hostname]['http_port'] | default(80) }}

ServerName {{ inventory_hostname }}
DocumentRoot {{ hostvars[inventory_hostname]['default_document_root'] | default('/var/www/html') }}

MaxClients {{ hostvars[inventory_hostname]['max_connections'] | default(100) }}

## Environment: {{ hostvars[inventory_hostname]['environment'] }}
EOF
cat > ~/project/ansible_hostvars/templates/configs/mysql.conf.j2 << 'EOF'
## MySQL configuration for {{ inventory_hostname }}
[mysqld]
port = {{ hostvars[inventory_hostname]['db_port'] | default(3306) }}
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock

max_connections = {{ hostvars[inventory_hostname]['max_connections'] | default(100) }}

## Backup directory: {{ hostvars[inventory_hostname]['backup_dir'] | default('/var/backups') }}
## Environment: {{ hostvars[inventory_hostname]['environment'] }}
EOF
cat > ~/project/ansible_hostvars/templates/configs/postgresql.conf.j2 << 'EOF'
## PostgreSQL configuration for {{ inventory_hostname }}
listen_addresses = '*'
port = {{ hostvars[inventory_hostname]['db_port'] | default(5432) }}

max_connections = {{ hostvars[inventory_hostname]['max_connections'] | default(100) }}

## Backup directory: {{ hostvars[inventory_hostname]['backup_dir'] | default('/var/backups') }}
## Environment: {{ hostvars[inventory_hostname]['environment'] }}
EOF

이제 이러한 템플릿을 적용하는 플레이북을 만듭니다.

cat > ~/project/ansible_hostvars/playbooks/config_generator.yml << 'EOF'
---
- name: Generate service configurations
  hosts: all
  gather_facts: no
  tasks:
    - name: Create output directory
      file:
        path: ~/project/ansible_hostvars/output/configs/{{ inventory_hostname }}
        state: directory
    
    - name: Generate Apache configuration for web servers
      template:
        src: ../templates/configs/apache.conf.j2
        dest: ~/project/ansible_hostvars/output/configs/{{ inventory_hostname }}/apache.conf
      when: inventory_hostname in groups['webservers']
    
    - name: Generate MySQL configuration for database servers with MySQL
      template:
        src: ../templates/configs/mysql.conf.j2
        dest: ~/project/ansible_hostvars/output/configs/{{ inventory_hostname }}/mysql.conf
      when: inventory_hostname in groups['dbservers'] and hostvars[inventory_hostname]['db_port'] | string == '3306'
    
    - name: Generate PostgreSQL configuration for database servers with PostgreSQL
      template:
        src: ../templates/configs/postgresql.conf.j2
        dest: ~/project/ansible_hostvars/output/configs/{{ inventory_hostname }}/postgresql.conf
      when: inventory_hostname in groups['dbservers'] and hostvars[inventory_hostname]['db_port'] | string == '5432'
EOF

구성 생성기 플레이북을 실행합니다.

cd ~/project/ansible_hostvars
ansible-playbook playbooks/config_generator.yml

생성된 구성 파일을 탐색합니다.

find ~/project/ansible_hostvars/output/configs -type f | sort

생성된 구성 중 일부를 확인합니다.

cat ~/project/ansible_hostvars/output/configs/web01/apache.conf
cat ~/project/ansible_hostvars/output/configs/db01/mysql.conf
cat ~/project/ansible_hostvars/output/configs/db02/postgresql.conf

호스트 문서 도구 만들기

마지막으로 인벤토리의 각 호스트에 대한 포괄적인 문서를 생성하는 도구를 만들어 보겠습니다.

cat > ~/project/ansible_hostvars/templates/host_doc.j2 << 'EOF'
## Host Documentation for {{ inventory_hostname }}
==============================================

### Basic Information
- Hostname: {{ inventory_hostname }}
- IP Address: {{ hostvars[inventory_hostname]['ansible_host'] }}
- Environment: {{ hostvars[inventory_hostname]['environment'] | default('Not specified') }}

### Role Information
{% if inventory_hostname in groups['webservers'] %}
- Role: Web Server
- HTTP Port: {{ hostvars[inventory_hostname]['http_port'] | default('Not specified') }}
- Max Connections: {{ hostvars[inventory_hostname]['max_connections'] | default('Not specified') }}
{% if 'web_server_type' in hostvars[inventory_hostname] %}
- Web Server Type: {{ hostvars[inventory_hostname]['web_server_type'] }}
{% endif %}
{% endif %}

{% if inventory_hostname in groups['dbservers'] %}
- Role: Database Server
- DB Port: {{ hostvars[inventory_hostname]['db_port'] | default('Not specified') }}
- Backup Directory: {{ hostvars[inventory_hostname]['backup_dir'] | default('Not specified') }}
{% if 'backup_frequency' in hostvars[inventory_hostname] %}
- Backup Frequency: {{ hostvars[inventory_hostname]['backup_frequency'] }}
- Backup Retention: {{ hostvars[inventory_hostname]['backup_retention'] }} days
{% endif %}
{% endif %}

### Related Hosts
{% if inventory_hostname in groups['webservers'] %}
#### Database Servers:
{% for db_host in groups['dbservers'] %}
- {{ db_host }} ({{ hostvars[db_host]['ansible_host'] }})
{% endfor %}
{% endif %}

{% if inventory_hostname in groups['dbservers'] %}
#### Web Servers:
{% for web_host in groups['webservers'] %}
- {{ web_host }} ({{ hostvars[web_host]['ansible_host'] }})
{% endfor %}
{% endif %}
EOF

문서 생성을 위한 플레이북을 만듭니다.

cat > ~/project/ansible_hostvars/playbooks/host_documentation.yml << 'EOF'
---
- name: Generate host documentation
  hosts: all
  gather_facts: no
  tasks:
    - name: Create output directory
      file:
        path: ~/project/ansible_hostvars/output/docs
        state: directory
    
    - name: Generate host documentation
      template:
        src: ../templates/host_doc.j2
        dest: ~/project/ansible_hostvars/output/docs/{{ inventory_hostname }}.md
EOF

문서 플레이북을 실행합니다.

cd ~/project/ansible_hostvars
ansible-playbook playbooks/host_documentation.yml

생성된 문서를 확인합니다.

ls -l ~/project/ansible_hostvars/output/docs/
cat ~/project/ansible_hostvars/output/docs/web01.md
cat ~/project/ansible_hostvars/output/docs/db01.md

축하합니다! 이제 기본 사용법부터 고급 적용 사례까지 Ansible hostvars 에 대한 포괄적인 탐색을 완료했습니다. 호스트 변수에 액세스하고, 템플릿에서 사용하고, 인프라 관리를 위한 실용적인 도구를 만드는 방법을 배웠습니다.

요약

이 실습에서는 Ansible hostvars 의 강력함과 다재다능함을 탐구했습니다. 다음 내용을 학습했습니다.

  1. 환경 설정: 호스트, 그룹 및 변수를 포함하는 인벤토리 구조로 Ansible 환경을 구성했습니다.

  2. Hostvars 탐색: 플레이북에서 hostvars 에 액세스하는 방법을 배웠으며, 현재 호스트의 변수와 인벤토리의 다른 호스트 변수에 액세스하는 방법을 포함합니다.

  3. 템플릿에서 Hostvars 사용: 각 호스트에 맞게 동적 구성 파일을 생성하기 위해 hostvars 를 활용하는 Jinja2 템플릿을 만들었습니다.

  4. 고급 Hostvars 기법: 그룹 변수, 동적 인벤토리 보고서 및 누락된 변수를 안전하게 처리하는 기법을 탐구했습니다.

  5. 모범 사례 및 실제 적용 사례: 구조화된 변수 구성을 구현하고 구성 생성기 및 호스트 문서 도구를 포함한 실용적인 애플리케이션을 만들었습니다.

Ansible hostvars 는 동적이고 적응 가능한 자동화 워크플로를 생성할 수 있는 강력한 기능입니다. hostvars 를 효과적으로 작업하는 방법을 이해함으로써 인프라에 대한 보다 유연하고 유지 관리 가능한 자동화 솔루션을 만들 수 있습니다.

Ansible 여정을 계속하면서 hostvars 는 Ansible 의 풍부한 기능 생태계의 일부일 뿐이라는 점을 기억하십시오. 역할, 컬렉션 및 동적 인벤토리와 같은 다른 기능을 탐색하여 자동화 기능을 더욱 향상시키는 것을 고려해 보세요.