티스토리 뷰
▶ 시간 맞추기
[opuser@control sample]$ ansible all -m command -a 'timedatectl set-timezone "Asia/Seoul"'
node2 | CHANGED | rc=0 >>
node1 | CHANGED | rc=0 >>
node3 | CHANGED | rc=0 >>
[opuser@control sample]$ ansible all -m command -a 'date'
node2 | CHANGED | rc=0 >>
Wed Feb 14 09:49:23 KST 2024
node3 | CHANGED | rc=0 >>
Wed Feb 14 09:49:23 KST 2024
node1 | CHANGED | rc=0 >>
Wed Feb 14 09:49:23 KST 2024
▶ 명령어 줄임말은 안통한다
▶ 정의되지 않은 변수 사용하여 에러
▶ 변수 우선순위는 커맨드라인 변수가 playbook 보다 높다
[vagrant@control work]$ ansible-playbook a.yaml -e "var1=100 var2=200 var3=300"
▶ 동일한 변수 중첩되어 문제 발생
>> homdir 이 동일
▷ 파이썬 표현
>> 딕셔너리 타입
users = {'user1':{'uid':1010,'homedir':'/home/user1'},'user2':{'uid':1011,'homedir':'/home/user2'}}
print(users['user1'],['uid'])
>> 파이썬 기반이므로 같은 형식으로 출력
msg: "{{users['user1']['uid']}}"
▷ 이렇게도 가능
msg: "{{users.user1.uid}}"
◎ 디버그 모듈
▷ 매직변수 - ansible 에 의해 자동으로 설정되는 변수
▷ hostvars - 관리대상 호스트의 변수를 얻을때 사용
▷ group_names - 현재 호스트가 속한 그룹리스트
▷ groups - inventory 내의 전체 그룹 및 모든호스트
▷ inventory_hostname - inventory 에 실제기록되어 있는 호스트 이름
♠ 참조
https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html#magic-variables
Special Variables — Ansible Documentation
When the current role is being executed by means of an include_role or import_role action, this variable contains a list of all parent roles, with the most recent role (in other words, the role that included/imported this role) being the first item in the
docs.ansible.com
▷ 팩트변수
- ansible 이 managed node(host) 에서 자동으로 검색한 변수 팩트에 포함된 정보
호스트이름 / 커널버전 / 환경변수 / CPU 정보 / 메모리정보 / 디스크정보 / 네트워크정보 / 운영체제버전 / ip주소
- 팩트는 managed node(host) 의 상태를 파악하고 해당 상태에 따라서 여러가지 조치를 하기위한 방법
- ansible 실행시 TASK [Gathering Facts] 부분이 수집하고 있는 것
>> node1에 대한 정보
[vagrant@control work]$ ansible -m setup node1
ex> 운영체제 출력
>> 특정 팩트 변수만 수집할 때
- hosts: all
tasks:
- debug:
msg: "{{ansible_facts['nodename']}} {{ansible_facts['devices']['sda']['model']}}"
>> 플레이북 실행시 팩트 수집 안하는 방법
[ 속도가 빨라진다 ]
- hosts: node1
gather_facts: no
tasks:
- debug:
msg: "{{ansible_facts['nodename']}} {{ansible_facts['devices']['sda']['model']}}"
◎ 제어구문
▶ when
>> 첫 command 값이 false 이므로 밑에는 실행되지 않고 에러가 난다
>> 두번째 command 가 참이므로 skipping이 출력
>> ignore_errors 는 default 가 false 이므로,
>> true 설정시, 에러가 나와도 실행한다
- hosts: localhost
tasks:
- command: /bin/false
register: result
ignore_errors: true
- command: cal
register: cal_result
when: result is failed
- debug:
msg: "{{cal_result}}"
>> 첫번째 command 에서 에러가 나왔지만
>> 두번째 command 실행한다
>> 두번째 command 에 해당하는 when 값이 실패로 일치하므로
>> cal_result 값이 지정되어 출력까지 된다
>> when 이 포함된 모듈에만 영향
>> when 조건을 만족하지 못했으므로, skipping
>> 앞에 여러가지 붙어있으므로 find() 는 method >>> 함수라고 생각,
>> hi 라는 인자를 찾는데 없으면 -1
>> stdout 은 표준 출력
>> node2 에 hi 추가
[root@node2 ~]# echo "hellohello hihi node2" > /etc/motd
[root@node2 ~]# cd /etc/motd
-bash: cd: /etc/motd: Not a directory
[root@node2 ~]# cat /etc/motd
hellohello hihi node2
>> node2 는 skipping 안됨
>> 변수 motd_contents 값 확인해보기
- name: test
gather_facts: no
hosts: all
tasks:
- shell: cat /etc/motd
register: motd_contents
- shell: echo "motd contains the word hi"
when: motd_contents.stdout.find('hi') != -1
- debug:
msg: "{{motd_contents}}"
#################
- name: test
gather_facts: no
hosts: all
tasks:
- shell: cat /etc/motd
register: motd_contents
- shell: echo "motd contains the word hi"
when: motd_contents.rc == 0
- debug:
msg: "{{motd_contents}}"
● 파이썬에서 확인
>> find() 함수는 글자 위치를 출력해준다
>> 해당 글자가 없으면 -1 출력한다
▶ loops
== with_list
# 해당되는 하나의 모듈에서만 영향
>> 리스트 이므로 [ ] 사용
>> 반복되는 값을 저장하는 변수를 item 으로 지정했다
>> 루프가 돌 때 마다 item 변수에 저장한다
>>> item 변수는 값을 바꿀 수 없다
>> loop 안에 값이 없을 때 까지 완료하고 아래로 실행이 진행
- hosts: localhost
gather_facts: no
tasks:
- user:
name: "{{item}}"
state: present
groups: wheel
loop:
[testuser1,testuser2]
>> with_list 로 지정해도 동일
- hosts: localhost
gather_facts: no
tasks:
- user:
name: "{{item}}"
state: present
groups: wheel
with_list:
[testuser1,testuser2]
>> testuser1, testuser2 유저 생성 완료
[vagrant@control work]$ sudo ls /home
kildong opuser testuser1 testuser2 vagrant younghee
▩ 에러 발생
>> zuser1 이라는 그룹이 없는데 zuser1 유저를 넣으려고 하니까 에러가 나온다
[vagrant@control work]$ sudo useradd -g zuser1 zuser1
useradd: group 'zuser1' does not exist
▶ 제대로 진행 완료
# 딕셔너리는 key 와 value로 되어있으므로, with_items 로 사용
#### with_list 로 써도 실행 됐다. 옛날에는 안됐다 ####
▷ loop 로 써도 가능
>> 같은 성격이 두개이면, 리스트로 표시한다 ( - 사용 )
>> 하나의 값이면 리스트 표시 안해도 된다
>> 딕셔너리 이므로, item.name , item.groups
>>> key.value
- hosts: all
gather_facts: no
tasks:
- user:
name: "{{item.name}}"
state: present
groups: "{{item.groups}}"
with_items:
- {name: 'usera', groups: 'root'}
- {name: 'admin', groups: 'wheel'}
>>> 동일
"{{item['name']}}"
"{{item['groups']}}"
♠ 참조
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_conditionals.html
Conditionals — Ansible Documentation
In a playbook, you may want to execute different tasks or have different goals, depending on the value of a fact (data about the remote system), a variable, or the result of a previous task. You may want the value of some variables to depend on the value o
docs.ansible.com
▶ netsted loop
>> 중첩 루프
create user dbuser1;
grant all privileges on testdb.* to dbuser1
identified by 'redhat';
- hosts: localhost
gather_facts: no
tasks:
- debug:
msg: "{{item[0]}} {{item[1]}}"
with_nested:
- ['dbuser1','dbuser2']
- ['testdb','mydb','sampledb']
이 내용을 플레이북으로 적용하기 위한 여정의 시작...
create user dbuser1;
grant all privileges on testdb.* to dbuser1
identified by 'redhat';
▩ 오류가 발생
>> python 은 2.7.5 버전 이므로, pymysql 로 실행해야한다
>> mysql-python 존재 확인
>> 안되길래 방화벽까지 건들다
- hosts: [node1,node2]
gather_facts: no
tasks:
- yum:
name: MySQL-python
state: latest
- yum:
name: mariadb-server
state: latest
- service:
name: firewalld
state: restarted
- firewalld:
immediate: true
service: mysql
state: enabled
- service:
name: mariadb
state: started
- mysql_user:
name: "{{item[0]}}"
priv: "{{item[1]}}.*:ALL"
append_privs: yes
password: redhat
with_nested:
- ['dbuser1','dbuser2']
- ['testdb','mydb','sampledb']
>> yum 이 여러개일 때 한번에 적을 수도 있다
>> yum 모듈은 대문자 엄격한 듯
>> mysql-python 은 안되더라...
- yum:
name:
- mariadb-server
- MySQL-python
◎ 핸들러 : 항상 마지막에 적는다
- notify 문을 사용하여 명시적으로 호출된 경우에만 실행
- 핸들러는 특정작업의 notify문에 나열된 순서가 아닌
핸들러 섹션이 플레이에서 작성된 순서로 항상 실행
- 핸들러는 task 의 모든 작업이 완료된 후에 실행
- notify는 changed 가 있는 경우에만 핸들러에게 알림
▩ host_vars ..... hosts_vars 가 아니다
>> 변수 넣는 형식 기억
>> = 이 아니다
>> hostname=node1 형식은 inventory에 넣는다
hostname: node1
▶ src 는 local / dest 는 관리 대상 장비
- hosts: all
gather_facts: no
tasks:
- yum:
name: httpd
state: latest
- service:
name: firewalld
state: restarted
- firewalld:
permanent: yes
immediate: yes
service: http
state: enabled
- service:
name: httpd
state: started
- copy:
src: ./src/httpd.conf
dest: /etc/httpd/conf
- lineinfile:
path: /var/www/html/index.html
line: welcome to {{hostname}}
create: yes
handlers:
- service:
name: httpd
state: restarted
>> 사전 조치
host 장비
mkdir src
cp /etc/httpd/conf/httpd.conf /home/vagrant/work/src
>> ansible-playbook 실행해 보고, 확인
>> /home/vagrant/work/src/httpd.conf 파일 수정
DirectoryIndex 에서 index.html 을 welcome.html 으로 수정
▒ 핸들러의 필요성 ▒
: 기존의 index.html 내용이 아닌 welcome.html 로 수정되었으니,
http service 를 수정이 되었을 때만 restart 하려고 한다
>> handlers 에 적은 name 에 적은 내용을
>> 바뀐 부분인 copy 부분에 notify 로 똑같이 적는다
>> 주의 : handlers 의 name 부분과 service 부분이 들여쓰기 동일해야 됨
>> 아니면 오류뜸
- hosts: all
gather_facts: no
tasks:
- yum:
name: httpd
state: latest
- service:
name: firewalld
state: restarted
- firewalld:
permanent: yes
immediate: yes
service: http
state: enabled
- service:
name: httpd
state: started
- copy:
src: ./src/httpd.conf
dest: /etc/httpd/conf
notify: restart http
- lineinfile:
path: /var/www/html/index.html
line: welcome to {{hostname}}
create: yes
handlers:
- name: restart http
service:
name: httpd
state: restarted
>> 또 한번 사전조치
>>> 설정파일에 주석 하나만 추가해도 값이 바뀐 것으로 적용
/home/vagrant/work/src/httpd.conf
>> 처음 값과 바뀌었다
▷ handlers 의 실행 순서
# command 명령어는 change 가 됐는지 안됐는지 모르므로,
# 에러가 안나오면 무조건 change 됐다고 인식
- hosts: localhost
gather_facts: no
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:
>>>> handlers 는 tasks 에 있는 내용이 모두 실행되고 나서 실행
>>>> handlers 에 입력한 순서대로 실행
▩ LAB
webapps 그룹에 속한 노드들중 현재 남아있는 메모리가 500메가 이상인 경우에만
ftp 서버패키지(vsftpd) 를 설치가 되게 하고 서비스를 실행하세요
(조건문과 팩트변수를 활용하세요)
(작업완료후 ftp 서버로 접속이 잘 되는지 확인해 보아야 합니다)
==> control node 에서 sudo yum -y install ftp 설치후
vsftpd 가 설치된 node 주소로 ftp 로 접속
ex) ftp node1
* ftp 설치조건을 만족한 장비에만 ftp 서버가 설치되고 실행이 되므로
접속이 안된다면 ftp 서버가 설치된것인지 확인해 해보고 접속해야 합니다.
[vagrant@control examples]$ ansible webapps -m setup > mem.txt
>> 뭘로 썼는지 확인
>> 확인 결과 잘 출력됨
>> facts 변수는 ansible_memory_mb 에서 ansible을 빼고 적는다
- hosts: webapps
tasks:
- debug:
msg: "{{ansible_facts['memfree_mb']}}"
- hosts: webapps
tasks:
- debug:
msg: "{{ansible_facts['memfree_mb']}}"
when: ansible_memory_mb >= 500
- yum:
name:
- epel-release
- vsftpd
state: latest
- service:
name: vsftpd
state: started
'Ansible' 카테고리의 다른 글
Ansible 총정리2 (0) | 2024.02.16 |
---|---|
Ansible 총 정리 (1) | 2024.02.15 |
yaml [ playbook ] (0) | 2024.02.13 |
Ansible module (0) | 2024.02.13 |
Visual Studio Code (0) | 2024.02.08 |