作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
目录
- 一.Playbook概述
- 1.什么是Playbook
- 2.模块(module)和剧本(playbook)的区别
- 3.playbook文件规范
- 4.Playbook的组成
- 5.playbook示例
- 二.YAML语言
- 1.什么是YAML
- 2.YAML的数据类型及特点
- 三.ansible-playbook命令
- 1.ansible-playbook命令格式
- 1.1 语法格式
- 1.2 ansible-playbook选项示例
- 2.ansible-playbook执行结果
- 2.1 编写剧本
- 2.2 运行剧本
- 3.ansible-vault文件加密解密
- 3.1 创建新文件剧本【文件不能存在】
- 3.2 解密剧本文件内容
- 3.3 编辑加密剧本文件
- 3.4 执行加密剧本文件
- 3.5 删除密码保护
- 1.ansible-playbook命令格式
- 四.Playbook案例
- 1.创建用户和组
- 2.安装nginx服务
- 3.其他案例
- 五.Playbook中的nofify和handlers
- 1.nofify和handlers概述
- 2.单个notify和handlers示例
- 3.多个notify和handlers示例
- 4.force_handlers示例
- 六.ignore_errors忽略错误
- 1.ignore_errors概述
- 2.ignore_errors示例
- 七.Playbook的tags
- 1.tags概述
- 2.tags示例
- 八.Playbook的变量
- 1.playbook变量概述
- 2.使用setup模块中的变量
- 2.1 setup模块概述
- 2.2 开启gather_facts实战案例
- 3 在命令行传递环境变量
- 3.1 编写剧本
- 3.2 执行剧本
- 4.在Playbook文件中定义变量
- 4.1 Playbook文件变量概述
- 4.2 Playbook文件变量案例
- 5.在单独文件中定义变量
- 5.1 文件定义变量的优先级概述
- 5.2 文件定义变量案例
- 6.在主机清单中定义变量
- 6.1 在主机清单定义变量
- 6.2 添加主机清单
- 7.在项目目录中定义变量
- 7.1 项目中定义变量概述
- 7.2
- 8.register注册变量
- 8.1 register注册变量概述
- 8.2 register注册变量案例
一.Playbook概述
1.什么是Playbook
在ansible中,比较简单的任务,我们可以直接调用单个模块来完成,但遇到比较复杂的场景,需要调用大量模块才能完成一个需求,或者多个任务间有依赖的时候,使用单条命令就特别不方便,这种情况下我们就需要Playbook剧本来实现。Playbook字面意思是剧本,演员按照剧本来演戏,运维人员编写Playbook剧本内容,而后ansible按照我们编写的剧本去执行任务。
2.模块(module)和剧本(playbook)的区别
- Playbook是对多个AD-Hoc(module)的一种编排组合的实现方式;- Playbook能控制任务执行的先后顺序;- Playbook可以持久保存到文件从而方便多次调用运行,而Ad-Hoc(module)只能临时运行;- Playbook适合复杂的重复性的任务,而Ad-Hoc(module)适合做快速简单的一次性任务;温馨提示:AD-Hoc指的是使用模块的一种方式,比如: " ansible -m '模块名称' -a '参数信息' "
3.playbook文件规范
playbook文件规范:- 扩展名称为yaml或者yml;- 第一行使用"---"表示yaml的开始,一般不写,如果多个yaml文件合并才会使用此标识;- 使用"#"作为注释;- 大小写敏感;- 缩进符要统一,用空格键缩进,不要用tab;- 缩进空格数量不重要,但是,相同层级的左边缩进,要对齐,保持一致;- 使用"- "表示单个列表项目;- 使用": "表示一个键值对;- 使用"{}"表示一个键值表;- 一个name只能有一个task;
4.Playbook的组成
Playbook是由一个或多个"play"组成的列表,Playbook的主要功能在于,将多个play组织在一个Playbook文件中,让多台预定义的主机按照Playbook中编排的内容完成一系列复杂的功能。一个Playbook至少要包含hosts和tasks两部分,主要由以下几部分组成:- hosts:指定要执行任务的远程主机,其值可以是通配符,主机或组。但一定要在主机清单中定义过的(/etc/ansible/hosts),可以用-i选项指定自定义的主机清单文件。- tasks:定义要在远程主机上执行的任务列表。各任务按顺序在hosts中指定主机上执行,即所有主机当做完当前任务,才会开始下一个任务。task的模式是执行指定模块,后面跟上预定的参数,参数中可以使用变量,模块的执行是幂等的。这意味着多次执行是安全的,因为其结果均一致。如果在执行过程中发生错误,则会全部回滚(包括前面已执行成功的)。每个task都应该定义name,用于执行结果的输出,如果没有指定name,则action的结果将用于输出。- remote_user:指定任务在远程主机上执行时,所使用的用户,可以是任意用户。也可以sudo,但前提是用户是存在的,可以不写,默认root。- tags:定义哪些代码内容可与被忽略,就是用tags跳过部分代码。标记应用于任务或包含的任务,这允许从命令行中选择任务的子集。- notify|handlers:一般配合使用,可以达到一种触发调用高度效果,类似于函数调用或触发器。- gather_facts:默认会自动调用的模块。获取远程主机的一些信息,可以在下面的任务重使用,相当于构造函数,可以禁用。- environment:定义Playbook运行时需要使用的变量,有多种定义方式。一个被转换为环境变量的字典,在执行时为任务提供。这只能与模块一起使用。任何其他类型的插件、Ansible本身及其配置都不支持此功能,它只是为负责执行任务的代码设置变量。这不是传递机密数据的推荐方式。所有组成可以参考官方文档:
https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html
5.playbook示例
1.编写配置文件
[root@worker232 ~]# cat ping.yaml
- hosts: allremote_user: roottasks:- name: t1ping:- name: t2shell: "ifconfig"
[root@worker232 ~]# 2.加载Playbook示例
[root@worker232 ~]# ansible-playbook ping.yaml PLAY [all] ***********************************************************************************************************************************************TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [10.0.0.232]
ok: [10.0.0.233]
ok: [10.0.0.231]TASK [t1] ************************************************************************************************************************************************
ok: [10.0.0.232]
ok: [10.0.0.233]
ok: [10.0.0.231]TASK [t2] ************************************************************************************************************************************************
changed: [10.0.0.233]
changed: [10.0.0.231]
changed: [10.0.0.232]PLAY RECAP ***********************************************************************************************************************************************
10.0.0.231 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.232 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.233 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@worker232 ~]#
二.YAML语言
1.什么是YAML
yaml是"Yet Another Markup Language"的简称,YAML是一种人性化的数据序列化。和HTML,XML,JSON类似,又是一款标记性语言,但你看它官网还会很傲娇的说" YAML Ain't Markup Language"。YAML是一个可读性高的用来表达资料序列的格式,是目前比较流行的配置文件格式,很多新的项目或者软件都采用yaml文件来保存配置信息,比如ubuntu,ansible,docker,kubernetes,ElasticStack等。官网地址:https://yaml.org
2.YAML的数据类型及特点
数据类型 | 描述 | 示例 |
---|---|---|
scalar(标量) | 单个的,不可再分的值。 包括但不限于字符串,布尔值,整数,浮点数,时间,日期,Null等。 |
name: "Jason Yin" age: 18 |
object(对象) | 键值对的集合,又称为字典(dictionary)|哈希(hashes)|映射(mapping) | labels: apps: xiuxian version: v1 |
array(数组) | 一组按次序排列的值,又称为列表(list)|序列(sequence) | command: - tail - -f - /etc/hosts |
YAML中的数据类型如上表所示。YAML语言特点:- yaml的可读性好;- yaml和脚本语言交互性强;- yaml使用实现语言的数据类型;- yaml有一个一致的信息模型;- yaml易于实现;- yaml可以基于流来处理;- yaml表达能力强,扩展性好;
三.ansible-playbook命令
1.ansible-playbook命令格式
1.1 语法格式
ansible-playbook [options] <filename.yaml> 常见的选项[options]:--syntax-check|--syntax语法检查。-C|--check:执行模拟,只检测可能会发生的改变,但不真正执行操作。-i|--inventory|--inventory-file:指定主机清单文件。-l|--limit:单位指定主机列表去执行。-k|--ask-pass:远程连接密码。-T|--timeout:连接超时时长,默认10s。-e|--extra-vars:定义变量。--become-user:指定用户执行。--flush-cache:刷新facts。--list-hosts:列出所有主机。--list-tags:列出Playbook中所有tag。-skip-tags:跳过指定tags。-t|--tags:只执行特定tag对应的task。--start-at-task:从指定task开始执行。--list-tasks:列出Playbook中所有task。-v|--verbose:显示详细信息,最多可以写5个v。
1.2 ansible-playbook选项示例
1.编写主机清单文件
[root@worker232 ~]# cat /etc/ansible/hosts
[k8s]
10.0.0.23[1:3][k8s:vars]
ansible_ssh_password=1
[root@worker232 ~]# 2.查看主机列表
[root@worker232 ~]# ansible-playbook --list-hosts demo.yaml playbook: demo.yamlplay #1 (all): all TAGS: []pattern: ['all']hosts (3):10.0.0.23310.0.0.23210.0.0.231
[root@worker232 ~]# 3.检查配置文件语法
[root@worker232 ~]# ansible-playbook --syntax -vvvvv demo.yaml
ansible-playbook [core 2.12.0]config file = /etc/ansible/ansible.cfgconfigured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']ansible python module location = /usr/lib/python3/dist-packages/ansibleansible collection location = /root/.ansible/collections:/usr/share/ansible/collectionsexecutable location = /usr/bin/ansible-playbookpython version = 3.10.12 (main, Nov 6 2024, 20:22:13) [GCC 11.4.0]jinja version = 3.0.3libyaml = True
Using /etc/ansible/ansible.cfg as config file
setting up inventory plugins
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Parsed /etc/ansible/hosts inventory source with ini plugin
1 plays in demo.yamlplaybook: demo.yaml
[root@worker232 ~]#
2.ansible-playbook执行结果
2.1 编写剧本
[root@worker232 ~]# cat demo.yaml # 指定主机分组【支持主机的匹配模式】
- hosts: all# 不收集主机信息,以提升运行速度gather_facts: no# 定义远程执行的用户,如果不写,默认就是root用户。# 如果在主机清单中定义了"ansible_ssh_user"参数则无视此配置,下同。remote_user: root# 定义任务列表tasks:# 定义任务的名称- name: t1 # 具体的模块和参数command: id# 指定模块的执行用户,会覆盖掉上面的root用户remote_user: yinzhengjie# 对于查询类任务,我们就不让他改变系统changed_when: false- name: t2shell: "echo 10+20|bc"changed_when: false- name: t3copy: 'content=#!/usr/bin/python3.10\n\nprint("杰哥讲运维")\nprint("https://www.cnblogs.com/yinzhengjie") dest=/tmp/yinzhengjie.py'
[root@worker232 ~]#
2.2 运行剧本
[root@worker232 ~]# ansible-playbook demo.yaml -l 10.0.0.231 -v
Using /etc/ansible/ansible.cfg as config filePLAY [all] ***********************************************************************************************************************************************TASK [t1] ************************************************************************************************************************************************
ok: [10.0.0.231] => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"}, "changed": false, "cmd": ["id"], "delta": "0:00:00.003250", "end": "2025-01-12 08:53:55.392259", "msg": "", "rc": 0, "start": "2025-01-12 08:53:55.389009", "stderr": "", "stderr_lines": [], "stdout": "uid=1000(yinzhengjie) gid=1000(yinzhengjie) groups=1000(yinzhengjie),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lxd)", "stdout_lines": ["uid=1000(yinzhengjie) gid=1000(yinzhengjie) groups=1000(yinzhengjie),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lxd)"]}TASK [t2] ************************************************************************************************************************************************
ok: [10.0.0.231] => {"changed": false, "cmd": "echo 10+20|bc", "delta": "0:00:00.003885", "end": "2025-01-12 08:53:55.626574", "msg": "", "rc": 0, "start": "2025-01-12 08:53:55.622689", "stderr": "", "stderr_lines": [], "stdout": "30", "stdout_lines": ["30"]}TASK [t3] ************************************************************************************************************************************************
changed: [10.0.0.231] => {"changed": true, "checksum": "2ff8189035b80ea1a00758c53d6adb24eae663bf", "dest": "/tmp/yinzhengjie.py", "gid": 0, "group": "root", "md5sum": "9c969b0ba5be0a78c437540b16be8243", "mode": "0644", "owner": "root", "size": 92, "src": "/tmp/ansible-tmp-1736643235.0918655-37397-238348265580265/source", "state": "file", "uid": 0}PLAY RECAP ***********************************************************************************************************************************************
10.0.0.231 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@worker232 ~]# PLAY RECAP执行结果说明:ok=33个task执行成功。changed=11个task导致了系统状态发生了变化。unreachable=00个task不可达。failed=00个task执行失败。skipped=00个task被跳过。rescued=00个task被拒绝。ignored=0 0个task被忽略。
3.ansible-vault文件加密解密
3.1 创建新文件剧本【文件不能存在】
[root@worker232 ~]# ansible-vault create yinzhengjie.yaml
New Vault password:
Confirm New Vault password:
[root@worker232 ~]#
[root@worker232 ~]# file yinzhengjie.yaml
yinzhengjie.yaml: Ansible Vault, version 1.1, encryption AES256
[root@worker232 ~]#
[root@worker232 ~]# cat yinzhengjie.yaml # 无法查看文件内容
$ANSIBLE_VAULT;1.1;AES256
65373965353531316232383462303362313735326632333664353038656164623539663337373934
6164383661333862643366386665626664663632393838370a303532623834613264393730636665
63643134393263663835333666656138383132373636353130353134386532303837333535323838
3932636564663661350a643261313265636333326161373365363762646639663764383238306464
6261
[root@worker232 ~]#
3.2 解密剧本文件内容
[root@worker232 ~]# ansible-vault view yinzhengjie.yaml
Vault password: # 输入密码后才能查看
- hosts: alltasks:- name: t1shell: id
[root@worker232 ~]#
3.3 编辑加密剧本文件
[root@worker232 ~]# ansible-vault edit yinzhengjie.yaml
Vault password: # 编辑时也需要输入密码
3.4 执行加密剧本文件
[root@worker232 ~]# echo 1 > /tmp/pwd.log
[root@worker232 ~]# ansible-playbook --vault-password-file /tmp/pwd.log yinzhengjie.yaml
3.5 删除密码保护
[root@worker232 ~]# file yinzhengjie.yaml
yinzhengjie.yaml: Ansible Vault, version 1.1, encryption AES256
[root@worker232 ~]#
[root@worker232 ~]# ansible-vault decrypt yinzhengjie.yaml
Vault password:
Decryption successful
[root@worker232 ~]#
[root@worker232 ~]# file yinzhengjie.yaml
yinzhengjie.yaml: ASCII text
[root@worker232 ~]#
四.Playbook案例
1.创建用户和组
1.编写剧本
[root@worker232 yinzhengjie]# cat bigdata_user.yaml
- hosts: 10.0.0.231gather_facts: notasks:- name: create hadoop groupgroup: name=hadoop system=yes gid=666- name: create hdfs useruser: name=hdfs system=yes group=hadoop uid=777 shell=/sbin/nologin home=/home/hdfs create_home=no
[root@worker232 yinzhengjie]# 2.检查剧本语法
[root@worker232 yinzhengjie]# ansible-playbook --syntax-check bigdata_user.yaml playbook: bigdata_user.yaml
[root@worker232 yinzhengjie]# 3.执行剧本
[root@worker232 yinzhengjie]# ansible-playbook -l 10.0.0.231 bigdata_user.yaml 4.远程服务器验证用户
[root@master231 ~]# id hdfs
uid=777(hdfs) gid=666(hadoop) groups=666(hadoop)
[root@master231 ~]#
[root@master231 ~]# getent passwd hdfs
hdfs:x:777:666::/home/hdfs:/sbin/nologin
[root@master231 ~]#
[root@master231 ~]# ll /home/
total 20
drwxr-xr-x 5 root root 4096 Jan 10 00:28 ./
drwxr-xr-x 20 root root 4096 Jan 11 12:14 ../
drwxr-x--- 3 2026 2026 4096 Jan 10 00:28 hanpaopao/
drwxrwxrwx 4 1002 jasonyin2020 4096 Jan 5 23:53 jasonyin2020/
drwxr-x--- 6 yinzhengjie yinzhengjie 4096 Jan 5 22:47 yinzhengjie/
[root@master231 ~]#
2.安装nginx服务
1.编写剧本
[root@worker232 yinzhengjie]# cat install_nginx.yaml
- hosts: 10.0.0.233gather_facts: notasks:- name: install nginxapt:name: nginx=1.18.0-6ubuntu14.5 state: present- name: set nginx index pagecopy:src: ./blog.txt# dest: /usr/share/nginx/html/index.html# 我的Ubuntu22.04 LTS系统安装nginx默认站点放在了/var/www/htmldest: /var/www/html/index.html- name: restart nginx serviceservice:name: nginxstate: restartedenabled: yes
[root@worker232 yinzhengjie]# 2.准备测试页面
[root@worker232 yinzhengjie]# echo https://www.cnblogs.com/yinzhengjie > blog.txt
[root@worker232 yinzhengjie]#
[root@worker232 yinzhengjie]# cat blog.txt
https://www.cnblogs.com/yinzhengjie
[root@worker232 yinzhengjie]# 3.运行剧本
[root@worker232 yinzhengjie]# ansible-playbook -l 10.0.0.233 install_nginx.yaml 4.访问测试
[root@worker232 yinzhengjie]# curl 10.0.0.233
https://www.cnblogs.com/yinzhengjie
[root@worker232 yinzhengjie]#
3.其他案例
有了上面的知识点,就可以完成我留的课堂作业了。比如完成zookeeper,kafka,ElasticSearch,Prometheus,Ceph,K8S等集群的一键部署。
五.Playbook中的nofify和handlers
1.nofify和handlers概述
handlers本质上就是任务列表(task list),也定义了一系列task,每个task中同样调用指定模块执行操作。只不过handlers中定义的task,不会主动执行,需要配合notify,让notify通知相应的handlers中的task,该task才会执行。在Playbook中,如果有task执行失败,那整个Playbook也执行失败,即便有部分task执行成功,这部分task对饮高度handlers也不会被执行,force_handlers保证的是已成功执行的task对应的handlers一定会被执行。nofify配合handlers,可以实现在特定条件下触发某些操作,例如服务器重启 ,服务重载等场景。温馨提示:- 1.如果多个task通知了相同的handlers,此handlers仅会在所有task结束后运行一次;- 2.只有notify对应的task发生改变了才会通知handlers,没有改变则不会触发handlers;- 3.handlers是在所有前面的tasks都执行成功才会执行,如果前面任何一个task失败,会导致handlers跳过执行;
2.单个notify和handlers示例
1.编写剧本
[root@worker232 yinzhengjie]# cat single-notify.yaml
- hosts: 10.0.0.233gather_facts: notasks:- name: set nginx index pagecopy:src: ./blog.txtdest: /usr/share/nginx/html/index.html- name: set nginx configcopy: src=./nginx-sites.conf dest=/etc/nginx/conf.d# 当拷贝的文件发生变化时,就会触发handlersnotify: reload nginx svc# handlers等到所有task执行完成之后才会被调用# 而且对于同一个handler,多个notify,也只会执行一次handlers:- name: reload nginx svcservice: name=nginx state=restarted
[root@worker232 yinzhengjie]# 2.准备配置文件
[root@worker232 yinzhengjie]# cat nginx-sites.conf
server {listen 81;server_name www.yinzhengjie.com;root /usr/share/nginx/html;index index.html;location / {try_files $uri $uri/ =404;}
}[root@worker232 yinzhengjie]# 3.执行剧本
[root@worker232 yinzhengjie]# ansible-playbook -l 10.0.0.233 single-notify.yaml 4.访问测试
[root@worker232 yinzhengjie]# curl -H "host: www.yinzhengjie.com" 10.0.0.233:81
https://www.cnblogs.com/yinzhengjie
[root@worker232 yinzhengjie]#
3.多个notify和handlers示例
1.编写剧本
[root@worker232 yinzhengjie]# cat multiple-notify.yaml
- hosts: 10.0.0.233gather_facts: notasks:- name: t1shell: echo "task 01"notify: [h1,h2]- name: t2shell: echo "task 02"notify: - h1- h2handlers:- name: h1shell: echo h1- name: h2shell: echo h2
[root@worker232 yinzhengjie]# 2.执行剧本【2和task同时调用了多个handlers,但最终只会执行一次】
[root@worker232 yinzhengjie]# ansible-playbook multiple-notify.yaml
4.force_handlers示例
1.编写剧本
[root@worker232 yinzhengjie]# cat force_handlers.yaml
- hosts: 10.0.0.231gather_facts: no# 表示成功执行的task,其调用的handlers肯定会执行成功force_handlers: yestasks:- name: t1shell: echo "task01"notify: h1- name: t2# 故意让t2任务执行失败,因为我主机上并没有myecho命令哟~shell: myecho "task02"notify: h2- name: t3shell: echo "task01"notify: h3handlers:- name: h1debug: msg="in h1 handlers"- name: h2debug: msg="in h2 handlers"- name: h3debug: msg="in h3 handlers"
[root@worker232 yinzhengjie]# 2.执行剧本【由于第2个task失败,导致后续的handlers均无法调用】
[root@worker232 yinzhengjie]# ansible-playbook force_handlers.yaml
六.ignore_errors忽略错误
1.ignore_errors概述
在同一个Playbook中,如果一个task出错,则默认不会再继续执行后续的其他task。利用"ignore_errors: yes"可以忽略此错误,继续执行其他task,此项可以配置为全局选项。
2.ignore_errors示例
1.编写剧本
[root@worker232 yinzhengjie]# cat ignore_errors.yaml
- hosts: 10.0.0.231gather_facts: noforce_handlers: yes# 如果任务执行失败,则可以忽略错误继续向下执行任务。ignore_errors: yestasks:- name: t1shell: echo "task01"notify: h1- name: t2shell: myecho "task02"notify: h2- name: t3shell: echo "task01"notify: h3handlers:- name: h1debug: msg="in h1 handlers"- name: h2debug: msg="in h2 handlers"- name: h3debug: msg="in h3 handlers"
[root@worker232 yinzhengjie]# 2.执行剧本【尽管t2任务执行失败,但t3依旧是可以正常执行的】
[root@worker232 yinzhengjie]# ansible-playbook ignore_errors.yaml
七.Playbook的tags
1.tags概述
ansible在执行一个Playbook时,会执行Playbook中所有的任务,可以利用tag标记特定task而非整个Playbook文件。一个task可以定义多个tags,也可以多个task对应同一个tag。tags主要用于调试环境,内置有三个特殊的tags:- all:表示所有任务。- tagged:表示所有被tag标记的任务。- untagged:表示所有没有被标记的任务。
2.tags示例
1.编写剧本
[root@worker232 yinzhengjie]# cat tags.yaml
- hosts: 10.0.0.231gather_facts: notasks:- name: t1shell: echo "in t1 task"tags: [k8s,ceph]- name: t2shell: echo "in t2 task"tags: [k8s,docker]- name: t3shell: echo "in t3 task"tags: [elasticstack]- name: t4shell: echo "in t4 task"
[root@worker232 yinzhengjie]# 2.查看tags信息
[root@worker232 yinzhengjie]# ansible-playbook tags.yaml --list-tagsplaybook: tags.yamlplay #1 (10.0.0.231): 10.0.0.231 TAGS: []TASK TAGS: [ceph, docker, elasticstack, k8s]
[root@worker232 yinzhengjie]# 3.查看任务信息
[root@worker232 yinzhengjie]# ansible-playbook tags.yaml --list-tasksplaybook: tags.yamlplay #1 (10.0.0.231): 10.0.0.231 TAGS: []tasks:t1 TAGS: [ceph, k8s]t2 TAGS: [docker, k8s]t3 TAGS: [elasticstack]t4 TAGS: []
[root@worker232 yinzhengjie]# 4.执行指定tags案例
[root@worker232 yinzhengjie]# ansible-playbook tags.yaml -t k8s
[root@worker232 yinzhengjie]# ansible-playbook tags.yaml -t docker
[root@worker232 yinzhengjie]# ansible-playbook tags.yaml -t elasticstack
[root@worker232 yinzhengjie]# ansible-playbook tags.yaml -t ceph,docker5.使用内置的tags案例
[root@worker232 yinzhengjie]# ansible-playbook tags.yaml -t untagged
[root@worker232 yinzhengjie]# ansible-playbook tags.yaml -t tagged
[root@worker232 yinzhengjie]# ansible-playbook tags.yaml -t all
八.Playbook的变量
1.playbook变量概述
Playbook支持变量的定义与引用,变量有数字,字母下划线组成,区分大小写且只能以字母开头。变量定义的两种方式:方式一:KEY=VALUE,例如: name=yinzhengjie方式二:KEY: VALUE,例如: age: 18引用变量的方式:通过"{{ 变量名称 }}"来调用,例如: "{{ name }}"变量的来源:- 1.使用setup facts获取的远程主机信息都是放在变量中的,可以直接使用;- 2.在命令行执行ansible-playbook时,可以使用-e选项设置变量,这种变量的优先级最高;- 3.在Playbook文件中定义变量;- 4.在单独的变量文件中定义变量,在Playbook中引用该文件;- 5.在主机清单中定义,当单独主机的变量与分组的变量有冲突时,单独定义的主机变量,优先级更高;- 6.在主机变量目录(host_vars)和主机分组目录(group_vars)中创建以主机名或分组名为文件名的文件,在该文件中定义;- 7.使用register将其他task或模块执行的输出内容保存到变量中,供别的task来使用;- 8.在role中定义;变量的优先级:- 1"-e"选项定义变量;- 2.Playbook中vars_files;- 3.Playbook中vars变量定义;- 4.host_vars/主机名文件;- 5.主机清单中主机变量;- 6.group_vars/主机组名文件;- 7.group_vars/all 文件;- 8.主机清单组变量;
2.使用setup模块中的变量
2.1 setup模块概述
在命令行中,可以通过指定setup模块的方式获取目标主机信息。在Playbook中,可以使用gather_facts选项来获得目标主机的信息。gather_facts选项默认是yes,次执行都需要消耗一定的资源和时间,在不需要时可以禁用该项来加快Playbook的执行效率。如果需要收集远程主机的信息,合理的配置“ansible.cfg”中facts相关的本地缓存策略,以便在频繁执行时减少资源消耗。gathering=implicitfacts策略,有效值为: implicit(the default),explicit,smart。implicit:不使用缓存,每次都抓取新的。explicit:不收集主机信息,除非在playbook中用"gather_facts: yes"显式指定。smart:远程主机信息如果有本地缓存,则使用缓存,如果没有,就去抓取,在存到缓存中,下次就直接使用缓存信息。fact_caching_timeout=86400本地缓存时长,默认86400sfact_caching=memory缓存类型,默认是memory,如果jsonfile,需要指定文件,如果redis,需要指定redis地址。fact_caching_connection=/path/to/cachedir本地缓存路径
2.2 开启gather_facts实战案例
1.编写剧本
[root@worker232 yinzhengjie]# cat setup-facts.yaml
- hosts: 10.0.0.231gather_facts: yestasks:- name: show-factsdebug: msg={{ ansible_facts }}- name: show-facts-hostnamedebug: msg={{ ansible_hostname }}- name: show-facts-ipv4-xixidebug: msg={{ ansible_facts["eth0"]["ipv4"]["address"] }}-----{{ ansible_facts.eth0.ipv4.address }}- name: show-facts-ipv4-hahadebug: msg={{ ansible_eth0["ipv4"]["address"] }}@@@@@{{ ansible_eth0.ipv4.address }}- name: show-facts-ipv4-hehedebug: msg={{ ansible_default_ipv4["address"] }}#####{{ ansible_default_ipv4.address }}
[root@worker232 yinzhengjie]# 2.执行剧本
[root@worker232 yinzhengjie]# ansible-playbook setup-facts.yaml
3 在命令行传递环境变量
3.1 编写剧本
[root@worker232 yinzhengjie]# cat facts-custom-variables.yaml
- hosts: 10.0.0.231gather_facts: notasks:- name: t1debug: msg={{ name }}:{{ hobby }}- name: t2shell: echo "https://www.cnblogs.com/yinzhengjie"notify: h1handlers:- name: h1debug: msg={{ gender }}
[root@worker232 yinzhengjie]#
3.2 执行剧本
1.在命令行中指定
[root@worker232 yinzhengjie]# ansible-playbook -e name=yinzhengjie -e hobby=K8S -e gender=boy facts-custom-variables.yaml -v2.多个变量一次定义
[root@worker232 yinzhengjie]# ansible-playbook -e "name=yinzhengjie hobby=K8S gender=boy" facts-custom-variables.yaml -v3.从文件中加载变量
[root@worker232 yinzhengjie]# cat ./variables.txt
name: JasonYin2020
hobby: 象棋
gender: boy
[root@worker232 yinzhengjie]#
[root@worker232 yinzhengjie]# ansible-playbook -e "@./variables.txt" facts-custom-variables.yaml -v
4.在Playbook文件中定义变量
4.1 Playbook文件变量概述
在Playbook文件中定义的变量,只能在当前Playbook中使用,属于私有变量。
4.2 Playbook文件变量案例
1.编写剧本
[root@worker232 yinzhengjie]# cat variables-playbook.yaml
- hosts: 10.0.0.231gather_facts: yesvars:name: 尹正杰hobby: kubernetesgender: boyip: "{{ ansible_facts.eth0.ipv4.address }}"tasks:- name: t1debug: msg={{ name }}:{{ hobby }}- name: t2shell: echo "https://www.cnblogs.com/yinzhengjie"notify: h1- name: t3debug: msg="变量支持互相调用 ---> {{ ip }}"handlers:- name: h1debug: msg={{ gender }}
[root@worker232 yinzhengjie]# 2.执行剧本2.1 使用Playbook定义的变量
[root@worker232 yinzhengjie]# ansible-playbook variables-playbook.yaml2.2 命令行传递的变量可以覆盖Playbook的变量
[root@worker232 yinzhengjie]# ansible-playbook -e "name=JasonYin" variables-playbook.yaml
5.在单独文件中定义变量
5.1 文件定义变量的优先级概述
在单独的变量文件中定义变量的优先级比在Playbook本身定义的变量优先级更高。在Playbook引用变量使用"vars_files"来定义,而"vars"在Playbook内置的变量,命令行传参使用"-e"来指定。
5.2 文件定义变量案例
1.定义变量文件
[root@worker232 yinzhengjie]# cat var01.txt
name: JasonYin
age: 18
[root@worker232 yinzhengjie]#
[root@worker232 yinzhengjie]# cat var02.txt
address: BeiJing
[root@worker232 yinzhengjie]# 2.Playbook引用变量文件
[root@worker232 yinzhengjie]# cat ref-variables.yaml
- hosts: 10.0.0.231gather_facts: novars_files:- var01.txt- /root/yinzhengjie/var02.txtvars:name: 尹正杰age: 30address: 北京hobby: "Kubernetes"tasks:- name: t1debug: msg="{{ name }}---{{ age }}---{{ address }}---{{ hobby }}"
[root@worker232 yinzhengjie]# 3.执行剧本3.1 验证vars_files优先级高于vars
[root@worker232 yinzhengjie]# ansible-playbook ref-variables.yaml3.2 验证命令行变量优先级更高,vars_files次之,vars最低
[root@worker232 yinzhengjie]# ansible-playbook -e "name=杰哥讲运维" ref-variables.yaml
6.在主机清单中定义变量
6.1 在主机清单定义变量
[root@worker232 yinzhengjie]# cat /etc/ansible/hosts
[k8s]
# 给分组的特定主机添加变量
10.0.0.23[1:3] hobby="k8s"
10.0.0.14[1:3]# 给整个分组定义变量
[k8s:vars]
ansible_ssh_password=1
name="yinzhengjie"
age=35
[root@worker232 yinzhengjie]#
6.2 添加主机清单
1.添加主机
[root@worker232 yinzhengjie]# cat ref-hosts-variables.yaml
- hosts: 10.0.0.231gather_facts: novars:address: 北京tasks:- name: t1debug: msg="{{ name }}---{{ age }}---{{ address }}---{{ hobby }}"
[root@worker232 yinzhengjie]# 2.执行脚本
[root@worker232 yinzhengjie]# ansible-playbook ref-hosts-variables.yaml
7.在项目目录中定义变量
7.1 项目中定义变量概述
在不同的项目中添加"host_vars","group_vars"目录。在"host_vars"目录下添加主机名或IP命名的文件,将该主机的变量写在此文件中。在group_vars目录中添加以分组命名的文件,将改组的变量写在此文件中。
7.2
1.创建存放主机和组变量的目录
[root@worker232 yinzhengjie-apps]# mkdir group_vars host_vars
[root@worker232 yinzhengjie-apps]#
[root@worker232 yinzhengjie-apps]# ll
total 16
drwxr-xr-x 4 root root 4096 Jan 14 00:17 ./
drwxr-xr-x 3 root root 4096 Jan 14 00:17 ../
drwxr-xr-x 2 root root 4096 Jan 14 00:17 group_vars/
drwxr-xr-x 2 root root 4096 Jan 14 00:17 host_vars/
[root@worker232 yinzhengjie-apps]# 2.查看主机清单
[root@worker232 yinzhengjie-apps]# cat /etc/ansible/hosts
[k8s]
10.0.0.23[1:3]
[root@worker232 yinzhengjie-apps]# 3.定义组变量【远程主机清单存在的组】
[root@worker232 yinzhengjie-apps]# tree
.
├── group_vars
│ └── k8s
├── host_vars
│ └── 10.0.0.231
├── my-variables.yaml
└── ref-project-vars.yaml2 directories, 4 files
[root@worker232 yinzhengjie-apps]#
[root@worker232 yinzhengjie-apps]# cat group_vars/k8s
ansible_ssh_password: 1
name: "yinzhengjie"
age: 35
[root@worker232 yinzhengjie-apps]# 4.定义主机变量【远程主机清单存在的主机】
[root@worker232 yinzhengjie-apps]# cat host_vars/10.0.0.231
hobby: "k8s"
[root@worker232 yinzhengjie-apps]# 5.自定义变量
[root@worker232 yinzhengjie-apps]# cat my-variables.yaml
address: 北京
[root@worker232 yinzhengjie-apps]# 6.引用自定义变量
[root@worker232 yinzhengjie-apps]# cat ref-project-vars.yaml
- hosts: 10.0.0.231gather_facts: novars_files:- my-variables.yamltasks:- name: t1debug: msg="{{ name }}---{{ age }}---{{ address }}---{{ hobby }}"
[root@worker232 yinzhengjie-apps]# 7.运行剧本
[root@worker232 yinzhengjie-apps]# ansible-playbook ref-project-vars.yaml
8.register注册变量
8.1 register注册变量概述
在Playbook中可以使用register将捕获命令的输出保存在临时变量中,方便后续调用此变量。说白了,就是让前一个task的结果保存为一个变量,让后一个task去使用该变量。
8.2 register注册变量案例
1.编写剧本
[root@worker232 yinzhengjie]# cat register-variables.yaml
- hosts: 10.0.0.231gather_facts: notasks:- name: t1shell: hostname# 使用关键字定义一个名称为"server_name"的变量,将执行结果放在该变了中register: server_name- name: t2# 调用变量debug: msg={{ server_name }}- name: t3# 调用变量的多个字段debug: msg={{ server_name.stdout }}---{{ server_name.start }}---{{ server_name.end }}[root@worker232 yinzhengjie]# 2.运行变量
[root@worker232 yinzhengjie]# ansible-playbook register-variables.yaml -k