티스토리 뷰

DevOps/Ansible

[A101] Ansible 시작하기

전빵수 2024. 1. 12. 20:51
CloudNet@의 가시다님 Ansible 1기 스터디에 참여하게 되어 배운 내용과 책의 내용을 함께 정리합니다.

📚 앤서블로 시작하는 인프라 자동화

 

앤서블로 시작하는 인프라 자동화 | 장현정 - 교보문고

앤서블로 시작하는 인프라 자동화 | 효율적인 IT 자동화를 위한 도구, 앤서블 설계부터 응용까지 단계별로 배우는 인프라 관리클라우드 컴퓨팅을 논할 때 IaC(Infrastructure as Code)를 빼놓을 수 없는

product.kyobobook.co.kr

 

 

1. Ansible이란?

앤서블은 마이클 데한에 의해 Ansiblework라는 이름으로 2014년 3월 4일에 처음 소개되었으며 퍼펫 랩스(Puppet Labs)에서 근무하며 조금 더 쉬운 자동화를 위해 앤서블을 시작했다고 합니다. 그 후, 2015년 10월 레드햇이 인수하여 개발 및 관리를 하고 있습니다. 앤서블은 리눅스, MacOS, BSC 계열 유닉스, WSL을 지원하는 원도우에 파이썬앤서블 코어만 설치하면 어디에서나 플레이북(YAML 형식의 작업들을 순서대로 작성해 놓은 파일)을 작성하고 이를 실행시킬 수 있습니다. 앤서블은 제어 노드에만 설치되고 관리 노드에는 설치되지 않습니다.

1.1. Ansible의 특징

  • No! 에이전트(Agentless)
    • 에이전트 설치 없이 SSH로 접속하여 쉽게 대상 서버들을 관리합니다.
  • 멱등성 (Idempotent)
    • 멱등성이란 동일한 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질로, 앤서블은 멱등성을 지원하여 동일한 운영작업을 여러 번 실행해도 항상 같은 결과를 유지합니다.
  • 쉬운 사용법과 다양한 모듈 제공
    • 자동화 단계에서 YAML 문법을 사용하여 쉽게 작성하고 읽을 수 있습니다.

 

1.2. 커뮤니티 앤서블

앤서블에는 커뮤니티 앤서블과 레드햇 앤서블 오토메이션 플랫폼이 존재하는데, 커뮤니티 앤서블은 오픈소스 형태로 운영체제가 리눅스라면 어디에나 설치하여 사용할 수 있으며, 레드햇 앤서블 오토메이션 플랫폼은 레드햇 서브스크립션을 통해서만 사용할 수 있는 유료제품입니다. 그래서 보통 `앤서블`이라고 하면 `커뮤니티 앤서블`을 떠올리시면 됩니다.

커뮤니티 앤서블의 구조

  • 제어 노드
    • 앤서블이 설치되는 노드로 운영체제가 리눅스이고 파이썬 모듈이 설치된 환경이라면 제어 노드가 될 수 있습니다.
  • 관리 노드
    • 앤서블이 제어하는 원격 시스템 또는 호스트를 의미합니다. 관리 노드는 다양한 OS 혹은 VM일 수 있으며 SSH 통신이 가능해야 하고, 파이썬이 설치되어 있어야 합니다.
  • 인벤토리
    • 제어 노드가 제어하는 관리 노드의 목록을 나열해놓은 파일입니다. 인벤토리에 정의되어 있는 관리 노드에만 접근할 수 있으며 성격별로 그룹핑할 수 있습니다.
  • 플레이북
    • 관리 노드에서 수행할 작업들을 YAML 문법을 통해 사용자가 직접 작성한 순서대로 작성한 파일입니다.

 

2. 실습 환경

책에서는 VM을 활용하여 실습 환경을 구성하였지만, 편의를 위해 가시다님이 제공해주신 CloudFormation으로 생성된 AWS EC2 환경에서 실습을 진행하였습니다.

2.1. 환경 정보

Node Name OS
server Ubuntu22.04
tnode1 Ubuntu22.04
tnode2 Ubuntu22.04
tnode3 Ubuntu22.04

 

2.2. 앤서블 설치

server Node에만 앤서블을 설치합니다.

# 작업 기본 디렉터리 확인
whoami
pwd
/root/my-ansible

# 파이썬 버전 확인
python3 --version
Python 3.10.12

# 설치
apt install software-properties-common -y
add-apt-repository --yes --update ppa:ansible/ansible
apt install ansible -y

# 확인 : 책 버전(파이썬 3.11.2, jinja 진자 3.1.2)
ansible --version
ansible [core 2.15.8]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.0.3
  libyaml = True

cat /etc/ansible/ansible.cfg
which ansible

# 책 저자 코드 확인
tree /root/my-ansible/Easy-Ansible/ -L 1
tree /root/my-ansible/Easy-Ansible/

앤서블은 로컬 사용자에게 개인 SSH 키가 있거나 관리 호스트에서 원격 사용자임을 인증 가능한 키가 구성된 경우 자동으로 로그인합니다.

  • ssh-keygen 명령어를 이용하여 SSH 키 생성
# 모니터링
tree ~/.ssh
watch -d 'tree ~/.ssh'

# Create SSH Keypair
ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa

 

  • 공개 키를 관리 노드에 복사
# 공개 키를 관리 노드에 복사
for i in {1..3}; do ssh-copy-id root@tnode$i; done

# 복사 확인
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i cat ~/.ssh/authorized_keys; echo; done

# ssh 접속 테스트
ssh tnode1
whoami
exit

ssh tnode2
exit

ssh tnode3
exit

 

3. 호스트 선정

3.1. 인벤토리를 이용한 자동화 대상 호스트 설정

인벤토리 파일은 텍스트 파일이며, 앤서블이 자동화 대상으로 하는 관리 호스트지정합니다. 이 파일은 INI 스타일 형식(이름 = 값) 또는 YAML을 포함한 다양한 형식을 사용하여 작성이 가능합니다.

 

my-ansible/inventory

  • IP를 이용한 인벤토리 파일 생성
# inventory 파일 생성
cat <<EOT > inventory
10.10.1.11
10.10.1.12
10.10.1.13
EOT

# inventory 검증 : -i 특정 인벤토리 지정
ansible-inventory -i ./inventory --list | jq
  • 호스트명을 이용한 인벤토리 파일 생성
# /etc/hosts 파일 확인
cat /etc/hosts

# inventory 파일 생성
cat <<EOT > inventory
tnode1
tnode2
tnode3
EOT

# inventory 검증
ansible-inventory -i ./inventory --list | jq

 

3.2. 호스트 그룹 설정

그룹별로 호스트를 설정하여 사용하면 앤서블 플레이북 실행 시 그룹별로 작업을 처리할 수 있어서 좀 더 효과적입니다. 이 경우 다음과 같이 그룹명을 대괄호 ([]) 내에 작성하고 해당 그룹에 속하는 호스트명이나 IP를 한 줄에 하나씩 나열합니다. 아래 인벤토리는 두 개의 호스트 그룹인 webservers와 db-servers를 정의한 것입니다.

# inventory 그룹 구성
cat <<EOT > inventory
[web]
tnode1
tnode2

[db]
tnode3

[all:children]
web
db
EOT

# inventory 검증
ansible-inventory -i ./inventory --list | jq
ansible-inventory -i ./inventory --graph

또는 호스트는 여러 그룹에 있을 수 있습니다. 실제 호스트를 여러 그룹으로 구성하면 호스트의 역할, 실제 위치, 프로덕션 여부 등에 따라 다양한 방식으로 구성할 수 있습니다. 그러면 특성, 용도 또는 위치에 따라 특정 호스트 집합에 앤서블 플레이를 쉽게 적용할 수 있습니다.

 

4. 플레이북 작성

현재 프로젝트 디렉터리 내에 ansible.cfg 라는 앤서블 환경 설정 파일을 구성 시, -i 옵션을 사용하지 않아도 ansible.cfg 설정 파일에 정의된 인벤토리의 호스트 정보를 확인할 수 있습니다.

# ansible.cfg 파일 생성
cat <<EOT > ansible.cfg
[defaults]
inventory = ./inventory
EOT

# inventory 목록 확인
ansible-inventory --list | jq

 

4.1. 앤서블 config 적용 우선 순위

 

Ansible Configuration Settings — Ansible Documentation

['bud-frogs', 'bunny', 'cheese', 'daemon', 'default', 'dragon', 'elephant-in-snake', 'elephant', 'eyes', 'hellokitty', 'kitty', 'luke-koala', 'meow', 'milk', 'moofasa', 'moose', 'ren', 'sheep', 'small', 'stegosaurus', 'stimpy', 'supermilker', 'three-eyes',

docs.ansible.com

  1. ANSIBLE_CONFIG (environment variable if set)
  2. ansible.cfg (in the current directory)
  3. ~/.ansible.cfg (in the home directory)
  4. /etc/ansible/ansible.cfg

 

4.2. 앤서블 환경 설정 파일

여러 개의 섹션에 키=값 포맷으로 정의하며 섹션 제목은 대괄호로 묶습니다. 기본적인 실행을 위한 아래의 예제를 살펴봅시다.

[defaults]
inventory = ./inventory
remote_user = root
ask_pass = false

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
  • [defaults] 앤서블 작업을 위한 기본값을 설정합니다.
매개 변수 설명
inventory 인벤토리 파일의 경로를 지정
remote_user 관리 호스트에 연결할 때 사용하는 이름 지정
(지정하지 않으면 현재 사용자 이름으로 설정됩니다.)
ask_pass SSH 암호 묻는 메시지 표시 여부 지정
(SSH 공개 키 인증을 사용하는 경우 기본값은 false입니다.)
  • [privilege_escalation] 원격 호스트에 권한이 없는 사용자로 먼저 연결한 후 관리 엑세스 권한을 에스컬레이션(escalation)하여 루트 사용자로 가져와야 할 때도 있어 해당 권한을 설정합니다.
매개 변수 설명
become 에스컬레이션을 활성화할 때 사용하며, 연결 후 관리 호스트에서 자동으로 사용자를 전환할지 여부를 지정
(일반적으로 root로 전환되며, 플레이북에서도 지정할 수 있습니다.)
become_method 권한을 에스컬레이션하는 사용자 전환 방식을 의미
(일반적으로 기본값은 sudo를 사용하며, su는 옵션으로 설정할 수 있습니다.)
become_user 관리 호스트에서 전환할 사용자를 지정
(일반적으로 기본값은 root입니다.)
become_ask_pass become_method 매개 변수에 대한 암호를 묻는 메시지 표시 여부를 지정
(기본값은 false이며, 사용자가 암호를 입력해야 하는 경우, true로 설정하면 됩니다.)

 

4.3 플레이북 작성

플레이북은 YAML 포맷으로 작성된 텍스트 파일이며, 일반적으로 .yml이라는 확장자를 사용합니다. 플레이북은 대상 호스트나 호스트 집합에 수행할 작업을 정의하고 이를 실행하며 특정 작업 단위를 수행하기 위해 모듈을 적용합니다.

 

my-ansible/restart-service.yml

---
- hosts: all
  tasks:
    - name: Restart sshd service
      ansible.builtin.service:
        name: sshd
        state: restarted

 

 

ansible.builtin.service module – Manage services — Ansible Documentation

Forces a ‘global’ task that does not execute per host, this bypasses per host templating and serial, throttle and other loop considerations Conditionals will work as if run_once is being used, variables used will be from the first available host This a

docs.ansible.com

# 문법 체크 (재시작하며 서비스가 변경될 예정이므로 changed=1 이라는 문구 확인 가능)
ansible-playbook --check restart-service.yml

# 플레이북 실제 실행
ansible-playbook restart-service.yml

5. 변수

5.1. 변수의 종류와 사용법

앤서블은 변수를 사용하여 사용자, 설치하고자 하는 패키지, 재시작할 서비스, 생성 또는 삭제할 파일명 등 시스템 작업 시 사용되는 다양한 값을 저장할 수 있습니다. 앤서블에서 사용되는 변수는 그룹 변수, 호스트 변수, 플레이 변수, 추가 변수가 있으며 플레이 결과를 저장하기 위한 작업 변수도 있습니다.

 

5.1.1. 그룹 변수

1. 인벤토리에 정의된 호스트 그룹에 적용하는 변수를 의미합니다. 선언하고자 하는 그룹명과 함께 :vars라는 문자열을 추가해 변수를 선언한다는 것을 알려줍니다. 이렇게 하면 all이라는 그룹에서 user라는 변수를 사용할 수 있습니다.

my-ansible/inventory

[web]
tnode1
tnode2

[db]
tnode3

[all:children]
web
db

[all:vars]
user=ansible

 

 

2. 사용자를 생성하는 태스크를 포함합니다. 앤서블에서 시스템 사용자를 생성하기 위해서는 ansible.builtin.user라는 모듈을 사용하며 인벤토리에서 선언한 user라는 변수를 겹중괄호 사이에 넣어주면, 해당 변수를 플레이북에서 사용할 수 있습니다. 이때, 겹 중괄호와 변수명 사이는 항상 한 칸씩 띄워주어야 합니다.

my-ansible/create-user.yml

---

- hosts: all
  tasks:
  - name: Create User {{ user }}
    ansible.builtin.user:
      name: "{{ user }}"
      state: present

 

3. 생성한 플레이북을 실행하면 태스트명으로 Create User {{ user }} 라고 변수를 사용한 부분에 해당 변수의 값인 ansible이라는 문자열이 보이는 것을 확인할 수 있습니다.

# 모니터링
watch -d "ssh tnode1 tail -n 3 /etc/passwd"

# 실행
ansible-playbook create-user.yml
...
TASK [Create User ansible] *********
...

# 한번 더 실행 : 멱등성 확인
ansible-playbook create-user.yml

 

4. 실제 대상 호스트에서 ansible 사용자 생성을 확인합니다.

# tnode1~3에서 ansible 사용자 생성 확인
#ssh tnode1 tail -n 3 /etc/passwd
#ssh tnode1 ls -l /home
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i tail -n 3 /etc/passwd; echo; done
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i ls -l /home; echo; done

 

5. 수동으로 tnode1 에 ansible 사용자 삭제 후 다시 플레이북 실행을 확인합니다.

# tnode1 에 ansible 사용자 삭제 후 확인
ssh tnode1 userdel -r ansible
ssh tnode1 tail -n 2 /etc/passwd

# 실행
ansible-playbook create-user.yml

 

5.1.2. 호스트 변수

변수를 해당 호스트에서만 사용할 수 있습니다.

 

1. 인벤토리 파일을 열고 db 그룹의 tnode-3 호스트 옆에 변수를 선언합니다.
my-ansible/inventory

 

[web]
tnode1
tnode2

[db]
tnode3 user=ansible1

[all:children]
web
db

[all:vars]
user=ansible

 

2. 플레이북 파일을 작성합니다.

my-ansible/create-user1.yml

---

- hosts: db
  tasks:
  - name: Create User {{ user }}
    ansible.builtin.user:
      name: "{{ user }}"
      state: present

 

3. 플레이북 실행을 확인합니다. (호스트 변수는 그룹 변수보다 우선순위가 높습니다.)

# (터미널2) 모니터링
watch -d "ssh tnode3 tail -n 3 /etc/passwd"

# 실행
ansible-playbook create-user1.yml
...
TASK [Create User ansible1] *********
...

# 확인
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i tail -n 3 /etc/passwd; echo; done

 

5.1.3. 플레이 변수

플레이북 내에서 선언되는 변수를 의미하며, 별도 파일로 분리해야 합니다.

 

1. hosts 아래에 vars: 를 추가하고 그 아래에 다시 user: ansible2 라는 변수와 값을 추가합니다.

my-ansible/create-user2.yml

---

- hosts: all
  vars:
    user: ansible2

  tasks:
  - name: Create User {{ user }}
    ansible.builtin.user:
      name: "{{ user }}"
      state: present

 

2. 플레이북 실행을 확인합니다. (그룹 변수보다 우선순위가 높았던 호스트 변수보다 플레이 변수의 우선순위가 높습니다.)

# (터미널2) 모니터링
watch -d "ssh tnode3 tail -n 3 /etc/passwd"

#  인벤토리에 선언한 그룹 변수와 호스트 변수 확인
cat inventory

# 실행
ansible-playbook create-user2.yml
...
TASK [Create User ansible2] *********
...

# 확인
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i tail -n 3 /etc/passwd; echo; done

 

3. 플레이 변수를 별도의 파일로 분리하여 정의한 후 이를 플레이북에서 선언하는 방법으로 변수를 사용해봅니다.

my-ansible/vars/users.yml

mkdir vars
echo "user: ansible3" > vars/users.yml

 

4. hosts 아래에 vars_files: 를 추가하고 그 아래에 파일의 위치를 추가합니다.

my-ansible/create-user3.yml

---

- hosts: all
  vars_files:
    - vars/users.yml

  tasks:
  - name: Create User {{ user }}
    ansible.builtin.user:
      name: "{{ user }}"
      state: present

 

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

# (터미널2) 모니터링
watch -d "ssh tnode3 tail -n 3 /etc/passwd"

# 플레이 변수 파일 확인
cat vars/users.yml

# 실행
ansible-playbook create-user3.yml
...
TASK [Create User ansible3] *********
...

# 확인
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i tail -n 4 /etc/passwd; echo; done



5.1.4. 추가 변수

외부에서 ansible-playbook를 실행할 때 함께 파라미터로 넘겨주는 변수를 의미하며 변수 중 우선순위가 가장 높습니다.

 

1. 실행 시 -e(extra_vars 약자) 옵션으로 추가 변수를 선언합니다.

# (터미널2) 모니터링
watch -d "ssh tnode3 tail -n 3 /etc/passwd"

# 실행
ansible-playbook -e user=ansible4 create-user3.yml
...
TASK [Create User ansible4] *********
...

# 확인
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i tail -n 5 /etc/passwd; echo; done

5.1.5. 작업 변수

플레이북의 태스트 수행 결과를 저장한 것을 의미합니다. 특정 작업 수행 후 그 결과를 후속 작업에서 사용할 때 주로 사용됩니다. 예를 들어 클라우드 시스템에 VM을 생성한다고 가정해보면, 이를 위해서는 네트워크나 운영체제 이미지와 같은 가상 자원이 필요합니다. 가상 자원을 조회하고, 조회된 결과를 가지고 VM을 생성할 때는 작업 변수를 사용하면 좋습니다.

 

1. Create User 태스트에 register: result 라는 문구를 추가합니다.

  • register를 선언하면 태스트를 실행한 결과를 register 다음에 나오는 result라는 변수에 저장하겠다는 의미가 됩니다.
  • result라는 변수에 저장한 결과를 debug 모듈을 통해 출력합니다.

my-ansible/create-user4.yml

---

- hosts: db
  tasks:
  - name: Create User {{ user }}
    ansible.builtin.user:
      name: "{{ user }}"
      state: present
    register: result
  
  - ansible.builtin.debug:
      var: result

 

2. 추가 변수와 함께 플레이북 실행을 확인합니다. (ok=3는 태스크의 개수를 의미합니다.)

# (터미널2) 모니터링
watch -d "ssh tnode3 tail -n 3 /etc/passwd"

# 실행
ansible-playbook -e user=ansible5 create-user4.yml
PLAY [db] ***************************************************************************

TASK [Gathering Facts] **************************************************************
ok: [tnode3-ubuntu.local]

TASK [Create User ansible5] *********
changed: [tnode3-ubuntu.local]

TASK [ansible.builtin.debug] ********************************************************
ok: [tnode3-ubuntu.local] => {
    "result": {
        "changed": true,
        "comment": "",
        "create_home": true,
        "failed": false,
        "group": 1006,
        "home": "/home/ansible5",
        "name": "ansible5",
        "shell": "/bin/sh",
        "state": "present",
        "system": false,
        "uid": 1006
    }
}

PLAY RECAP **************************************************************************
tnode3-ubuntu.local        : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

6. Ansible Vault

앤서블 파일에 접근 권한이 있는 사용자는 파일 내용을 볼 수 있어 패스워드나 API 키 등 중요한 데이터들이 외부로 유출될 수 있습니다. 따라서 앤서블은 사용되는 모든 데이터 파일을 암호화하고 암호화된 내용을 해독할 수 있는 기능을 제공합니다.

6.1. 암호화된 파일

ansible-vault 명령어를 통해 파일 생성/암호화하여 사용 및 해독과 확인이 가능합니다.

 

1. [ansible-server] ansible-vault create 로 생성하려는 플레이북 파일명을 입력한 후 해당 파일에서 사용할 패스워드를 입력합니다.

my-ansible/mysecret.yml

ansible-vault -h
ansible-vault create mysecret.yml
New Vault password: P@ssw0rd!
Confirm New Vault password: P@ssw0rd!

 

2. vi 에디터와 같이 파일을 편집할 수 있는 창으로 전환되면 아래와 같이 입력 후 저장하고 빠져나옵니다.

user: ansible
password: P@ssword!

:wq

 

3. 생성된 파일의 접근 권한과 내용을 확인합니다.

# 파일을 생성한 소유자만 읽고 쓸수 있음을 확인
ll -rtl mysecret.yml
-rw------- 1 root root 484 Dec 27 14:46 mysecret.yml

# ubuntu 유저로 파일 확인 시도
su - ubuntu -c 'cat /root/my-ansible/mysecret.yml'

# 파일 내용 확인 : 암호화되어 있음
cat mysecret.yml
$ANSIBLE_VAULT;1.1;AES256
38656334303839613837666364363938643032366561393032626330346430656537636634316632
6165353664396261373132636139383431643833636463650a653035663661623064363563356464
39663634653931396663396535313038643564356532306261376136313662306663383361346539
6635343333633265340a356630653934343938663432663232303837313137343063373739366534
32366631633234653938613130346539383936633338363865363539393935373736336330633235
3338663837623364316663393238663938613038666566306362

 

4. 원래 파일 내용을 확인합니다. (복호화)

ansible-vault view mysecret.yml
Vault password: P@ssword!

user: ansible
password: P@ssword!

7. Facts

앤서블이 관리 호스트에서 자동으로 검색한 변수(자동 예약 변수)입니다. 팩트에는 플레이, 조건문, 반복문 또는 관리 호스트에서 수집한 값에 의존하는 기타 명령문의 일반 변수처럼 사용 가능한 호스트별 정보가 포함되어 있습니다. 관리 호스트에서 수집된 일부 팩트에는 다음 내용들이 포함될 수 있습니다.

  • 호스트 이름
  • 커널 버전
  • 네트워크 인터페이스 이름
  • 운영체제 버전
  • CPU 개수
  • 사용 가능한 메모리
  • 스토리지 장치의 크기 및 여유 공간

7.1.  사용법

기본으로 활성화되어 있으며 플레이북을 실행할 때 자동으로 팩트가 수집됩니다.

 

1. 파일을 생성합니다.(ansible_facts 변수로 사용합니다.)

my-ansible/facts.yml

---

- hosts: db

  tasks:
  - name: Print all facts
    ansible.builtin.debug:
      var: ansible_facts

 

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

#
ansible-playbook facts.yml
...
TASK [Gathering Facts] ***********************************************************************************************************************************************************************
ok: [tnode3]

TASK [Print all facts] ***********************************************************************************************************************************************************************
ok: [tnode3] => {
...
  "hostname": "tnode3",
...
  "default_ipv4": {
      "address": "10.10.1.13",
...

 

3. 팩트를 통해 수집된 변수 중 특정 값만 추출합니다.

my-ansible/facts1.yml

---

- hosts: db

  tasks:
  - name: Print all facts
    ansible.builtin.debug:
      msg: >
        The default IPv4 address of {{ ansible_facts.hostname }}
        is {{ ansible_facts.default_ipv4.address }}

 

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

#
ansible-playbook facts1.yml
...
TASK [Gathering Facts] **************************************************************************
ok: [tnode3]

TASK [Print all facts] **************************************************************************
ok: [tnode3] => {
    "msg": "The default IPv4 address of tnode3 is 10.10.1.13"
}

7.2. 변수로 사용할 수 있는 팩트

앤서블 2.* 버전에서는 ansible_facts.* 네임스페이스 표기법을 따릅니다. (구 ansible_* 비권장)

팩트 ansible_facts.*표기법
호스트명 ansible_facts.hostname
도메인 기반 호스트명 ansible_facts.fqdn
기본 IPv4 주소 ansible_facts.default_ipv4.address
네트워크 인터페이스 이름 목록 ansible_facts.interfaces
/dev/vda1 디스크 파티션 크기 ansible_facts.device.vda.partitions.vda1.size
DNS 서버 목록 ansible_facts.dns.nameservers
현재 실행 중인 커널 버전 ansible_facts.kernel
운영체제 종류 ansible_facts.distribution
  • (참고) 구 표기법
ansible_* 표기법 ansible_facts.* 표기법
ansible_hostname ansible_facts.hostname
ansible_fqdn ansible_facts.fqdn
ansible_default_ipv4.address ansible_facts.default_ipv4.address
ansible_interfaces ansible_facts.interfaces
ansible_device.vda.partitions.vda1.size ansible_facts.device.vda.partitions.vda1.size
ansible_dns.nameservers ansible_facts.dns.nameservers
ansible_kernel ansible_facts.kernel
ansible_distribution ansible_facts.distribution

 

앤서블 환경 설정 파일인 ansible.cfg [defaults] 섹션에 있는 inject_facts_as_vars 매개 변수 기본 설정 값이 true이기 때문에 현재는 두 개의 표기법 모두 앤서블이 인지합니다. 이를 false로 설정하면 ansible_* 표기법을 비활성화 할 수 있습니다. 다만, 대부분의 플레이북에서 이전 표기법인 ansible_* 표기법을 사용하므로 기본 설정 값인 true를 그대로 사용하는 것이 좋습니다.

 

7.3. 팩트 수집 끄기

팩트 수집을 위해 해당 호스트에 특정 패키지를 설치해야만 하는 경우가 있습니다. 그런데 간혹 특정 이유로 패키지를 설치할 수 없는 경우에는 앤서블도 팩트 수집을 할 수 없게 됩니다. 또는 사용자가 팩트 수집으로 인해 호스트에 부하가 걸리는 것을 원치 않을 수도 있습니다. 이런 경우에는 팩트 수집 기능을 비활성화 할 수 있습니다.

 

1. 팩트 수집 실행 시 관리 호스트에 프로세스를 확인합니다.

# (터미널2) tnode3에 SSH 접속 후 아래 모니터링
ssh tnode3
watch -d -n 1 pstree

# [ansible-server]에서 아래 플레이북 실행
ansible-playbook facts.yml
ansible-playbook facts.yml
ansible-playbook facts.yml

 

2. 플레이북을 작성합니다.

my-ansible/facts3.yml

---

- hosts: db
  gather_facts: no

  tasks:
  - name: Print all facts
    ansible.builtin.debug:
      msg: >
        The default IPv4 address of {{ ansible_facts.hostname }}
        is {{ ansible_facts.default_ipv4.address }}

 

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

# 실행 결과 확인 : 팩트를 수집하지 않았는데, 팩트에서 수집해야만 하는 변수를 사용하려고 해서 에러가 발생
ansible-playbook facts3.yml


# 파일 복사
cp facts3.yml facts3-2.yml

# facts3-2.yml 파일 편집
---

- hosts: db
  gather_facts: no

  tasks:
  - name: Print message
    debug:
      msg: Hello Ansible World

# 실행 : TASK [Print all facts] 가 없다!
ansible-playbook facts3-2.yml
PLAY [db] ***************************************************************************

TASK [Print message] ****************************************************************
ok: [tnode3] => {
    "msg": "Hello Ansible World"
}
...

 

4. 매뉴얼한 방법으로 플레이북에 팩트 수집을 설정해봅니다.

my-ansible/facts4.yml

# 파일 복사
cp facts3.yml facts4.yml

# facts4.yml 파일 편집
---

- hosts: db
  gather_facts: no

  tasks:
  - name: Manually gather facts
    ansible.builtin.setup:

  - name: Print all facts
    ansible.builtin.debug:
      msg: >
        The default IPv4 address of {{ ansible_facts.hostname }}
        is {{ ansible_facts.default_ipv4.address }}

 

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

#
ansible-playbook facts4.yml
...
TASK [Manually gather facts] ********************************************************
ok: [tnode3]

TASK [Print all facts] **************************************************************
ok: [tnode3] => {
    "msg": "The default IPv4 address of tnode3 is 10.10.1.13"
}

 

7.4. 사용자 지정 팩트

사용자에 의해 정의된 팩트를 이용하여 환경 설정 파일의 일부 항목을 구성하거나 조건부 작업을 진행할 수 있습니다. 관리 호스트의 로컬에 있는 /etc/ansible/facts.d 디렉터리 내에 ‘*.fact’로 저장되어야만 앤서블이 플레이북을 실행할 때 자동으로 팩트를 수집할 수 있습니다.

 

1. ansible-server 에 디렉터리 생성 후 파일을 생성합니다.

mkdir /etc/ansible/facts.d

# my-custom.fact 파일 생성
cat <<EOT > /etc/ansible/facts.d/my-custom.fact
[packages]
web_package = httpd
db_package = mariadb-server

[users]
user1 = ansible
user2 = sjjeon
EOT

cat /etc/ansible/facts.d/my-custom.fact

 

2. 플레이북 파일을 생성합니다. (ansible_local 변수로 사용합니다.)

# 파일 복사
cp facts4.yml facts5.yml

# facts5.yml 파일 편집
---

- hosts: localhost

  tasks:
  - name: Print all facts
    ansible.builtin.debug:
      var: ansible_local

 

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

# 실행 : 커스텀으로 생성했던 팩트 내용이 출력
ansible-playbook facts5.yml
PLAY [localhost] ******************************************************************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************************************************
ok: [localhost]

TASK [Print all facts] ************************************************************************************************************************************************************
ok: [localhost] => {
    "ansible_local": {
        "my-custom": {
            "packages": {
                "db_package": "mariadb-server",
                "web_package": "httpd"
            },
            "users": {
                "user1": "ansible",
                "user2": "gasida"
            }
        }
    }
}
...

# 
tail -n 5 /etc/passwd

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함