ansible playbook 编写
一、Jinja2 模板简介
Jinja2 是什么
Jinja2 是基于 Python 的模板引擎, 蕴含变量和表达式两局部, 两者在模板求值时会被替换为值, 模板中还有标签, 管制模板的逻辑
为什么要学习 Jinja2 模板
因为 playbook 的模板应用 Python 的 Jinja2 模块来解决
Jinja2 模版的根本语法
- 模板的表达式都是蕴含在他要分隔符 ”{{}}” 内的
- 管制的语句都是蕴含在分隔符 ”{% %}” 内的
- 模板反对正文, 都是蕴含在分隔符 '{# #}’ 内, 反对块正文
- 调用变量
{{varname}} - 计算
{{2+2}} - 判断
{{1 in {{1,2,3}} - Jinja2 模版管制语句
{% if name == '诗仙' %}
李白
{% elif name == '诗圣' %}
杜甫
{% elif name == '诗魔' %}
白居易
{% else %}
李贺
{% endif %}
Jinja2 过滤器
变量能够通过过滤器批改, 过滤器与变量用管道符号 (|) 宰割, 也能够用圆括号传递可选参数, 多个过滤器能够链式调用, 前一个过滤器的输入会被作业后一个过滤器的输出
例如:
加密一个字符串:{{‘astr’|password_hash(‘sha512’)}}
二、playbook 简介
playbook 是什么
playbook 是 ansible 用于配置, 部署和治理托管主机剧本, 通过 playbook 的详细描述, 执行其中一系列 tasks, 能够让远端主机达到预期的状态
也能够说 playbook 字面意思即剧本, 事实中由演员按剧本表演, 在 ansible 中由计算机进行装置, 部署利用, 提供对外服务, 以及组织计算机解决各种各样的事件
为什么要应用 palybook
- 执行一些简略的工作, 应用 ad-hoc 命令能够不便的解决问题, 但有时一个设施过于简单时, 执行 ad-hoc 命令是不适合的, 最好应用 playbook
- playbook 能够重复应用编写的代码, 能够放到不同机器下面, 像函数一样, 最大化的利用代码, 在应用 ansible 的过程中, 解决的大部分操作都是在编写 playbook
playbook 语法根底(1)
- playbook 由 YAML 语文编写, 遵循 YAML 规范
- 在同一行中,# 之后的内容示意正文
- 同一个列表中元素应该放弃雷同缩进
- playbook 由一个或多个 play 组成
- play 中 host,variables,roles,tasks 等对角示意办法都是键值两头以 ”: “ 分隔示意
- YAML 还有一个小的怪癖, 它的文件开始行都是以 —, 这是 YAML 格局的一部分, 表明一个文件的开始
playbook 形成
- hosts: 定义交要执行 playbook 的近程主机级
- vars: 定义 playbook 运行时须要应用的变量
- tasks: 定义将要近程主机上执行的工作列表
- handlers: 定义 task 执行实现当前须要调用的工作
playbook 执行后果
应用 ansible-playbook 运行 playbook 文件, 输入内容为 JSON 格局, 由不同色彩组成便于辨认
- 绿色代表执行胜利
- 黄色 代表零碎状态产生扭转
- 红色代表执行失败
ansible 具备幂等性,幂等性可能保障咱们反复的执行一项操作时,失去的后果是雷同的,咱们再来回顾一下幂等性的概念
“ 幂等性 ” 是什么意思呢?举个例子,你想把一个文件拷贝到指标主机的某个目录上,然而你不确定此目录中是否曾经存在此文件,当你应用 ansible 实现这项工作时,就非常简单了,因为如果指标主机的对应目录中曾经存在此文件,那么 ansible 则不会进行任何操作,如果指标主机的对应目录中并不存在此文件,ansible 就会将文件拷贝到对应目录中,说白了,ansible 是 ” 以后果为导向的 ”,咱们指定了一个 ” 指标状态 ”,ansible 会主动判断,” 以后状态 ” 是否与 ” 指标状态 ” 统一,如果统一,则不进行任何操作,如果不统一,那么就将 ” 以后状态 ” 变成 ” 指标状态 ”,这就是 ” 幂等性 ”,” 幂等性 ” 能够保障咱们反复的执行同一项操作时,失去的后果是一样的。
有了幂等性的概念下面显示色彩代表的不同后果就比拟好了解了
- 绿色 代表执行胜利 后果曾经和指定 ” 指标状态 ” 统一不须要批改
- 黄色 执行胜利, 零碎状态产生扭转, 批改过 ” 指标状态 ”
- 红色代表执行失败
三、playbook 编写
应用 ping 模块编写 第一个 playbook
[root@ansible default]# cat ping.yml
--- #第一行, 示意开始
- hosts: all #近程主机, 多个能够用逗号孙隔开
remote_user: root #近程执行的用户名
tasks:
- name: ping test #工作名称, 你也能够了解为备注信息, 会在执行中显示, 不便浏览
ping: #模块名 ping
[root@ansible default]# ansible-playbook ping.yml -f 5 #-f 并发过程数量, 默认是 5
PLAY [all] ******************************************************************************************
TASK [Gathering Facts] ******************************************************************************
ok: [cache]
ok: [web1]
ok: [web2]
ok: [db2]
ok: [db1]
TASK [ping test] ************************************************************************************
ok: [cache]
ok: [web1]
ok: [web2]
ok: [db1]
ok: [db2]
PLAY RECAP ******************************************************************************************
cache : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
db1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
db2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
playbook 语法根底(2)
- tasks
命令的汇合
每一个 play 蕴含一个 task 列表(工作列表)
一个 task 在其所对应的所有主机上(通过 hosts pattern 匹配的所有主机) 执行结束之后, 下一个 task 才执行 - hosts
主机的汇合
定义要执行的主机
案例 1:
实现 给 web 主机增加用户 james
设置默认明码 123456, 并把 james 用户增加到 users 组
[root@ansible default]# cat user.yml
---
- hosts: web
remote_user: root
tasks:
- name: Add the user 'james'
user:
name: james
groups: users
- name: set passwd
shell: echo 123456|passwd --stdin james
[root@ansible default]# ansible-playbook user.yml
PLAY [web] ******************************************************************************************
TASK [Gathering Facts] ******************************************************************************
ok: [web1]
ok: [web2]
TASK [Add the user 'james'] *************************************************************************
changed: [web1]
changed: [web2]
TASK [set passwd] ***********************************************************************************
changed: [web2]
changed: [web1]
PLAY RECAP ******************************************************************************************
web1 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web2 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0
案例 2:
要求:
1. 所以 web 主机装置 Apache
2. 批改配置文件的监听端口为 8080
3. 设置默认页面 hello world
4. 启动服务
5. 设置开机自启
1)先在本面筹备默认拜访
[root@ansible default]# cat /root/index.htm
hello world
2)编号 playbook
[root@ansible default]# cat http.yml
---
- hosts: web
remote_user: root
tasks:
- name: install one specific version of Apache //tasks01. 装置
yum:
name: httpd
state: installed
- lineinfile: //tasks02. 批改监听端口
path: /etc/httpd/conf/httpd.conf
regexp: '^Listen'
line: 'Listen 8080'
- copy: //tasks03 替换主页 index.html
src: /root/index.html
dest: /var/www/html/index.html
- service: //tasks04. 开启服务
name: httpd
enabled: yes
state: restarted
[root@ansible default]# ansible-playbook http.yml
PLAY [web] ***********************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************
ok: [web1]
ok: [web2]
TASK [install one specific version of Apache] ************************************************************************************
changed: [web2]
changed: [web1]
TASK [lineinfile] ****************************************************************************************************************
changed: [web1]
changed: [web2]
TASK [copy] **********************************************************************************************************************
changed: [web2]
changed: [web1]
TASK [service] *******************************************************************************************************************
changed: [web2]
changed: [web1]
PLAY RECAP ***********************************************************************************************************************
web1 : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web2 : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible default]# curl web1:8080 // 测试
holle world
四、playbook 进阶
4.1 变量
案例 3:**
要求: 增加用户 应用变量 username 代替
给 web 主机增加用户 james2, 设置默认明码 123456
[root@ansible default]# cat user2.yml
---
- hosts: web
remote_user: root
vars:
username: james2
tasks:
-
name: Add the user "{{username}}"
user:
name: "{{username}}"
-
shell: echo 123456|passwd --stdin "{{username}}"
[root@ansible default]# ansible-playbook user2.yml
PLAY [web] ************************
......
用户设明码
作完以上的试验你必定曾经发现为什么不必 user 模块间接设置明码, 而且用 shell 模块独自设置, 这是因为 user 模块是把 Password 字符串间接写入 shadow, 并没有扭转, 而 Linux 的 shadow 明码是通过加密的, 所以明文明码不能间接应用
解决方案
- 应用变量过滤器 password_hash
{{‘urpassword’|password_hash(‘sha512’)}}
最初的 playbook 如下
[root@ansible default]# cat user3.yml
---
- hosts: web
remote_user: root
vars:
username: james2
tasks:
- name: Add the user "{{username}}"
user:
name: "{{username}}"
group: root
password: "{{'123qqq...A'|password_hash('sha512')}}"
变量参数
-e 传递变量或文件参数
-e @文件
文件的格局必须是 YAML 或 JSON 格局
[root@ansible default]# ansible-playbook user3.yml -e username=james4
PLAY [web] *******************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [web2]
ok: [web1]
TASK [Add the user "james4"] *************************************************************************
changed: [web2]
changed: [web1]
PLAY RECAP *******************************************************************************************
web1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0
web2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0
[root@ansible default]# ssh web1 id james4
uid=1007(james4) gid=0(root) 组 =0(root)
[root@ansible default]# cat username.yml
---
username:
james5
[root@ansible default]# ansible-playbook user3.yml -e @username.yml
PLAY [web] ******************************************************************************************
TASK [Gathering Facts] ******************************************************************************
ok: [web1]
ok: [web2]
TASK [Add the user "james5"] ************************************************************************
changed: [web2]
changed: [web1]
PLAY RECAP ******************************************************************************************
web1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible default]# cat username.yml
---
username:
james5
[root@ansible default]# ssh web1 id james5
uid=1008(james5) gid=0(root) 组 =0(root)
4.2 error 解决 ansible-playbook 对谬误的解决
因为 playbook 是程序执行, 当遇到谬误就会进行往下执行, 默认状况判断上一个工作 $?, 如果值不为 0 就进行执行
但某些状况咱们须要疏忽谬误继续执行
案例 4:
要求:
创立缓存目录, 而后重启 apache
1. 因为 /tmp/web 之前曾经存在 shell 模块 mkdir 报错 playbook 进行继续执行, 但其实这个谬误是不影响上面的工作执行
[root@ansible default]# cat Restart.yml
---
- hosts: web
remote_user: root
tasks:
- shell: mkdir /tmp/web
- name: ReStart service httpd
service:
name: httpd
state: restarted
[root@ansible default]# ansible-playbook Restart.yml
PLAY [web] ******************************************************************************************
TASK [Gathering Facts] ******************************************************************************
ok: [web2]
ok: [web1]
TASK ****************************************************************************************
[WARNING]: Consider using the file module with state=directory rather than running 'mkdir'. If you
need to use command because file is insufficient you can add 'warn: false' to this command task or
set 'command_warnings=False' in ansible.cfg to get rid of this message.
fatal: [web2]: FAILED! => {"changed": true, "cmd": "mkdir /tmp/web", "delta": "0:00:00.008765", "end": "2020-11-19 16:55:04.967697", "msg": "non-zero return code", "rc": 1, "start": "2020-11-19 16:55:04.958932", "stderr": "mkdir: 无奈创立目录 \"/tmp/web\": 文件已存在", "stderr_lines": ["mkdir: 无奈创立目录 \"/tmp/web\": 文件已存在"], "stdout": "","stdout_lines": []}
fatal: [web1]: FAILED! => {"changed": true, "cmd": "mkdir /tmp/web", "delta": "0:00:00.007319", "end": "2020-11-19 16:55:05.751981", "msg": "non-zero return code", "rc": 1, "start": "2020-11-19 16:55:05.744662", "stderr": "mkdir: 无奈创立目录 \"/tmp/web\": 文件已存在", "stderr_lines": ["mkdir: 无奈创立目录 \"/tmp/web\": 文件已存在"], "stdout": "","stdout_lines": []}
PLAY RECAP ******************************************************************************************
web1 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
web2 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
错误处理办法:
增加谬误选项:ignore_errors
True 示意疏忽谬误继续执行
False 示意遇到谬误就进行执行(默认)
[root@ansible default]# cat Restart.yml
---
- hosts: web
remote_user: root
tasks:
- shell: mkdir /tmp/web
ignore_errors: True
- name: ReStart service httpd
service:
name: httpd
state: restarted
[root@ansible default]# ansible-playbook Restart.yml
PLAY [web] ******************************************************************************************
TASK [Gathering Facts] ******************************************************************************
ok: [web1]
ok: [web2]
TASK ****************************************************************************************
[WARNING]: Consider using the file module with state=directory rather than running 'mkdir'. If you
need to use command because file is insufficient you can add 'warn: false' to this command task or
set 'command_warnings=False' in ansible.cfg to get rid of this message.
fatal: [web2]: FAILED! => {"changed": true, "cmd": "mkdir /tmp/web", "delta": "0:00:00.007426", "end": "2020-11-19 17:01:57.077906", "msg": "non-zero return code", "rc": 1, "start": "2020-11-19 17:01:57.070480", "stderr": "mkdir: 无奈创立目录 \"/tmp/web\": 文件已存在", "stderr_lines": ["mkdir: 无奈创立目录 \"/tmp/web\": 文件已存在"], "stdout": "","stdout_lines": []}
...ignoring
fatal: [web1]: FAILED! => {"changed": true, "cmd": "mkdir /tmp/web", "delta": "0:00:00.014932", "end": "2020-11-19 17:01:57.853702", "msg": "non-zero return code", "rc": 1, "start": "2020-11-19 17:01:57.838770", "stderr": "mkdir: 无奈创立目录 \"/tmp/web\": 文件已存在", "stderr_lines": ["mkdir: 无奈创立目录 \"/tmp/web\": 文件已存在"], "stdout": "","stdout_lines": []}
...ignoring
TASK [ReStart service httpd] ************************************************************************
changed: [web2]
changed: [web1]
PLAY RECAP ******************************************************************************************
web1 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
web2 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
4.3 tags 标签
tags: 给指定的工作定义一个调用标识 有时把多个模块写在一个 playbook 中. 但只想用到其中一个或其中几个模块
- 应用办法在模块里增加 tags 标签
-playbook 调用形式
-t TAGS, –tags=TAGS
案例 5:
要求: 调用工作 task03 创立文件
[root@ansible default]# cat tags2.yml
---
- hosts: web
remote_user: root
tasks:
- name: task01
file:
path: /tmp/web/task01
state: touch
tags: t1
- name: task02
file:
path: /tmp/web/task02
state: touch
tags: t2
- name: task03
file:
path: /tmp/web/task03
state: touch
tags: t3
[root@ansible default]# ansible-playbook tags2.yml -t t3
PLAY [web] ******************************************************************************************
TASK [Gathering Facts] ******************************************************************************
ok: [web2]
ok: [web1]
TASK [task03] ***************************************************************************************
changed: [web2]
changed: [web1]
PLAY RECAP ******************************************************************************************
web1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible default]# ssh web1 ls /tmp/web/
task03
4.4 handlers
当关注的资源发生变化时采取的操作
notify 这个 action 可用于每个 play 的最初触发, 这样就能够防止有屡次扭转产生时每次都执行指定的操作, 取而代之仅在所有的变动产生实现后一次性执行指定操作
在 notify 中列出的操作称为 handler, 即 notify 调用 handler 中定义的操作
咱们还是拿下面的 httpd 服务举例
案例 6:
要求:
批改 httpd 默认 index.html 而后重启 httpd 服务
[root@ansible default]# cat RestartHttp.yml
---
- hosts: web
remote_user: root
tasks:
- copy:
src: /root/index.html
dest: /var/www/html/index.html
ignore_errors: True
- name: ReStart service httpd
service:
name: httpd
state: restarted
[root@ansible default]# ansible-playbook RestartHttp.yml
PLAY [web] *******************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [web1]
ok: [web2]
TASK [copy] ******************************************************************************************************************************************************************************************************
changed: [web2]
changed: [web1]
TASK [ReStart service httpd] *************************************************************************************************************************************************************************************
changed: [web2]
changed: [web1]
PLAY RECAP *******************************************************************************************************************************************************************************************************
web1 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web2 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
第二次执行雷同操作
[root@ansible default]# ansible-playbook RestartHttp.yml
第二次和第一次执行的区别是没有在拷贝文件, 因为第一次曾经拷贝过了, 但服务还是重启过两次, 看上去如同没问题, 但细想第二次文件没有改变过, 和咱们批改配置文件后重启服务的理论需要是有区别的, 或者说第二次服务重次是齐全没有必要的
这时就要用的 notify 调用 handler 中定义的操作
简略说就是当文件产生过改变后, 才重启服务
批改配置后
[root@ansible default]# cat RestartHttp.yml
---
- hosts: web
remote_user: root
tasks:
- copy:
src: /root/index.html
dest: /var/www/html/index.html
ignore_errors: True
notify:
- restart "ReStart service httpd"
handlers:
- name: ReStart service httpd
service:
name: httpd
state: restarted
[root@ansible default]# ansible-playbook RestartHttp.yml
PLAY [web] ******************************************************************************************
TASK [Gathering Facts] ******************************************************************************
ok: [web2]
ok: [web1]
TASK [copy] *****************************************************************************************
ok: [web1]
ok: [web2]
PLAY RECAP ******************************************************************************************
web1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
从执行后果来看 并没有重启 httpd 服务
4.5 when 条件判断
有些时候须要在满足特定条件后再触发某一项操作, 或在特定的条件下终止某个行为, 这时候须要进行条件判断,when 正是解决这个问题的最佳抉择, 行程中的零碎变量 facts 作为 when 的条件, 能够通过 setup 模块查看
案例 7:
咱们用 debug 模块做个测试 debug 模块咱们前面会讲到
通过两个 when 判断条件如果成立, 则输入 ”System release is centos7″
[root@ansible default]# cat when.yml
---
- hosts: cache
remote_user: root
tasks:
- debug:
msg: "System release is centos7"
when:
- ansible_distribution == "CentOS"
- ansible_distribution_major_version == "7"
[root@ansible default]# ansible-playbook when.yml
PLAY [cache] ****************************************************************************************
TASK [Gathering Facts] ******************************************************************************
ok: [cache]
TASK [debug] ****************************************************************************************
ok: [cache] => {"msg": "System release is centos7"}
PLAY RECAP ******************************************************************************************
cache : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
4.6 register 返回值
有时候咱们还须要更简单的例子, 如判断前一个命令的执行后果去解决前面的操作, 这时候就须要 register 模块来保留前一个命令的返回状态, 在前面进行调用
案例 8:
要求: 把零碎负载太高的 Apache 服务进行
当零碎负载超过 0.7 时,则关掉 httpd
[root@web2 ~]# awk 'BEGIN{while(1){}}' // 先用 awk 对 web2 进步零碎负载, 为测试创立条件
[root@ansible default]# ssh web2 uptime // 曾经满足测试条件
11:10:11 up 24 days, 17:47, 2 users, load average: 0.88, 0.30, 0.14
root@all (5)[f:5]$ sys
[root@ansible default]# ansible-console web // 通过 ansible-console 查看 httpd 状态
Welcome to the ansible console.
Type help or ? to list commands.
root@web (2)[f:5]$ systemctl status httpd
web1 | CHANGED | rc=0 >>
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since 四 2020-11-19 17:58:04 CST; 17h ago
......
web2 | CHANGED | rc=0 >>
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since 四 2020-11-19 17:58:03 CST; 17h ago
....
root@web (2)[f:5]$ exit
[root@ansible default]# cat when.yml
---
- hosts: web
remote_user: root
tasks:
- shell: uptime|awk '{printf("%.2f\n",$(NF-2))}'
register: result // 返回 shell 执行后果到变量 result
- name: stop service
service:
name: httpd
state: stopped
when: result.stdout|float > 0.7 // 对 result 后果进行判断
[root@ansible default]# ansible-playbook when.yml
PLAY [web] ******************************************************************************************
TASK [Gathering Facts] ******************************************************************************
ok: [web1]
ok: [web2]
TASK ****************************************************************************************
changed: [web1]
changed: [web2]
TASK [stop service] ********************************************************************************
skipping: [web1]
changed: [web2]
PLAY RECAP ******************************************************************************************
web1 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
web2 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible default]# ssh web2 systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: inactive (dead) since 五 2020-11-20 11:24:23 CST; 41s ago //httpd 服务已敞开
......
4.7 with_items 循环
with_items 是 playbook 规范循环, 能够用于迭代一个列表或字典, 通过 {{item}} 获取每次迭代的值
案例 9:
要求: 一次性创立多个用户 nb、aa、plj、lx
[root@ansible default]# cat adduser.yml
---
- hosts: cache
remote_user: root
tasks:
- name: add users
with_items: ["nb","aa","plj","lx"]
user: group=wheel password={{'123456'|password_hash('sha512')}} name={{item}}
[root@ansible default]# ansible-playbook adduser.yml
PLAY [cache] ****************************************************************************************
TASK [Gathering Facts] ******************************************************************************
ok: [cache]
TASK [add users] ************************************************************************************
changed: [cache] => (item=nb)
changed: [cache] => (item=aa)
changed: [cache] => (item=plj)
changed: [cache] => (item=lx)
PLAY RECAP ******************************************************************************************
cache : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
4.8 include
在编写 playbook 的时候随随着我的项目越来越大,playbook 越来越简单, 批改也很麻烦, 这时能够把一些 paly、task 或 handler 放到其余文件中, 通过 include 指令蕴含进来是一个不错的抉择
蕴含项包含
- vars: 变量层
- tasks: 工作层
- handlers: 触发条件
- files: 文件
- template: 模板
- default: 默认, 优先级最低
案例 10:
把工作层独立进去
[root@ansible default]# cat include1.yml
---
- hosts: cache
remote_user: root
tasks:
- include: in3.yml
when: 2 > 1
[root@ansible default]# cat in3.yml
- debug:
msg: "task1 in in3.yml"
- debug:
msg: "task2 in in3.yml"
[root@ansible default]# ansible-playbook include1.yml
4.9 debug 调试
如果对于 Python 语法不相熟的,playbook 书写起来容易出错, 且排错艰难, 这里介绍几种简略的排错调试形式
检测语法
- ansible-playbook –syntax-check playbook.ymal
显示受到影响的主机
- –list-hosts
显示工作的 task - –list-tasks
显示将要运行的 tag - –list-tags
测试运行
模仿运行后果, 但如果在工作列表中, 工作 2 须要工作 1 执行的后果, 那么工作 2 可能会报错, 因为工作 1 没有理论执行
- ansible-playbook -C playbook.yaml
还能够在运行时输入更为具体的信息, 帮忙排错 比方: 变量的值
案例 11:
以之前 when.yml 为例, 查看 result 变量中的内容
[root@ansible default]# cat when.yml
---
- hosts: web
remote_user: root
tasks:
- shell: uptime|awk '{printf("%.2f\n",$(NF-2))}'
register: result
- name: stop service
service:
name: httpd
state: stopped
when: result.stdout|float > 0.7
- name: Show debug info
debug:
var: result
[root@ansible default]# ansible-playbook when.yml
PLAY [web] ******************************************************************************************
TASK [Gathering Facts] ******************************************************************************
ok: [web1]
ok: [web2]
TASK ****************************************************************************************
changed: [web1]
changed: [web2]
TASK [stop service] ********************************************************************************
skipping: [web1]
ok: [web2]
TASK [Show debug info] ******************************************************************************
ok: [web1] => {
"result": {
"changed": true,
"cmd": "uptime|awk'{printf(\"%.2f\\n\",$(NF-2))}'","delta":"0:00:00.010118","end":"2020-11-20 15:12:05.959884","failed": false,"rc": 0,"start":"2020-11-20 15:12:05.949766","stderr":"",
"stderr_lines": [],
"stdout": "0.04",
"stdout_lines": ["0.04"]
}
}
ok: [web2] => {
"result": {
"changed": true,
"cmd": "uptime|awk'{printf(\"%.2f\\n\",$(NF-2))}'","delta":"0:00:00.010133","end":"2020-11-20 15:12:05.484865","failed": false,"rc": 0,"start":"2020-11-20 15:12:05.474732","stderr":"",
"stderr_lines": [],
"stdout": "2.04",
"stdout_lines": ["2.04"]
}
}
PLAY RECAP ******************************************************************************************
web1 : ok=3 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
web2 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=