Ansible Playbooks 介绍 和 使用 二
handlers
接上一篇文章 Ansible Playbooks 介绍 和 使用 一 继续说明
用于当关注的资源发生变化时采取一定的操作。
notify
这个action
可用于在每个play的最后被处罚,这样可以避免多次有改变时每次都执行指定的操作,取而代之,尽在所有的变化发生完成后一次性执行指定的操作。在notify中列出的操作成为handler。
例如:
- name: template configuration file
template: src=template.j2 dest=/etc/foo.conf
notify:
- restart memcached
- restart apache
handler是task列表,这些task与前述task并没有本质上的不同。
handlers:
- name: restart memcached
service: name=memcached state=restarted
- name: restart apache
service: name=httpd state=restarted
playbook 案例 2 handlers
应用场景
在webservs组安装httpd服务,默认启动httpd监听的是
80
端口
步骤
- 创建一个配置安装httpd服务的playbook,并配置开机器启动等相关操作
- 执行httpd.yml
- 修改配置文件httpd.conf中的端口为8080
- 再次执行httpd的playbook文件
首先创建httpd.yml文件
[root@node01 ansible]# pwd
/etc/ansible
[root@node01 ansible]# cat httpd.yml
- hosts: webservs
remote_user: root
tasks:
- name: install httpd packge
yum: name=httpd state=present
- name: configuration file for httpd
copy: src=/etc/ansible/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
- name: start httpd service
service: name=httpd enabled=true state=started
创建配置文件目录,并拷贝httpd.conf
[root@node01 ansible]# pwd
/etc/ansible
[root@node01 ansible]# mkdir conf
[root@node01 ansible]# cp /etc/httpd/conf/httpd.conf conf/
[root@node01 ansible]# vim conf/httpd.conf
执行httpd.yuml的playbook
[root@node01 ansible]# ansible-playbook httpd.yml
PLAY [webservs] ***********************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [10.0.0.65]
TASK [install httpd packge] ***********************************************************************************************
changed: [10.0.0.65]
TASK [configuration file for httpd] ***************************************************************************************
ok: [10.0.0.65]
TASK [start httpd service] ************************************************************************************************
changed: [10.0.0.65]
PLAY RECAP ****************************************************************************************************************
10.0.0.65 : ok=4 changed=2 unreachable=0 failed=0
验证:
[root@node01 ansible]# ansible webservs -a 'rpm -qa httpd'
10.0.0.65 | CHANGED | rc=0 >>
httpd-2.4.6-80.el7.centos.1.x86_64
[root@node01 ansible]# ansible webservs -m shell -a 'netstat -lntup | grep 80'
10.0.0.65 | CHANGED | rc=0 >>
tcp6 0 0 :::80 :::* LISTEN 31354/httpd
修改ansible服务端下httpd.conf配置文件中的端口为8080,然后重新执行
[root@node01 ansible]# egrep '^Listen' conf/httpd.conf
Listen 8080
[root@node01 ansible]# ansible-playbook httpd.yml
PLAY [webservs] ***********************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [10.0.0.65]
TASK [install httpd packge] ***********************************************************************************************
ok: [10.0.0.65]
TASK [configuration file for httpd] ***************************************************************************************
changed: [10.0.0.65]
TASK [start httpd service] ************************************************************************************************
ok: [10.0.0.65]
PLAY RECAP ****************************************************************************************************************
10.0.0.65 : ok=4 changed=1 unreachable=0 failed=0
[root@node01 ansible]# ansible webservs -m shell -a 'netstat -lntup | grep httpd'
10.0.0.65 | CHANGED | rc=0 >>
tcp6 0 0 :::80 :::* LISTEN 31354/httpd
[root@node01 ansible]# ansible webservs -m shell -a 'egrep "^Listen" /etc/httpd/conf/httpd.conf'
10.0.0.65 | CHANGED | rc=0 >>
Listen 8080
最后可以看到,虽然远程主机的配置文件中的端口修改了,但实际监听的端口没有变,说明httpd没有重启
此时就需要用handlers,来监听当有类似于这样的配置文件操作变更的时候,就需要重启这样的操作,
下面修改httpd.yml中的内容
[root@node01 ansible]# cat httpd.yml
- hosts: webservs
remote_user: root
tasks:
- name: install httpd packge
yum: name=httpd state=present
- name: configuration file for httpd
copy: src=/etc/ansible/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: start httpd service
service: name=httpd enabled=true state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
再次把httpd.conf中的端口改成808,然后再次执行
[root@node01 ansible]# egrep '^Listen' conf/httpd.conf
Listen 808
[root@node01 ansible]# ansible-playbook httpd.yml
PLAY [webservs] ***********************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [10.0.0.65]
TASK [install httpd packge] ***********************************************************************************************
ok: [10.0.0.65]
TASK [configuration file for httpd] ***************************************************************************************
changed: [10.0.0.65]
TASK [start httpd service] ************************************************************************************************
ok: [10.0.0.65]
RUNNING HANDLER [restart httpd] *******************************************************************************************
changed: [10.0.0.65]
PLAY RECAP ****************************************************************************************************************
10.0.0.65 : ok=5 changed=2 unreachable=0 failed=0
[root@node01 ansible]# ansible webservs -m shell -a 'netstat -lntup | grep httpd'
10.0.0.65 | CHANGED | rc=0 >>
tcp6 0 0 :::808 :::* LISTEN 32212/httpd
最后可以看到,远程主机的httpd服务监听的端口已经变成了808。
vars 变量
在playbook中使用变量,可以直接在playbook中直接定义变量,也可以在其他模板中定义变量,在playbook文件中饮用
下面以httpd.yml为例,在文件中增加vars变量
[root@node01 ansible]# cat httpd.yml
- hosts: webservs
remote_user: root
vars:
- package: httpd
- service: httpd
tasks:
- name: install httpd package
yum: name={{ package }} state=present
- name: configuration file for httpd
copy: src=/etc/ansible/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: start httpd service
service: name={{ service }} enabled=true state=started
handlers:
- name: restart httpd
service: name={{ service }} state=restarted
从上面的定义可以看出,变量的引用是通过{{ }}
两个大括号来的
下面看下重新执行一下,看下效果
[root@node01 ansible]# ansible-playbook httpd.yml
PLAY [webservs] ***********************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [10.0.0.65]
TASK [install httpd package] **********************************************************************************************
ok: [10.0.0.65]
TASK [configuration file for httpd] ***************************************************************************************
ok: [10.0.0.65]
TASK [start httpd service] ************************************************************************************************
ok: [10.0.0.65]
PLAY RECAP ****************************************************************************************************************
10.0.0.65 : ok=4 changed=0 unreachable=0 failed=0
可以看到都是OK,说明变量引用成功了
setup facts 变量使用
playbook也可以直接引用facts中获取的远程主机信息的变量来使用
案例
首先来查看
[root@node01 ansible]# ansible webservs -m setup | head
10.0.0.65 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"10.0.0.65"
],
"ansible_all_ipv6_addresses": [
"fe80::20c:29ff:fe07:47f6"
],
"ansible_apparmor": {
"status": "disabled"
这里就使用变量:ansible_all_ipv4_addresses 来调用使用
[root@node01 ansible]# cat test.yml
- hosts: webservs
remote_user: root
tasks:
- name: copy file
copy: content="{{ ansible_all_ipv4_addresses }}" dest=/tmp/vars.ans
[root@node01 ansible]# ansible-playbook test.yml
PLAY [webservs] ***********************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [10.0.0.65]
TASK [copy file] **********************************************************************************************************
changed: [10.0.0.65]
PLAY RECAP ****************************************************************************************************************
10.0.0.65 : ok=2 changed=1 unreachable=0 failed=0
[root@node01 ansible]# ansible webservs -a 'cat /tmp/vars.ans'
10.0.0.65 | CHANGED | rc=0 >>
["10.0.0.65"]
从上面最后输出的结果来看,变量的调用成功。
inventory 中定义变量
同样也可以在inventory中定义变量,然后在playbook中引用
案例
修改inventory文件hosts
[root@node01 ansible]# cat hosts
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
# - Comments begin with the '#' character
# - Blank lines are ignored
# - Groups of hosts are delimited by [header] elements
# - You can enter hostnames or ip addresses
# - A hostname/ip can be a member of multiple groups
[webservs]
10.0.0.65 testvars="10.0.0.65"
[dbservs]
10.0.0.66 testvars="10.0.0.66"
上面给个主机定义了 testvars变量
下面来引用,修改playbook文件
[root@node01 ansible]# cat test.yml
- hosts: webservs, dbservs
remote_user: root
tasks:
- name: copy file
copy: content="{{ ansible_all_ipv4_addresses }}\n{{ testvars }}" dest=/tmp/vars.ans
[root@node01 ansible]# ansible-playbook test.yml
PLAY [webservs, dbservs] **************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [10.0.0.65]
ok: [10.0.0.66]
TASK [copy file] **********************************************************************************************************
changed: [10.0.0.66]
changed: [10.0.0.65]
PLAY RECAP ****************************************************************************************************************
10.0.0.65 : ok=2 changed=1 unreachable=0 failed=0
10.0.0.66 : ok=2 changed=1 unreachable=0 failed=0
[root@node01 ansible]# ansible all -a 'cat /tmp/vars.ans'
10.0.0.66 | CHANGED | rc=0 >>
[u'10.0.0.66']
10.0.0.66
10.0.0.65 | CHANGED | rc=0 >>
[u'10.0.0.65']
10.0.0.65
从上面最后的输出结果可以看出,引用成功。
条件测试
如果需要根据变量、facts或此前任务的执行结果来为某task执行与否的前提时要用到条件测试。
when 语句
在task后面添加when子句即可使用条件测试;when语句支持jinja2表达式语法,例如:
tasks:
- name: "shutdown Debian flavored systems"
command: /sbin/shutdown -h now
when: ansible_os_family == "Debian"
when 语句中还可以使用jinja2的太多filter,例如要忽略此前某语句的错误并基于其结果(failed或者sucess)运行后面指定的语句,可使用类似如下的形式:
tasks:
- command: /bin/false
register: result
ignore_errors: True
- command: /bin/something
when: result | failed
- command: /bin/something_else
when: result | success
- command: /bin/still/something_else
when: result | skipped
此外 when语句中还可以使用facts或playbook中定义的变量。
案例
判断当主机名为node02的时候,添加一个node02的新用户,否则其他机器不添加
首先使用ansible查看所有主机的主机名:
[root@node01 ansible]# ansible all -m setup | grep ansible_fqdn
"ansible_fqdn": "node02",
"ansible_fqdn": "node03",
定义和执行playbook文件
[root@node01 ansible]# cat cond.yml
- hosts: all
remote_user: root
vars:
- username: node02
tasks:
- name: create {{ username }} user
user: name={{ username }}
when: ansible_fqdn == "node02"
[root@node01 ansible]# ansible-playbook cond.yml
PLAY [all] ****************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [10.0.0.65]
ok: [10.0.0.66]
TASK [create node02 user] *************************************************************************************************
skipping: [10.0.0.66]
changed: [10.0.0.65]
PLAY RECAP ****************************************************************************************************************
10.0.0.65 : ok=2 changed=1 unreachable=0 failed=0
10.0.0.66 : ok=1 changed=0 unreachable=0 failed=0
[root@node01 ansible]# ansible all -a 'grep node02 /etc/passwd'
10.0.0.66 | FAILED | rc=1 >>
non-zero return code
10.0.0.65 | CHANGED | rc=0 >>
node02:x:1002:1002::/home/node02:/bin/bash
从上最后执行的结果来看,when的条件测试判断成功。
迭代
当有需要重复性执行的任务时,可以使用迭代机制,其使用格式为将需要迭代的内容定义为item变量,并通过with_items语句来指明迭代的元素列表即可。例如:
- name: add several users
user: name={{ item }} state=present groups=wheel
with_items:
- testuser1
- testuser2
事实上,with_items中可以使用元素还可以为hashes,例如:
- name: add several users
user: name={{ item }} state=present groups={{ item.groups }}
with_items:
- { name: 'testuser1', group: 'wheel' }
- { name: 'testuser2', group: 'root' }
templates 模板
在某个服务的配置文件中,预先定义好需要变更的变量,然后在执行playbook的时候,向定义好的配置文件中传入参数,可灵活修改;
如http服务,一个http监听80端口,另一个监听8080端口,则可以使用
案例
以httpd的配置文件为例,对其进行修改
[root@node01 ansible]# pwd
/etc/ansible
[root@node01 ansible]# mkdir templates
[root@node01 ansible]# cp /etc/httpd/conf/httpd.conf templates/httpd.conf.j2
[root@node01 ansible]# egrep "^Listen|^ServerName" templates/httpd.conf.j2
Listen {{ http_port }}
ServerName {{ ansible_fqdn }}
然后修改inventory文件中增加变量
[root@node01 ansible]# cat /etc/ansible/hosts
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
# - Comments begin with the '#' character
# - Blank lines are ignored
# - Groups of hosts are delimited by [header] elements
# - You can enter hostnames or ip addresses
# - A hostname/ip can be a member of multiple groups
[webservs]
10.0.0.65 http_port=80
[dbservs]
10.0.0.66 http_port=8080
定义playbook文件
[root@node01 ansible]# cat apache.yml
- hosts: webservs dbservs
remote_user: root
vars:
- package: httpd
- service: httpd
tasks:
- name: install httpd package
yum: name={{ package }} state=present
- name: configuration file for httpd
template: src=/etc/ansible/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: start httpd service
service: name={{ service}} enabled=true state=started
handlers:
- name: restart httpd
service: name={{ service }} state=restarted
执行
[root@node01 ansible]# ansible-playbook apache.yml
PLAY [webservs dbservs] ***************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [10.0.0.66]
ok: [10.0.0.65]
TASK [install httpd package] **********************************************************************************************
ok: [10.0.0.65]
ok: [10.0.0.66]
TASK [configuration file for httpd] ***************************************************************************************
changed: [10.0.0.65]
changed: [10.0.0.66]
TASK [start httpd service] ************************************************************************************************
changed: [10.0.0.65]
changed: [10.0.0.66]
RUNNING HANDLER [restart httpd] *******************************************************************************************
changed: [10.0.0.66]
changed: [10.0.0.65]
PLAY RECAP ****************************************************************************************************************
10.0.0.65 : ok=5 changed=3 unreachable=0 failed=0
10.0.0.66 : ok=5 changed=3 unreachable=0 failed=0
[root@node01 ansible]# ansible all -m shell -a 'egrep "^Listen|^ServerName" /etc/httpd/conf/httpd.conf'
10.0.0.65 | CHANGED | rc=0 >>
Listen 80
ServerName node02
10.0.0.66 | CHANGED | rc=0 >>
Listen 8080
ServerName node03
[root@node01 ansible]# ansible all -m shell -a 'netstat -lntup | grep httpd'
10.0.0.65 | CHANGED | rc=0 >>
tcp6 0 0 :::80 :::* LISTEN 34619/httpd
10.0.0.66 | CHANGED | rc=0 >>
tcp6 0 0 :::8080 :::* LISTEN 29274/httpd
从上个最后的执行结果可以看出,template中定义的端口已经生效了。
tags
当一个playbook需要运行多次是,可以在playbook文件中的一个tasks中,定义一个tags,在第二次运行时,可以指定tags,只运行其中一个tasks。
案例
重新定义playbook文件
[root@node01 ansible]# cat apache.yml
- hosts: webservs dbservs
remote_user: root
vars:
- package: httpd
- service: httpd
tasks:
- name: install httpd package
yum: name={{ package }} state=present
- name: configuration file for httpd
template: src=/etc/ansible/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
tags:
- conf
notify:
- restart httpd
- name: start httpd service
service: name={{ service}} enabled=true state=started
handlers:
- name: restart httpd
service: name={{ service }} state=restarted
[root@node01 ansible]# cat hosts
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
# - Comments begin with the '#' character
# - Blank lines are ignored
# - Groups of hosts are delimited by [header] elements
# - You can enter hostnames or ip addresses
# - A hostname/ip can be a member of multiple groups
[webservs]
10.0.0.65 http_port=808
[dbservs]
10.0.0.66 http_port=800
运行:
[root@node01 ansible]# ansible-playbook apache.yml --tags="conf"
PLAY [webservs dbservs] ***************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [10.0.0.66]
ok: [10.0.0.65]
TASK [configuration file for httpd] ***************************************************************************************
changed: [10.0.0.65]
changed: [10.0.0.66]
RUNNING HANDLER [restart httpd] *******************************************************************************************
changed: [10.0.0.66]
changed: [10.0.0.65]
PLAY RECAP ****************************************************************************************************************
10.0.0.65 : ok=3 changed=2 unreachable=0 failed=0
10.0.0.66 : ok=3 changed=2 unreachable=0 failed=0
从上面运行的结果来看,安装和启动没有运行,只运行了配置修改和重启。
说明
特殊的 tags: always
表示无论指定或者不指定,都会运行对应的tasks
Ansible Playbooks 介绍 和 使用 二的更多相关文章
- Ansible Playbooks 介绍 和 使用 一
目录 Ansible Playbooks Playbooks 组成部分: YAML 介绍 YAML 语法 Ansible 基础元素 变量 facts registre 通过命令传递变量 通过roles ...
- ansible运维工具(二)
ansible playbook(二) 运行palybook时 要使用ansible-playbook命令 palybook执行任务的顺序是,在第一个主机上完成第一个任务,然后在第二个主机上完成第一个 ...
- Ansible简单介绍(一)
一 :ansible简单介绍 此名取自 Ansible 作者最喜爱的<安德的游戏> 小说,而这部小说更被后人改编成电影 -<战争游戏>. 官网地址:https://www.an ...
- 第二十七章 ansible变量介绍
一.ansible变量介绍 1.概念 变量提供了便捷的方式来管理Ansible playbook的每一个项目中的动态值,比如nginx-1.6.3这个软件包的版本,在其它地方或许会反复使用,那么如果讲 ...
- 3、Ansible playbooks(Hosts、Users、tasks、handlers、变量、条件测试(when、迭代)、templates)
Ansible playbooks playbook是由一个或多个“play”组成的列表.play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色.从根本上来讲 ...
- 从Client应用场景介绍IdentityServer4(二)
原文:从Client应用场景介绍IdentityServer4(二) 本节介绍Client的ClientCredentials客户端模式,先看下画的草图: 一.在Server上添加动态新增Client ...
- Ansible Playbooks入门介绍
1.目录结构 2.详细目录 3.主任务文件main.yaml 主任务文件main.yaml - name: print server name and user to remote testbox # ...
- ansible的介绍和一些基本模块介绍
必须保证ansible工作站与各个node实现无密码ssh登入 ①:192.168.1.100 - 在你本地的工作站或服务器上安装 Ansible. ②:文件服务器1到代理服务器3 - 使用 19 ...
- ansible模块介绍之ios_command
一.模块简介 ios_command此模块将任意命令发送到ios节点并返回设备读取的结果 此模块不支持在配置模式下使用,即只支持在用户模式>和特权模式#下使用 官方文档地址:https://do ...
随机推荐
- ArcGIS Engine空间分析之缓冲区分析的实现
缓冲分析(BufferAnalysis)的结果是一个面状要素——即缓冲要素,点状要素.线状要素和面状要素,被缓冲分析功能处理过之后,它们的周围产生一个缓冲区域,该区域即新产生的面状要素. 在缓冲方向上 ...
- 20190723_C的三个小实现
1. 有一个字符串开头或结尾含有n个空格(“ abcdefgdddd ”),欲去掉前后的空格,返回一个新的字符串.a) 要求1:请自己定义一个接口(函数),并实现功能:b) 要求2:编写测试 ...
- Jsp的四大域对象
Jsp Jsp的四大域对象 作用范围 特殊之处 pageContext 当前jsp页面,当转发就失效 可以获取其他域对象中的值 request 一次请求,转发公用request,重 ...
- Spring 动态代理 之 but was actually of type 'com.sun.proxy.$Proxy14 Exception
今天在写Spring的引介代理的时候,报了一个错: Exception in thread "main" org.springframework.beans.factory.Bea ...
- 查找一个卷对应的osd
1.首先找到卷的id: 2.使用rados命令找到卷上面的对象数据: 3.通过ceph osd map命令可以查询到对象对应的pgid及pg对应的osd:
- NOIP模拟 40
考得更嘛也不是了. 不过如果不犯任何低错的话.. T1 我神奇地想要缩减码量 比如想把尽量多的$b[i]-1$省掉 于是求$b[i]$的时候先减了个一 本来是正的 减完就忘了他应该是非负的了 于是线段 ...
- kettle数据同步的5中方案
数据同步:当数据源发生改变时,其他相关数据也跟着发展变化.根据需求不同可采取以下方案.1.触发器:在数据库建立增删改的触发器.触发器将变更放到一张临时表里.oracle同步cdc优点:实时同步缺点:影 ...
- C语言程序设计100例之(4):水仙花数
例4 水仙花数 题目描述 一个三位整数(100-999),若各位数的立方和等于该数自身,则称其为“水仙花数”(如:153=13+53+33),找出所有的这种数. 输入格式 没有输入 输出格式 若 ...
- inux下vi命令大全
分类: LINUX 进入vi的命令 vi filename :打开或新建文件,并将光标置于第一行首 vi +n filename :打开文件,并将光标置于第n行首 vi + filename :打开文 ...
- Project Euler 59: XOR decryption
计算机上的每个字母都对应一个独特的编号,普遍接受的标准是ASCII(美国信息交换标准代码).例如,大写字母的A的ASCII码是65,星号(*)的ASCII码是42,而小写字母k的代码是107. 一种现 ...