目录
一、handlers和notify结合使用触发条件
Handlers
是task列表,这些task与前述的task的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作。
Notify此action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作成为handler,也即notify中调用handler中定义的操作。
例如:更新配置文件,重新启动playbook,系统不会重启服务。
1.新建httpd.yml文件
[root@ansible145 ansible]# vim httpd.yml
---
- hosts: websrvs
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd
- name: copy conf file
copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=yes
- name: start service
service: name=httpd state=started enabled=yes
2.复制配置文件到ansible的files目录中
[root@ansible145 ansible]# ll /etc/httpd/conf/httpd.conf
-rw-r--r--. 1 root root 11753 May 30 21:49 /etc/httpd/conf/httpd.conf
[root@ansible145 ansible]# cp /etc/httpd/conf/httpd.conf files/
[root@ansible145 ansible]# tree
.
├── files
│ ├── httpd.conf
│ ├── index.html
│ └── test.html
├── file.yml
├── hello2.yml
├── hello.yml
├── host.sh
└── selinux
3.卸载被控机已安装的httpd
检查端口号,80端口已开启,需要卸载httpd
卸载命令
[root@ansible145 ansible]# ansible all -m yum -a 'name=httpd state=absent'
检查被控机的80端口已消失
4.执行httpd.yml脚本
# 检查语法
[root@ansible145 ansible]# ansible-playbook -C httpd.yml
# 语法没问题再执行脚本
[root@ansible145 ansible]# ansible-playbook -C httpd.yml
被控机已成功安装并启动httpd服务,80端口已启动
[root@ansible145 ansible]# ansible websrvs -m shell -a 'ss -ntl | grep :80'
192.168.22.142 | CHANGED | rc=0 >>
LISTEN 0 128 :::80 :::*
192.168.22.141 | CHANGED | rc=0 >>
LISTEN 0 128 :::80 :::*
5.更改httpd.conf配置文件
修改端口号为8080
bash
[root@ansible145 ansible]# vim ./files/httpd.conf
再次执行httpd.yml后,检查80端口号,依然还在启动,没有变为8080
6.使用handlers
因此,当我们修改程序的配置文件时,重新执行ansible脚本需要重启服务,变为最新的配置和服务,此时,就需要用到handlers。
bash
---
- hosts: websrvs
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd
- name: copy conf file
copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=yes
notify: restart service # 标记改变的任务,名字要与handlers下的name一一对应
# 告诉handlers,当配置文件发生改变时,执行handlers下面的重启服务任务
- name: start service
service: name=httpd state=started enabled=yes
handlers: # 当上面的某个或某些任务改变时,执行下面的任务
- name: restart service
service: name=httpd state=restarted
更改主控机的配置文件,因为第二次执行脚本时,更改后的配置文件8080端口已经复制到被控机上了,如果不更改,就相当于配置文件没有变。
bash
[root@ansible145 ansible]# vim ./files/httpd.conf
7.重新执行httpd.yml脚本
bash
[root@ansible145 ansible]# ansible-playbook httpd.yml
8.检查被控机的端口号是否改变
端口号改变,服务成功重启!
9.handlers也可以触发多个
bash
- hosts: websrvs
remnte user: root
tasks:
- name: add group nginx
tags: user
user: name=nginx state=present
- name: add user nginx
user: name=nginx state=present group=nginx
- name: Inslall Ngiix
yum: name=nginx state=present
- name: config
copy: src=/root/contig.txt dest=/etc/nginx/nginx.conf
notify:
- Restart Nginx
- Check Nginx Process
handlers:
- name: Restart Nginx
service: name=nginx state=restarted enabled=yes
- name: Check Nginx process
shell: killall -0 nginx > /tmp/nginx.log
二、tags
1.通过指定标签来执行特定的动作
bash
---
- hosts: websrvs
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd
tags: inshttpd
- name: copy conf file
copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=yes
notify: restart service
- name: start service
service: name=httpd state=started enabled=yes
tags: rshttpd
handlers:
- name: restart service
service: name=httpd state=restarted
2.停止httpd服务
bash
[root@ansible145 ansible]# ansible websrvs -m service -a 'name=httpd state=stopped'
3.检查是否成功停止
4.执行启动服务的tags
bash
[root@ansible145 ansible]# ansible-playbook -t rshttpd httpd.yml
5.重新检查服务是否启动
6.也可以针对多个标签执行脚本
bash
# 卸载httpd
[root@ansible145 ansible]# ansible websrvs -m yum -a 'name=httpd state=absent'
# 检查是否成功卸载
[root@ansible145 ansible]# ansible websrvs -m shell -a 'rpm -q httpd'
# 执行多个tags
[root@ansible145 ansible]# ansible-playbook -t inshttpd,rshttpd httpd.yml
# 启动的服务为默认的80端口
[root@ansible145 ansible]# ansible websrvs -m shell -a 'ss -ntl | grep :80'
192.168.22.141 | CHANGED | rc=0 >>
LISTEN 0 128 :::80 :::*
192.168.22.142 | CHANGED | rc=0 >>
LISTEN 0 128 :::80 :::*
7.多个动作对应一个标签tags
脚本:
bash
---
- hosts: websrvs
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd
tags: httpd
- name: copy conf file
copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=yes
notify: restart service
- name: start service
service: name=httpd state=started enabled=yes
tags: httpd
handlers:
- name: restart service
service: name=httpd state=restarted
bash
# 卸载httpd
[root@ansible145 ansible]# ansible websrvs -m yum -a 'name=httpd state=absent'
# 检查是否成功卸载
[root@ansible145 ansible]# ansible websrvs -m shell -a 'rpm -q httpd'
# 执行tags
[root@ansible145 ansible]# ansible-playbook -t httpd httpd.yml
# 启动的服务为默认的80端口
[root@ansible145 ansible]# ansible websrvs -m shell -a 'ss -ntl | grep :80'
192.168.22.141 | CHANGED | rc=0 >>
LISTEN 0 128 :::80 :::*
192.168.22.142 | CHANGED | rc=0 >>
LISTEN 0 128 :::80 :::*
查看标签:
bash
[root@ansible145 ansible]# ansible-playbook httpd.yml --list-tags
playbook: httpd.yml
play #1 (websrvs): websrvs TAGS: []
TASK TAGS: [httpd]
三、playbook中变量的使用
使用变量可以对不同的被控机进行不同的操作。
bash
ansible websrvs -m setup | grep ansible_fqdn
ansible websrvs -m setup | grep ansible_hostname
ansible websrvs -m setup -a 'filter=ansible_fqdn'
ansible websrvs -m setup -a 'filter=ansible_hostname'
ansible websrvs -m setup -a 'filter=ansible_*'
ansible websrvs -m setup -a 'filter=*address'
ansible websrvs -m setup -a 'filter=ansible_all_ipv4_addresses'
ansible websrvs -m setup -a 'filter=ansible_eth0'
1.定义1个变量
(1)编写脚本
bash
vim app.yml
---
- hosts: appsrvs
remote_user: root
tasks:
- name: install package
yum: name={{ pkname }}
- name: start service
service: name={{ pkname }} state=started enabled=yes
(2)启动脚本时对脚本中的变量进行赋值
bash
[root@ansible145 ansible]# ansible-playbook -e 'pkname=vsftpd' app.yml
(3)检查程序是否成功安装、服务是否成功开启
2.定义2个变量
(1)编写脚本
bash
---
- hosts: appsrvs
remote_user: root
tasks:
- name: install package
yum: name={{ pkname1 }}
- name: install package
yum: name={{ pkname2 }}
(2)执行脚本
bash
[root@ansible145 ansible]# ansible-playbook -e 'pkname1=httpd pkname2=memcached' app.yml
(3)查看程序是否安装成功
(4)卸载程序
bash
[root@ansible145 ansible]# ansible appsrvs -m shell -a 'yum -y remove httpd memcached vsftpd'
3.在脚本内部给变量赋值
上面两个脚本都是在命令行对脚本中的变量进行赋值的,我们也可以在脚本内部给变量赋值。
(1)编写脚本
bash
---
- hosts: appsrvs
remote_user: root
vars:
- pkname1: httpd
- pkname2: vsftpd
tasks:
- name: install package
yum: name={{ pkname1 }}
- name: install package
yum: name={{ pkname2 }}
(2)执行脚本
bash
[root@ansible145 ansible]# ansible-playbook app.yml
(3)检查程序是否成功安装
(4)卸载程序
bash
[root@ansible145 ansible]# ansible appsrvs -m shell -a 'yum -y remove httpd vsftpd'
4.在主机清单中给脚本定义变量
bash
[root@ansible145 ansible]# vim /etc/ansible/hosts
bash
vim hostname.yml
---
- hosts: websrvs
remote_user: root
tasks:
- name: set hostname
hostname: name=www{{ http_port }}.test.com
执行脚本
bash
# 检查语法
[root@ansible145 ansible]# ansible-playbook -C hostname.yml
# 执行脚本
[root@ansible145 ansible]# ansible-playbook hostname.yml
# 查看websrvs主机名是否成功更改
[root@ansible145 ansible]# ansible websrvs -a 'hostname'
192.168.22.141 | CHANGED | rc=0 >>
www81.test.com
192.168.22.142 | CHANGED | rc=0 >>
www82.test.com
上面的修改主机名的脚本中,www{}test.com部分是公用的,也可以对其进行修改
修改/etc/ansible/hosts文件
修改脚本
bash
vim hostname.yml
---
- hosts: websrvs
remote_user: root
tasks:
- name: set hostname
hostname: name={{ nodename }}{{ http_port }}.{{ domainname }}
执行脚本后查看主机名,已经被成功修改
注意:如果在上述地方都设置后,在命令行对变量进行重新赋值,则命令行的优先级最高
bash
[root@ansible145 ansible]# ansible-playbook -e 'nodename=web domainname=example.com' hostname.yml
普通变量的优先级比分组的公共变量的优先级高