💡 전체 코드를 작성하지 않은 것들은 tasks 밑에 들어갈 내용만 적어둔 것이다.
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
- 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
-name: lookuptest
hosts: ansi-node1
vars:
hostname1: "{{ lookup('file','/etc/hostname') }}"
gather_facts: no
tasks:
- debug:
msg: "{{ hostname1 }}"
- 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') }}"
- name: hashtest
hosts: ansi-node1
gather_facts: no
tasks:
- debug:
msg: "{{ '123' | password_hash('sha256','1234') }}"
# 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 }}"
운영 체제 관련 정보, IP 주소, NIC 정보, 디스크 장치, 배포판, 환경 변수, CPU 정보, 메모리 정보, 마운트 정보 등 관리 노드의 정보를 가진 변수이다.
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 모듈을 실행해 팩트 변수를 수집한다. 팩트 변수가 필요하지 않은 경우 팩트 변수 수집을 비 활성화해 성능을 향상시킬 수 있다.
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
사용자 정의 팩트는 각 호스트별 사용자가 직접 정적 팩트 변수를 선언 가능하다.
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
# ansible ansi-node1 -m setup
- name: fact var
hosts: ansi-node1
gather_facts: yes
tasks:
- debug:
msg: "{{ ansible_facts }}"
# 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'] }}"
- 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 }}"
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' }
...
여러 개의 목록을 결합(데카르트 곱) 가능하다.
예) 데카르트 곱
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') }}"