Playbook
Playbook
1개 이상의 play를 저장한 것 (.yaml / .yml)
위에서부터 차례대로 play하기 때문에 start 먼저하고 install 하면 안됨.
** 문법체크
"ansible-playbook --syntax-check http.yaml"
기본 틀 (useradd)
--- # yaml문서의 시작 (생략가능)
- name: For useradd # 문서를 설명하는 이름 playbook의 시작은 무조건 리스트형("-")
hosts: all
tasks: # tasks의 시작도 리스트형("-")
- name: For useradd task # task를 설명하는 이름 (얘는 생략가능)
user:
name: tuser10 # 얘만 생략불가 나머지는 안쓰면 디폴트
comment: guaba # 유저코멘트
shell: /bin/bash
state: present # present=생성
- name: 두번째 계정 생성
user:
name: tuser20
state: present
http 깔고 실행하기
"ansible-doc yum", "ansible-doc service"로 확인해보면 편함
http.yaml
- name: playbook for http service
hosts: node1
tasks:
- name: installed httpd
yum:
name: httpd
state: latest # 설치되어있어도 최신버전으로 업데이트
- name: started httpd
service:
name: httpd
state: started # systemctl start httpd
enabled: yes
방화벽(firewalld) 설치 및 추가
[opuser@control sample]$ cat http.yaml
- name: playbook for http service
hosts: node1
tasks:
- name: installed httpd
yum:
name: httpd
state: latest # 설치되어있어도 최신버전으로 업데이트
- name: installed firewalld
yum:
name: firewalld
state: latest
- name: started httpd
service:
name: httpd
state: started # systemctl start httpd
enabled: yes
- name: started firewalld
service:
name: firewalld
state: restarted
enabled: yes
- name: add service https
firewalld:
service: https
state: enabled
permanent: yes # firewall-cmd --add-service=https --permanent
immediate: yes # firewall-cmd --reload
- name: add service http
firewalld:
service: http
state: enabled
여기에 install이 두개니까 리스트로 묶어서 할 수도 있다.
- name: installed httpd, firewalld
yum:
name:
- httpd
- firewalld
state: latest
이런식으로
혹은
name: [httpd, firewalld] 도 됨
index.html copy
멱등성 때문에 한번더 실행해도 change가 안됨.
하지만, index.html을 수정 혹은 변경하면 복사함
체크섬을 확인해서 복사하기 때문에
체크섬 확인 방법
"md5sum index.html"
- name: copy index.html
copy:
src: ./src/index.html # 출발지
dest: /var/www/html # 도착지
echo 출력 (command 모듈)
[opuser@control sample]$ cat test.yaml
- name: test
hosts: localhost
tasks:
- command: echo "hello ans"
register: myvar # register 변수의 이름은 myvar
- debug:
msg: "{{myvar.stdout}}"
- command: echo "hello linux"
register: myvar2
- debug:
msg: "{{myvar2.stdout}}"
- command: date
register: myvar3
- debug:
msg: "{{myvar3.stdout}}"
결과 출력
[opuser@control sample]$ ansible-playbook test.yaml
PLAY [test] ***************************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [localhost]
TASK [command] ************************************************************************************
changed: [localhost]
TASK [debug] **************************************************************************************
ok: [localhost] => {
"msg": "hello ans"
}
TASK [command] ************************************************************************************
changed: [localhost]
TASK [debug] **************************************************************************************
ok: [localhost] => {
"msg": "hello linux"
}
TASK [command] ************************************************************************************
changed: [localhost]
TASK [debug] **************************************************************************************
ok: [localhost] => {
"msg": "Tue Feb 13 06:47:34 UTC 2024"
}
PLAY RECAP ****************************************************************************************
localhost : ok=7 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
변수 (var - variable)
변수이름은 문자로 시작해야 하고 특수문자는 '_' 만 사용가능하다.
변수로 인식은 {{변수}} 다. (중괄호 두개)
var.yaml
[opuser@control sample]$ cat var.yaml
- name: var
hosts: node1
vars: # 변수선언
service: vsftpd
service_port: 21
tasks:
- name: installed {{service}} # 변수가 뒤에있다면 "" 안붙여도 됨
yum:
name: "{{service}}" # 변수가 맨 앞에 있다면 "" 붙여야함
state: present
- name: "{{service_port}} is ftp port"
debug:
var: service_port
TASK [21 is ftp port] *****************************************************************************
ok: [node1] => {
"service_port": 21
}
inventory에 변수 등록
[opuser@control sample]$ cat inventory
[webservers]
node1 package=finger # 한칸 이상만 띄우면 된다. node1에서 package=finger로 변수 설정
node2 package=finger-server service=finger-server
[dbservers]
node3
[dbservers:vars] # 그룹으로 묶어서 변수 설정
service=mariadb
** inventory에 변수를 등록하면 지저분해질 수 있다.
그래서 host_vars와 group_vars에 등록할 수 있다. (이름 이대로 해야함)
vim host_vars/node1 # 호스트 이름을 파일명으로
>> package: finger # ":" 콜론뒤에 한칸 띄워야함
vim host_vars/node2
>> package: finger-server
service: finger-server
vim group_vars/dbservers # 그룹 이름을 파일명으로
>> service: mariadb
등록된 변수 확인
[opuser@control sample]$ cat var.yaml
- name: var
hosts: [node1, node2]
tasks:
- name: "{{package}}"
debug:
var: package
- name: var2
hosts: node2
tasks:
- debug:
var: service
[opuser@control sample]$ ansible-playbook var.yaml
PLAY [var] ****************************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [node2]
ok: [node1]
TASK [finger] *************************************************************************************
ok: [node1] => {
"package": "finger"
}
ok: [node2] => {
"package": "finger-server"
}
PLAY [var2] ***************************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [node2]
TASK [debug] **************************************************************************************
ok: [node2] => {
"service": "finger-server"
}
실습
시나리오:
192.168.110.20 (node1)에서는 node1
192.168.110.30 (node2)에서는 node2
192.168.110.40 (node3)에서는 node3
이라고 나오도록 만들기
src/index.html에 node1
src2/index.html에 node2
src3/index.html에 node3 를 만든뒤
[opuser@control sample]$ cat index.yaml
- name: playbook for http service
hosts: [node1, node2, node3]
tasks:
- name: installed httpd, firewalld
yum:
name:
- httpd
- firewalld
state: latest # 설치되어있어도 최신버전으로 업데이트
- name: started httpd
service:
name: httpd
state: started # systemctl start httpd
enabled: yes
- name: started firewalld
service:
name: firewalld
state: restarted
enabled: yes
- name: add service https
firewalld:
service: https
state: enabled
permanent: yes
immediate: yes
- name: add service http
firewalld:
service: http
state: enabled
permanent: yes
immediate: yes
- name: node1 index
hosts: node1
tasks:
- name: copy index.html
copy:
src: ./src/index.html # 출발지
dest: /var/www/html # 도착지
- name: node2 index
hosts: node2
tasks:
- name: copy index.html
copy:
src: ./src2/index.html
dest: /var/www/html
- name: node3 index
hosts: node3
tasks:
- name: copy index.html
copy:
src: ./src3/index.html
dest: /var/www/html
이거 말고도 커맨드로 echo "node1" > /var/www/html/index.html 하는 방법도 있지만 이건 멱등성 문제때매 패스
목적지 dest: 를 변수로 잡고 해도 될거같음
혹은
node1.html, node2.html, node3.html 이런식으로 다 만들어두고
inventory에 node1 index_file=node1.html 이런식으로 변수 등록 한 뒤
src를 ./src/{{index_file}} 하고
dest를 /var/www/html/index.html 로 바꿔서 저장하면 된다. - 요러면 yaml파일에 task 한번으로 다됨
혹은
lineinfile을 사용하면 되는데 (한줄 추가하는것)
- name:
lineinfile:
path: /var/www/html/index.html # 도착지 경로
line: welcome to {{nodename}} # nodename은 inventory에 등록해두고
create: yes # 없으면 추가하는것
** 여러줄 추가는 blockinfile
debug를 통한 팩트변수 출력하기
[vagrant@control /home/vagrant/sample]$ cat b.yaml
- hosts: all
tasks:
- debug:
msg: "{{ansible_facts['nodename']}} {{ ansible_facts['devices']}}"
- debug:
msg: "{{ansible_facts['system']}}"
- debug:
msg: "{{ansible_facts['os_family']}}"
결과
[vagrant@control /home/vagrant/sample]$ ansible-playbook b.yaml
PLAY [all] ****************************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [node2]
ok: [node3]
ok: [node1]
TASK [debug] **************************************************************************************
ok: [node1] => {
"msg": "node1.example.com {u'sda': {u'scheduler_mode': u'noop', u'sectorsize': u'512', u'vendor': u'ATA', u'sectors': u'83886080', u'links': {u'masters': [], u'labels': [], u'ids': [u'ata-VBOX_HARDDISK_VB7fb4235f-51b795ad'], u'uuids': []}, u'sas_device_handle': None, u'sas_address': None, u'virtual': 1, u'holders': [], u'host': u'IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)', u'rotational': u'1', u'removable': u'0', u'support_discard': u'0', u'serial': u'VB7fb4235f', u'size': u'40.00 GB', u'model': u'VBOX HARDDISK', u'partitions': {u'sda1': {u'sectorsize': 512, u'uuid': u'1c419d6c-5064-4a2b-953c-05b2c67edb15', u'sectors': u'83884032', u'links': {u'masters': [], u'labels': [], u'ids': [u'ata-VBOX_HARDDISK_VB7fb4235f-51b795ad-part1'], u'uuids': [u'1c419d6c-5064-4a2b-953c-05b2c67edb15']}, u'start': u'2048', u'holders': [], u'size': u'40.00 GB'}}}}"
}
ok: [node2] => {
"msg": "node2.example.com {u'sda': {u'scheduler_mode': u'noop', u'sectorsize': u'512', u'vendor': u'ATA', u'sectors': u'83886080', u'links': {u'masters': [], u'labels': [], u'ids': [u'ata-VBOX_HARDDISK_VB331308a0-1b094729'], u'uuids': []}, u'sas_device_handle': None, u'sas_address': None, u'virtual': 1, u'holders': [], u'host': u'IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)', u'rotational': u'1', u'removable': u'0', u'support_discard': u'0', u'serial': u'VB331308a0', u'size': u'40.00 GB', u'model': u'VBOX HARDDISK', u'partitions': {u'sda1': {u'sectorsize': 512, u'uuid': u'1c419d6c-5064-4a2b-953c-05b2c67edb15', u'sectors': u'83884032', u'links': {u'masters': [], u'labels': [], u'ids': [u'ata-VBOX_HARDDISK_VB331308a0-1b094729-part1'], u'uuids': [u'1c419d6c-5064-4a2b-953c-05b2c67edb15']}, u'start': u'2048', u'holders': [], u'size': u'40.00 GB'}}}}"
}
ok: [node3] => {
"msg": "node3.example.com {u'sda': {u'scheduler_mode': u'noop', u'sectorsize': u'512', u'vendor': u'ATA', u'sectors': u'83886080', u'links': {u'masters': [], u'labels': [], u'ids': [u'ata-VBOX_HARDDISK_VB96bd062b-9460dfb3'], u'uuids': []}, u'sas_device_handle': None, u'sas_address': None, u'virtual': 1, u'holders': [], u'host': u'IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)', u'rotational': u'1', u'removable': u'0', u'support_discard': u'0', u'serial': u'VB96bd062b', u'size': u'40.00 GB', u'model': u'VBOX HARDDISK', u'partitions': {u'sda1': {u'sectorsize': 512, u'uuid': u'1c419d6c-5064-4a2b-953c-05b2c67edb15', u'sectors': u'83884032', u'links': {u'masters': [], u'labels': [], u'ids': [u'ata-VBOX_HARDDISK_VB96bd062b-9460dfb3-part1'], u'uuids': [u'1c419d6c-5064-4a2b-953c-05b2c67edb15']}, u'start': u'2048', u'holders': [], u'size': u'40.00 GB'}}}}"
}
TASK [debug] **************************************************************************************
ok: [node1] => {
"msg": "Linux"
}
ok: [node2] => {
"msg": "Linux"
}
ok: [node3] => {
"msg": "Linux"
}
TASK [debug] **************************************************************************************
ok: [node1] => {
"msg": "RedHat"
}
ok: [node2] => {
"msg": "RedHat"
}
ok: [node3] => {
"msg": "RedHat"
}
when 제어구문
[vagrant@control /home/vagrant/sample]$ cat when.yaml
- hosts: localhost
tasks:
- command: /bin/false
register: result # register는 결과물을 변수로 정의하는 것
ignore_errors: True # 에러가 나더라도 무시하고 아래꺼를 실행해라
- command: cal
register: cal_result
when: result is failed # 위의 register의 result(변수)가 failed라면 아래꺼를 실행해라
- debug:
msg: "{{cal_result}}"
** register는 결과물을 변수로 정의하는 것이다.
결과
[vagrant@control /home/vagrant/sample]$ ansible-playbook when.yaml
PLAY [localhost] **********************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [localhost]
TASK [command] ************************************************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.006196", "end": "2024-02-14 12:01:56.983409",
"msg": "non-zero return code", "rc": 1, "start": "2024-02-14 12:01:56.977213", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring
TASK [command] ************************************************************************************
changed: [localhost]
TASK [debug] **************************************************************************************
ok: [localhost] => {
"msg": {
"changed": true,
"cmd": [
"cal"
],
"delta": "0:00:00.008171",
"end": "2024-02-14 12:01:57.620365",
"failed": false,
"rc": 0,
"start": "2024-02-14 12:01:57.612194",
"stderr": "",
"stderr_lines": [],
"stdout": " February 2024 \nSu Mo Tu We Th Fr Sa\n
1 2 3\n 4 5 6 7 8 9 10\n11 12 13 14 15 16 17\n18 19 20 21 22 23 24\n25 26 27 28 29",
"stdout_lines": [
" February 2024 ",
"Su Mo Tu We Th Fr Sa",
" 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"
]
}
}
loop (반복)
[vagrant@control /home/vagrant/sample]$ cat loop2.yaml
- name: add several users
hosts: all
tasks:
- user:
name: "{{ item }}"
state: present
groups: "wheel"
loop:
- testuser1
- testuser2
[vagrant@control /home/vagrant/sample]$ ansible-playbook loop2.yaml
PLAY [add several users] **************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [node2]
ok: [node3]
ok: [node1]
TASK [user] ***************************************************************************************
changed: [node2] => (item=testuser1)
changed: [node3] => (item=testuser1)
changed: [node1] => (item=testuser1)
changed: [node2] => (item=testuser2)
changed: [node3] => (item=testuser2)
changed: [node1] => (item=testuser2)
[vagrant@control /home/vagrant/sample]$ ansible all -a "ls /home"
node1 | CHANGED | rc=0 >>
admin
devops
opuser
testuser1 # 추가됨
testuser2 # 추가됨
tuser10
vagrant
node2 | CHANGED | rc=0 >>
admin
devops
opuser
testuser1 # 추가됨
testuser2 # 추가됨
vagrant
node3 | CHANGED | rc=0 >>
admin
devops
opuser
testuser1 # 추가됨
testuser2 # 추가됨
vagrant
handlers
서비스를 등록 해두고 notify로 불러올 수 있다. (평상시에는 안됨)
* 대신 불러올 때 handlers의 name을 참조하기 때문에 name을 잘 쓸 필요가 있다.
* notify가 붙은 모듈에서 change가 발생해야 handlers로 등록된 모듈이 실행된다.
* handlers는 tasks와 같은 라인임 (띄어쓰기 주의)
* handlers는 tasks가 다 끝난 이후에 실행됨.
- hosts: all
tasks:
- name: install httpd
yum:
name: httpd
state: present
- name: start httpd
service:
name: httpd
state: started
enabled: yes
- name: start firewalld
service:
name: firewalld
state: started
- name: permit httpd on firewalld
firewalld:
service: http
permanent: yes
immediate: yes
state: enabled
- name: copy file httpd.conf to managed nodes
copy:
src: ./src/httpd.conf
dest: /etc/httpd/conf/
notify:
- restart apache
- name: line add in index.html to managed nodes
lineinfile:
path: /var/www/html/index.html
line: <h1>welcome to {{hostname}}</h1>
create: yes
handlers:
- name: restart apache
service:
name: httpd
state: restarted
handler 출력 순서 확인
[vagrant@control sample]$ cat handler.yaml
- hosts: localhost
tasks:
- command: /bin/true
- debug:
msg: test messages 1
- command: /bin/true
notify: second handler
- debug:
msg: test messages 2
- command: /bin/true
notify: first handler
- debug:
msg: test messages 3
handlers:
- name: first handler
debug:
msg: first handler's message
- name: second handler
debug:
msg: second handler's message
- name: third handler
debug:
msg: third handler's message
test 1 > second handler > test 2 > first handler > test 3 로 적혀있지만
실제로는 test 1 > test 2 > test 3 > first handler > second handler 순으로 출력된다.
(그냥 모든 모듈이 먼저 출력이 된 후에 소환된 핸들러를 출력함)
[vagrant@control sample]$ ansible-playbook handler.yaml
TASK [debug] **************************************************************************************
ok: [localhost] => {
"msg": "test messages 1"
}
TASK [debug] **************************************************************************************
ok: [localhost] => {
"msg": "test messages 2"
}
TASK [debug] **************************************************************************************
ok: [localhost] => {
"msg": "test messages 3"
}
RUNNING HANDLER [first handler] *******************************************************************
ok: [localhost] => {
"msg": "first handler's message"
}
RUNNING HANDLER [second handler] ******************************************************************
ok: [localhost] => {
"msg": "second handler's message"
}
'Ansible' 카테고리의 다른 글
centos, ubuntu, window node 생성 및 nfs (0) | 2024.02.15 |
---|---|
실습 (0) | 2024.02.14 |
Ansible Yaml (0) | 2024.02.07 |
Ansible 기본 설정 및 Ad-hoc (0) | 2024.02.06 |
Ansible 사전 작업 (VM생성) - Vagrant를 통해 (0) | 2024.02.06 |