ansible-playbook是ansible中实现自动化最常用的命令之一,能够完成大量复杂的批量远程部署。其工作机制是:通过读叏预先编写好的 playbook 文件实现批量管理。要实现的功能与命令 ansible 一样。类似于shell脚本,或mysql中的存储过程。
ansible-playbook在语法格式上使用的是yml语法格式,文件类型为user.yml
playbook由 YAML 语言编写,遵循 YAML 标准
– 在同一行中,#后的内容表示注释
– 同一个列表中的元素应该保持相同的缩迚
– playbook 由一个戒多个 play 组成
– play 中 hosts,variables,roles,tasks 等对象的表示方法都是键值中间以 ": " 分隔表示
– YAML 还有一个小的怪癖. 所有的 YAML 文件开始行都应该是 ---. 这是 YAML 格式的一部分, 表明一个文件的开始
Playbook构成
– Target: 定义将要执行 playbook 的进程主机组
– Variable: 定义 playbook 运行时需要使用的变量
– Tasks: 定义将要在进程主机上执行的任务列表
– Handler: 定义 task 执行完成以后需要调用的任务
playbook具体操作:
对s1801组进行批量装apache服务:
---
- hosts: web
remote_user: root
tasks:
- name: install the latest version of Apache //注释此次安装内容
yum: //yum安装apache
name: httpd
state: installed
- lineinfile: //将配置文件中端口替换为8080
path: /etc/httpd/conf/httpd.conf
regexp: '^Listen ' //匹配的对象
insertafter: '^#Listen '
line: 'Listen 8080' //更改为的对象
- lineinfile:
path: /etc/httpd/conf/httpd.conf //更改ServerName
regexp: '^#ServerName'
line: 'ServerName www.test01.com'
- copy: //将设置好的测试网页拷入对应位置设置权限
src: /root/index.html
dest: /var/www/html/index.html
owner: apache
group: apache
mode: 0644
- service: //启动服务
name: httpd
state: started
enabled: yes
playbook中的变量设置
使用playbook增加变量vars: user=nb,引用为:”{{user}}”
注意:user中写: Password: 12345 --->执行中会直接在/etc/shadow中写明码12345密码,会造成密码错误,故需要写加密的密码。有两种方式解决问题:
1.在本机上添加用户输入密码,然后将生成的加密密码写入playbook
2.在playbook中写入过滤器: '密码' | password_hash(‘加密算法’)
---
- hosts: other
remote_user: root
vars:
un: lixin
tasks:
- user:
name: "{{un}}"
password: "{{'123456'|password_hash('sha512')}}"
- shell: chage -d 0 "{{un}}"
过滤器:
变量可以通过 过滤器 修改。过滤器与变量用管道符号( | )分割,并且也 可以用圆括号传递可选参数。多个过滤器可以链式调用,前一个过滤器的输出会被作为 后一个过滤器的输入。
-password_hash('加密算法')
-ignore_errors: True (忽略上一步的错误,使$?=0) 在对上一语句进行判断时,也可以| true执行
Handlers与notify:
Handlers类似于函数:可以使一个handlers后面的所有动作重复执行n次在每个标记的nodify上面进行标记,在所有的tasks的命令执行完成后才执行, notify 调用的是 handler 段 name 定义的串,必须一致,否则达不到触发的效果 – 多个 task
---
- hosts: 192.168.1.16
remote_user: root
tasks:
- name: config httpd.conf
notify: //nodify标签stop
- stop httpd
copy: src=/root/playbook/httpd.conf
dest=/etc/httpd/conf/httpd.conf
notify: //nodify标签start
- start httpd
copy: src=/root/index.html
dest=/var/www/html
notify: //nodify标签restart
- restart httpd
handlers:
- name: restart httpd
service: name=httpd state=restarted
- name: start httpd
service: name=httpd state=started
- name: stop httpd
service: name=httpd state=stoped
触发同一个 notify 的时候,同一个服务叧会触发一次(如一个httpd的重启,若都写了这个那么最后就执行最后一次,等价于最后重启一次,但往往handlers中含有多个不同的触发条件,可以大大简化逻辑判断的时间) – notify 可以触发多个条件,在生产环境中往往涉及到某一个配置文件的改变要重现若干服务的场景, handler 用到这里非常适合– 结合 vars 可以写出非常普适的服务管理脚本
when
• 某些时候我们可能需要在满足特定的条件后在触収某一项操作,在特定的条件下需要提前判断上个命令的执行状态,这个时候我们就需要进行条件判断,when 正是解决这个问题的最佳选择,进程中的系统变量 facts 变量作为when 的条件,这些 facts 我们可以通过 setup 模块
---
- name: Install VIM
hosts: all
tasks:
- name: Install VIM via yum
yum: name=vim-enhanced state=installed
when: ansible_os_family == "RedHat"
- name: Install VIM via apt
apt: name=vim state=installed
when: ansible_os_family == "Debian"
register
– 有时候我们可能还需要更复杂的例子,比如判断前一个命令的执行结果,根据结果处理后面的操作,这时候我们就需要 register 模块来保存前一个命令的返回状态,在后面进行调用(常与when一起使用)
举例:针对运行命令结果的返回值做判定当系统负载超过一定值的时候做特殊处理:
---
- hosts: 192.168.1.16
remote_user: root
tasks:
- shell: uptime |awk '{printf("%f\n",$(NF-2))}' //显示cpu负载值
register: result //将上面的导入到resault中
- shell: touch /tmp/isreboot
when: result.stdout|float > 0.5 //如果result中的值大于0.5则输出信息
with_items
with_items 是 playbook 标准循环,最常用到的就是它,with_items 可以用于迭代一个列表或字典,通过{{ item }}获取每次迭代的值
循环过程:A,B,C |1,2,3 --------->A1,B2,C3
---
- hosts: other
remote_user: root
tasks:
- user:
name: "{{item.name}}" --------(要求格式,类似于引用数组)
group: "{{item.group}}" ---------(通上)
password: "{{'123456'|password_hash('sha512')}}"
with_items: ------(一个数组列表)
- {name: "nb", group: "users" }
- {name: "dd", group: "mail" }
- {name: "jj", group: "root" }
- {name: "son", group: "wheel" }
with_nested 嵌套循环:
循环过程:A,B,C | 1,2,3 ------> A1,A2,A3,B1,B2,B3,C1,C2,C3
---
- hosts: 192.168.1.16
remote_user: root
vars:
un: [a, b, c]
id: [1, 2, 3]
tasks:
- name: add users
shell: echo {{item}}
with_nested:
- "{{un}}"
- "{{id}}"
tags
给指定的任务定义一个调用标识;
vars:
soft: httpd
tasks:
- name: install {{soft}}
yum: name={{soft}}
- name: config httpd.conf
copy: src=/root/playbook/httpd.conf
dest=/etc/httpd/conf/httpd.conf
- name: config services
service: enabled=yes state=restarted name={{soft}}
tags: restartweb
• 调用方式
ansible-playbook i.yml --tags=restartweb
include and role
• 调用方式
ansible-playbook i.yml --tags=restartweb我们在编写 playbook 的时候随着项目越来越大,playbook 也越来越复杂,修改起来也越来越麻烦。这时候可以把一些 play、task 或handler 放到其他文件中,然后通过include指令包含进行是一个不错的选择
Ansible检测方法
Playbook报错时是执行到哪一步是出错,不一定就是那个位置出错
调试方法
– 检测语法
ansible-playbook --syntax-check playbook.yaml
– 测试运行
ansible-playbook -C playbook.yaml
有些测试运行报错为正常(有些服务并没有实际执行起来)需要时别出真假错误
执行前面,先查看目前的情况:
– 显示收到影响到主机 --list-hosts
– 显示工作的 task --list-tasks
– 显示将要运行的 tag --list-tags
Debug
执行一次后会打包一个文件,可以保存一个完整的运行信息
---
- hosts: 192.168.1.16
remote_user: root
tasks:
- shell: uptime |awk '{printf("%f\n",$(NF-2))}'
register: result
- shell: touch /tmp/isreboot
when: result.stdout|float > 0.5 //当负载超过0.5时,将debug信息写入result
- name: Show debug info
debug: var=result //查看result中的内容,显示到命令行中