[쿠버네티스 2/2] Ansible - fact 변수 & 반복문

신현식·2023년 2월 2일
0

구름_Ansible

목록 보기
4/5
post-thumbnail

변수 선언 및 사용 실습

💡 전체 코드를 작성하지 않은 것들은 tasks 밑에 들어갈 내용만 적어둔 것이다.

사용자를 만드는 플레이북을 만드세요. (vars_prompt 를 통해서 아래 정보를 입력 받도록 하시오.)[ 이름 : UID : SHELL : ]


vi vars_prompt.yml

---
- name: Create user
  hosts: ansi-node1
  vars_prompt:
  - name: username
    prompt: username
    private: no
  - name: user_id
    prompt: uid
    private: no

  - name: user_shell
    prompt: shell
    private: no

  gather_facts: no

  tasks:
  - user:
      name: "{{ username }}"
      uid: "{{ user_id }}"
      shell: "{{ user_shell }}"
... 
 
ansible-playbook vars_prompt 
ssh ansi-node1 tail -5 /etc/passwd   

파일을 복사하는 플레이북을 만드세요. (단, 복사하는 파일을 변수로 지정하도록 설정하세요.)


- name: Copy play
  hosts: ansi-node1
  vars:
    copyfile: /tmp/testfile
  gather_facts: no
  tasks:
  - copy:
      src: "{{ copyfile }}"
      dest: /tmp/fileb
      

패키지를 설치하는 플레이북을 만드세요. (apt 모듈 사용. 패키지 이름을 vars_prompt로 지정. ansi-node1 만 지정)

- name: Inatll Package
  hosts: ansi-node1
  vars_prompt:
  - name: package
    prompt: choice package
    private: no
  gather_facts: no
  tasks:
  - apt:
      name: "{{ package }}"
      state: latest
      update_cache: yes

lookup의 file 플러그인을 이용해서 ansi-master1 의 /etc/hostname 파일의 내용을 출력하세요.

-name: lookuptest
  hosts: ansi-node1
  vars:
    hostname1: "{{ lookup('file','/etc/hostname') }}"
  gather_facts: no
  tasks:
  - debug:
      msg: "{{ hostname1 }}"

dic1={user01:123,user02:456}을 dic2items 필터를 이용해서 [{id:user01,pw:123},{id:user02,pw:456}] 형태로 변환시키세요.

- name: lookuptest
  hosts: ansi-node1
  vars:
    dic1:
      user01: 123
      user02: 456
  gather_facts: no
  tasks:
  - debug:
      msg: "{{ dic1 | dict2items(key_name='id',value_name='pw') }}"

hash 필터를 이용해서 user01의 패스워드인 123 을 해시 알고리즘 (sha256) 솔트 ('1234') 으로 해서 hash 암호화 시키세요.

- name: hashtest
  hosts: ansi-node1
  gather_facts: no
  tasks:
  - debug:
      msg: "{{ '123' | password_hash('sha256','1234') }}"

ipaddr 필터를 이용해서 100.100.100.100 이 ip 주소 형식인지 알아보세요.

# ansi-node1에서 진행
# sudo apt install python-pip
# sudo pip install netaddr

# 마스터에서 진행

- name: ipaddrtest
  hosts: ansi-node1
  gather_facts: no
  tasks:
  - debug:
      msg: "{{ '100.100.100.100' | ipaddr }}"

팩트 변수(fact 변수)

운영 체제 관련 정보, IP 주소, NIC 정보, 디스크 장치, 배포판, 환경 변수, CPU 정보, 메모리 정보, 마운트 정보 등 관리 노드의 정보를 가진 변수이다.

  • ansible_로 시작하는 변수로 접근할 수 있음
  • 별도로 설정하지 않는 한, 기본적으로 플레이 실행 시 첫 번째 작업으로 해당 호스트의 정보를 팩트 변수로 자동으로 수집하고 메모리에 저장
  • Ad-hoc 명령에서 팩트 변수 확인

    setup 모듈을 이용해서 팩트 변수 확인
    $ ansible all -m setup # 불필요한 많은 정보가 보이기 떄문에 필터 사용
    $ ansible localhost -m setup -a 'filter=ansible_hostname'

    $ ansible localhost -m setup -a 'filter=ansible_all_ipv4_addresses'

vi fact_test.yml

- name: fact test
  hosts: ansi-node1
  gather_facts: 0
  tasks:
  # 아무런 결과가 나오지 않는다. setup이 없기 때문에!
  - name: print facts
    debug:
      msg: "{{ ansible_facts }}"
  # 같은 결과가 나온다.
  - name: Gathering facts
    setup:
  - debug:
      msg: "ansible_hostname = {{ ansible_hostname }}"
  - debug:
      msg: "ansible_facts.hostname - {{ ansible_facts.hostname }}"
             
ansible-playbook fact_test.yml

팩트 수집 비활성화

플레이북의 플레이 실행 전 기본적으로 첫 작업으로 setup 모듈을 실행해 팩트 변수를 수집한다. 팩트 변수가 필요하지 않은 경우 팩트 변수 수집을 비 활성화해 성능을 향상시킬 수 있다.

  • gather_facts: no

작업 중 변수 수정: set_fact

set_fact 모듈을 사용해 플레이북의 작업을 실행하는 중에 새 변수를 정의하거나 기존 변수의 값을 재정의 할 수 있다.

vi set_fact.yml

- name: set fact test
  hosts: ansi-node1
  gather_facts: 0
  vars:
    var1: test1
  tasks:
  - debug:
      msg: "{{ var1 }}"
  - set_fact:
      var1 : test2
  - debug:
      msg: "{{ var1 }}"
   
ansible-playbook set_fact.yml

사용자 정의 팩트 변수

사용자 정의 팩트는 각 호스트별 사용자가 직접 정적 팩트 변수를 선언 가능하다.

  • 정의된 사용자 정의 팩트는 ansible_local 변수로 참조 가능
  • 사용자 정의 팩트 정의 방법
    • 각 관리 노드의 /etc/ansible/facts.d 디렉토리에 JSON 또는 INI 파일 형식으로 *.fact 파일을 생성

ssh ansi-node1

# ansi-node1에서 작업

# 현재는 폴더가 없음
vagrant@ansi-node1:~$ ls -ld /etc/ansible
ls: cannot access '/etc/ansible': No such file or directory

# 폴더 생성 
sudo mkdir -p /etc/ansible/facts.d
vagrant@ansi-node1:~$ ls -R /etc/ansible
/etc/ansible:
facts.d

sudo vi /etc/ansible/facts.d/test.fact

[test_section1]
username=Lee
groupname=goorm

exit

# master에서 사용자 정의 팩트변수 확인

ansible ansi-node1 -m setup -a 'filter=ansible_local'
                

사용자 정의 팩트변수 한번에 선언

vi local_fact.yml

- name: local fact test
  hosts: ansi-node2
  tasks:
  - name: Create facts directory
    file:
      state: directory
      dest: "/etc/ansible/facts.d/"
      recurse: yes
  - name: Create facts file
    file:
      state: touch
      dest: "/etc/ansible/facts.d/test.fact"
  - name: Edit facts file
    copy:
      content: "[test_section]\nusername=Pack\ngroupname=nobeak"
      dest: "/etc/ansible/facts.d/test.fact"
  
  # 반드시 적어주어야 작동
  - name: Update gather_facts
    setup:
    
  - name: Print local facts
    debug:
      msg: "{{ ansible_local }}"
  - debug:
      msg: "{{ ansible_local['test']['test_section']['username'] }}"
  - debug:
      msg: "{{ ansible_local.test.test_section.groupname }}"


ansible-playbook local_fact.yml
  • 항목을 다시 불러와야 만든 것들을 사용할 수 있기 때문에 setup을 반드시 넣어주어야 한다. 아니면 2번 실행하거나

팩트 변수 실습

ad-hoc 명령어와 플레이북으로 ansi-node1의 팩트 변수의 내용을 출력하기

# ansible ansi-node1 -m setup
- name: fact var
  hosts: ansi-node1
  gather_facts: yes
  tasks:
  - debug:
      msg: "{{ ansible_facts }}"
      

팩트 변수의 내용 중에서 배포판(distribution) 와 hostname 만 출력하기

# ansible ansi-node1 -m setup -a "filter=ansible_distribution"
# ansible ansi-node1 -m setup -a "filter=ansible_hostname"

- name: fact var
  hosts: ansi-node1
  gather_facts: yes
  tasks:
  - debug:
      msg: "{{ ansible_facts.distribution }}"
  - debug:
      msg: "{{ ansible_facts['hostname'] }}"

팩트 변수의 내용 중 hostname 항목을 var1 변수에 넣고 출력한 후에 다시 배포판 (distribution )의 내용을 var1에 재지정 후에 출력 되도록 하기

- name: set_fact var
  hosts: ansi-node1
  gather_facts: yes
  vars:
    var1: "{{ ansible_hostname }}"
  tasks:
  - debug:
      msg: "{{ var1 }}"

  - set_fact:
      var1: "{{ ansible_distribution }}"

  - debug:
      msg: "{{ var1 }}"

BB 에 /etc/ansible/facts.d 디렉토리를 만들어 local.fact 파일을 저장한 후에 local fact 변수를 이용해서 samba 패키지를 설치하고 시작해보기


vi localfacts_test.yml

- name: local_fact file
  hosts: ansi-master1
  gather_facts: no
  tasks:
  - copy:
      content: "[localfacts]\npkgname=samba\nsrvc=smbd\nstate=present\n"
      dest: /home/vagrant/ansitest/local.fact

- name: local_fact make
  hosts: BB
  tasks:
  - file:
      state: directory
      path: /etc/ansible/facts.d/
      recurse: yes
  - copy:
      src: /home/vagrant/ansitest/local.fact
      dest: /etc/ansible/facts.d/local.fact
  - setup:

  - apt:
      name: "{{ ansible_local.local.localfacts.pkgname }}"
      state: "{{ ansible_local.local.localfacts.state }}"

  - service:
      name: "{{ ansible_local.local.localfacts.srvc }}"
      state: started
      enabled: yes
    
    
# 만약 안에서 파일을 생성하지 않고 따로 만든다면 밑의 방식을 파일을 생성하고 진행
# ansi-master1 대상으로 local.fact 파일 생성 (ansible을 이용해서)
vi /etc/ansible/facts.d/local.fact

[localfacts]
pkgname = samba
srvc = smbd
state = present       

작업제어

  • 반복문, 조건문, 핸들러 등을 이용해 다양하게 작업 순서를 제어해 효과적으로 실행할 수 있음

반복문

동일한 작업을 여러 번 실행해야 하는 경우 사용한다. 여러 파일을 생성하고 관리해야하는 경우, 여러 사용자를 생성해야하는 경우 반복을 통해 효과적으로 작업을 제어할 수 있다.

  • Ansible 2.4 까지는 with_* 키워드를 사용하여 작업을 반복

  • Ansible 2.5 부터 조금 더 명확한 loop 키워드를 추가

  • 지금 당장 with_* 키워드의 기능을 loop가 완전하게 대체하는 것은 아니지만, 거의 대부분 loop에서도 유효

반복문 예시들

) 반복문을 사용하지 않는 일반적인 작업

---
- name: add user testuser1
  user:
    name: "testuser1"
    state: present
    groups: "wheel"

- name: add user testuser2
  user:
    name: "testuser2"
    state: present
...

예) 반복문 사용

---
- name: add several users
  user:
    name: "{{ item }}"
    state: present
  loop:
    - testuser1
    - testuser2
...

예) 반복문에서 변수 참조

- name: add several users
  hosts: ansi-node1
  gather_facts: 0
  vars:
    username:
    - testuser1
    - testuser2
  tasks:
  - name: add several users
    user:
      name: "{{ item }}"
      state: present
    loop: "{{ username }}"
    
  • 반복문에서 제공되는 목록을 참조하는 변수명은 항상 item으로 loop는 모듈의 옵션이 아니라, 작업의 속성을 지정한 것으로 들여 쓰기에 조심

  • apt 모듈은 설치 패키지 이름을 리스트로 받을 수 있기 때문에 굳이 반복문을 사용할 필요가 없다. 오히려 반복문을 사용하면 작업을 완료하는 시간이 오래 걸릴 수 있다.

사전이 목록으로 있는 변수

---
- name: add several users
  hosts: ansi-node1
  tasks:
  - name: Update gather_facts
    setup:
  - name: user test
    user:
      name: "{{ item.name }}"
      state: present
      groups: "{{ item.groups }}"
    loop:
      - { name: 'testuser1', groups: 'root' }
      - { name: 'testuser2', groups: 'root' }
...
  • 변수를 참조하는 방법은 item.<dict_key> or item['dict_key']형식으로 참조

중첩 목록 반복

여러 개의 목록을 결합(데카르트 곱) 가능하다.

예) 데카르트 곱
A = [ x, y, z ]
B = [ 1, 2, 3 ]
(x, 1) (x, 2) (x, 3)
(y, 1) (y, 2) (y, 3)
(z, 1) (z, 2) (z, 3)

- name: loop test
  hosts: ansi-node1
  gather_facts: 0
  vars:
    list1:
    - 1
    - 2
    list2:
    - a
    - b
    - c
  tasks:
  - debug:
      msg: "number = {{ item[0] }} apha = {{ item[1] }}"
    loop: "{{ list1 | product(list2) | list}}"
    

인벤토리 반복

인벤토리 호스트 목록을 반복문을 통해 가져올 수 있다.

- name: test
  hosts: ansi-node1
  gather_facts: 0
  tasks:
  - debug:
      msg: "{{ item }}"
    loop: "{{ groups['all'] }}"

  - debug:
      msg: "{{ item }}"
    loop: "{{ query('inventory_hostnames', 'all') }}"
                                                      

profile
전공 소개

0개의 댓글