playbook是一个不同于ansible命令行方式的模式,其功能更强大灵活。简单地说,playbook是一个非常适合部署复杂应用程序的基础,它可以定制部署,可以按照指定的操作有序执行,支持同步和异步方式。playbook是通过yaml或者yml格式进行描述定义的。
playbook核心元素
(1)Hosts 执行远程主机列表
(2)Tasks 任务集
(3)Varniables 内置变量或自定义变量在playbook中调用
(4)Templates 模板,可替代模板文件中的变量并实现一些简单逻辑的文件
(5)Handlers和notify 这2个需要结合使用,由特定条件触发的操作,满足条件方才执行
(6)tags 标签,指定某条任务执行,用于运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然非常长。此时,如果确定没有变化,可以通过tags跳过一些代码片段
运行playbook
运行playbook的方式
ansible-playbook <filename.yml> ...[options]
|
常见选项
–check 只检查可能会发生的改变,但不真正执行操作
–list 列出运行任务的主机
–limit 只针对主机列表中的主机执行
-v 显示过程 -vv -vvv更详细
示例
ansible-playbook file.yml --check ansible-playbook file.yml ansible-playbook file.yml --limit test
|
写一个playbook
--- - hosts: test remote_user: root tasks: - name: install httpd package yum: name=httpd tags: inshttpd - name: copy conf file copy: src=/home/httpd.conf dest=/etc/httpd/conf backup=yes - name: start service service: name=httpd state=started enabled=yes tags: shttpd
ansible-playbook ansible-playbook.yml --check
ansible-playbook ansible-playbook.yml
ansible-playbook -t inshttpd ansible-playbook.yml
|
现在有一种场景:有些服务,我们需要修改它的配置文件,但是它的服务一直是开启状态。当我们修改了配置文件,再次执行这个playbook,那么就会产生一个问题,当进行启动服务的任务时,ansible会因为这个服务已经运行了,而不去重新执行这个任务,就会导致修改的配置没有重启服务而无法生效。handlers和notify就是解决这种场景的方法。
--- - hosts: test remote_user: root tasks: - name: install httpd package yum: name=httpd tags: inshttpd - name: copy conf file copy: src=/home/httpd.conf dest=/etc/httpd/conf backup=yes notify: restart service - name: start service service: name=httpd state=started enabled=yes tags: shttpd handlers: - name: restart service service: name=httpd state=restarted
|
playbook中变量的使用
变量名:仅能由字母、数字、下划线组成,且只能以字母开头
变量来源:
(1)ansible setup facts远程主机的所有变量都可以直接调用
(2)在/etc/ansible/hosts中定义
1)普通变量:主机组中主机单独定义,优先级高于公共变量
192.168.136.128 http_port=80
|
2)公共变量:针对主机组中所有主机统一定义变量
[test] 192.168.136.128 http_port=80 [test:vars] nodename=www
|
(3)通过命令行指定变量(参数-e),优先级最高
(4)在playbook中定义
vars:
- var1: value1
- var2: value2
(5)在role中定义
使用变量文件
cat vars.yml var1: httpd var2: nginx
cat ansible-playbook.yml - hosts: test remote_user: root vars_files: - vars.yml tasks: - name: create httpd log file: name=/home/{{var1}}.log state=touch - name: create nginx log file: name=/home/{{var2}}.log state=touch
|
templates
(1)文本文件,嵌套有脚本(使用模板编程语言编写)
(2)Jinja2语言,使用字面量,有下面形式
字符串:使用单引号或双引号
数字:整数,浮点数
列表:[item1,item2,…]
元祖:(item1,item2,…)
字典:{key1:value1,key2:value2,…}
布尔型:true/false
(3)算术运算:+,-,*,/,//,%,**
(4)比较操作:==,!=,>,>=,<,<=
(5)逻辑运算:and,or,not
(6)流表达式:For If When
- hosts: test remote_user: root tasks: - name: install yum: name=nginx - name: copy template template: src=/home/nginx.conf.j2 dest=/etc/nginx/nginx.conf - name: start service service: name=nginx state=started enabled=yes
|
when
条件测试:如果需要根据变量、facts或者此前任务的执行结果来做某task执行与否的前提时要用条件测试,通过when语句实现,在task中使用,jinja2的语法格式
tasks: - name: "shutdown RedHat flavored systems" command: /sbin/shutdown -h now when: ansible_os_family == "RedHat"
|
with_items
迭代:当有需要重复性执行的任务时,可以使用迭代机制
对迭代项的引用,固定变量名为“item”
要在task中使用with_items给定要迭代的元素列表
- hosts: test remote_user: root tasks: - name: create some files file: name=/home/{{ item }} state=touch with_items: - file1 - file2 - file3
|
with_items还可以做到迭代嵌套自变量的情况
现在有一种情景:(1)创建user1、user2、user3三个用户(2)创建group1、group2、group3(3)user1所属组是group1,user2所属组是group2,user3所属组是group3
- hosts: test remote_user: root tasks: - name: add some groups group: name={{ item }} state=present with_items: - group1 - group2 - group3 - name: add some users user: name={{ item.name }} group={{ item.group }} state=present with_items: - {name: 'user1', group: 'group1'} - {name: 'user2', group: 'group2'} - {name: 'user3', group: 'group3'}
|
For
cat ansible-playbook.yml - hosts: test remote_user: root vars: ports: - 81 - 82 - 83 tasks: - name: copy template template: src=/home/nginx.conf.j2 dest=/etc/nginx/nginx.conf
cat nginx.conf.j2 {% for port in ports %} server{ listen: {{ port }} } {% endfor %}
|