当前位置: 首页 > java >正文

Ansible循环与判断实战指南

Ansible 循环与判断使用指南

循环

1. with_items 迭代列表

当需要在 Linux 中依次安装多个软件包时,可使用 with_items 进行迭代。

示例:安装 httpd、samba、samba-client 软件包

---
- name: install packageshosts: node1tasks:- name: yum_repo1yum_repository:file: servername: baseosdescription: rhel8baseurl: file:///mnt/BaseOSenabled: yesgpgcheck: no- name: yum_repo2yum_repository:file: servername: appstreamdescription: appstreambaseurl: file:///mnt/AppStreamenabled: yesgpgcheck: no- name: mount cdrommount:src: /dev/cdrompath: /mntfstype: iso9660state: mounted- name: install pksyum:name: "{{ item }}"state: presentwith_items:- httpd- samba- samba-client

2. with_dict 迭代字典

item.key 对应字典的键,item.value 对应字典的值。

示例:迭代字典并输出键值对

---
- name: testhosts: node1tasks:- name: debugdebug:msg: "{{ item.key }} & {{ item.value }}"with_dict:address: 1netmask: 2gateway: 3

3. with_fileglob 迭代文件

适用于拷贝多个文件到受控主机的场景。

示例:拷贝 /tmp/ 目录下的 .sh 和 .py 文件

---
- name: testhosts: node1tasks:- name: cp filecopy:src: "{{ item }}"dest: /tmp/with_fileglob:- /tmp/*.sh- /tmp/*.py

4. with_lines 迭代行

with_lines 可将命令的输出结果按行迭代。

示例:查找 /etc/ansible 目录下的所有 .yml 文件并拷贝

---
- name: testhosts: node1tasks:- name: cp filecopy:src: "{{ item }}"dest: /tmp/with_lines:- find /etc/ansible -name "*.yml"

5. with_nested 嵌套迭代

用于多重循环场景,例如组合多个列表中的元素。

示例:嵌套迭代输出组合值

---
- name: testhosts: node1tasks:- name: debugdebug:msg: "{{ item[0] }} & {{ item[1] }}"with_nested:- [a, b]- [1, 2, 3]

6. with_sequence 序列迭代

生成数字序列,支持指定起始值、结束值和步长。

示例:生成从 1 到 5 的序列

---
- name: testhosts: node1tasks:- name: debugdebug:msg: "{{ item }}"with_sequence:start=1end=5stride=1

注意:在较新版本的 Ansible 中,建议使用 loop 配合 range 过滤器替代 with_sequence

7. with_random_choice 随机选择

从列表中随机选择一个值。

示例:随机输出列表中的一个值

---
- name: testhosts: node1tasks:- name: debugdebug:msg: "{{ item }}"with_random_choice:- 1- 2- a- b- c

Loop 循环(现代写法)

现在更推荐使用 loop 替代传统的 with_*,通常结合过滤器使用。


过滤器(Filters)

字符串过滤器

---
- name: testhosts: node1vars:testvar: "abc123ABC 666"testvar1: " abc "tasks:- name: debug1debug:msg: "{{ testvar | upper }}"  # 转换为大写- name: debug2debug:msg: "{{ testvar | lower }}"  # 转换为小写- name: debug3debug:msg: "{{ testvar1 | trim }}"  # 去除首尾空格- name: debug4debug:msg: "{{ testvar | length }}" # 计算字符串长度

创建用户并使用哈希密码

使用加密算法对字符串进行hash加密

创建一个用户ydh,并且设置密码为redhat,密码采用SHA512哈希格式

---
- name: create userhosts: node1tasks:- name: create ydhuser:name: ydhpassword: "{{ 'redhat' | password_hash('sha512') }}"

补充字符串过滤器示例

---
- name: 过滤器hosts: serveravars:testvar: "abc123ABC 666"testvar1: "  abc  "testvar2: "123456789"testvar3: "1a2b,@#$%^&"tasks:- name: 将字符串转换成纯大写debug:#将字符串转换成纯大写msg: "{{ testvar | upper }}"- name: 将字符串转换成纯小写debug:#将字符串转换成纯小写msg: "{{ testvar | lower }}"- name: 将字符串首字母大写,之后的所有字母纯小写debug:#将字符串首字母大写,之后的所有字母纯小写msg: "{{ testvar | capitalize }}" - name: 返回字符串的第一个字符debug:#返回字符串的第一个字符msg: "{{ testvar | first }}" - name: 返回字符串的最后一个字符   debug:#返回字符串的最后一个字符msg: "{{ testvar | last }}"- name: 将字符串开头和结尾的空格去除debug:#将字符串开头和结尾的空格去除msg: "{{ testvar1 | trim }}"- name: 将字符串放在中间,并且设置字符串的长度为30,字符串两边用空格补齐30位长debug:#将字符串放在中间,并且设置字符串的长度为30,字符串两边用空格补齐30位长msg: "{{ testvar1 | center(width=30) }}"- name: 返回字符串长度,length与count等效,可以写为countdebug:#返回字符串长度,length与count等效,可以写为countmsg: "{{ testvar2 | length }}"- name: 将字符串转换成列表,每个字符作为一个元素debug:#将字符串转换成列表,每个字符作为一个元素msg: "{{ testvar3 | list }}"- name: 将字符串转换成列表,每个字符作为一个元素,并且随机打乱顺序debug:#将字符串转换成列表,每个字符作为一个元素,并且随机打乱顺序#shuffle的字面意思为洗牌msg: "{{ testvar3 | shuffle }}"

数字操作过滤器

# 将字符串转换为整数
msg: "{{ '8' | int }}"msg: "{{ 8+('8' | int) }}"  #将对应的值转换成int类型#ansible中,字符串和整形不能直接计算,比如{{ 8+'8' }}会报错#所以,我们可以把一个值为数字的字符串转换成整形后再做计算# 转换失败时返回默认值
msg: "{{ 'a' | int(default=6) }}"  
#将对应的值转换成int类型,如果无法转换,默认返回0
#使用int(default=6)或者int(6)时,如果无法转换则返回指定值6# 转换为浮点数
msg: "{{ '8' | float }}" #将对应的值转换成浮点型,如果无法转换,默认返回'0.0'msg: "{{ 'a' | float(8.88) }}" #当对应的值无法被转换成浮点型时,则返回指定值’8.88‘# 获取绝对值
msg: "{{ testvar4 | abs }}" #获取对应数值的绝对值# 四舍五入
msg: "{{ 12.5 | round }}" # 四舍五入
msg: "{{ 3.1415926 | round(5) }}" #取小数点后五位  # 生成随机数
msg: "{{ 100 | random }}" #从0到100中随机返回一个随机数
msg: "{{ 10 | random(start=5) }}" #从5到10中随机返回一个随机数
msg: "{{ 15 | random(start=5, step=3) }}"  
#从5到15中随机返回一个随机数,步长为3
#步长为3的意思是返回的随机数只有可能是5、8、11、14中的一个
msg: "{{ 15 | random(step=5) }}" #从0到15中随机返回一个随机数,这个随机数是5的倍数

文件与目录类过滤器

# 使用不同算法计算哈希值
msg: "{{ '123456' | hash('sha1') }}" #使用sha1算法对字符串进行哈希
msg: "{{ '123456' | hash('md5') }}" #使用md5算法对字符串进行哈希
msg: "{{ '123456' | checksum }}"  #获取到字符串的校验和,与md5哈希值一致
msg: "{{ '123456' | password_hash('sha256') }}" #使用sha256算法对字符串进行哈希,哈希过程中会生成随机"盐",以便无法直接对比出原值
msg: "{{ '123456' | password_hash('sha256', 'mysalt') }}" #使用sha256算法对字符串进行哈希,并使用指定的字符串作为"盐"
msg: "{{ '123123' | password_hash('sha512') }}" #使使用sha512算法对字符串进行哈希,哈希过程中会生成随机"盐",以便无法直接对比出原值
msg: "{{ '123123' | password_hash('sha512','ebzL.U5cjaHe55KK') }}" #使用sha512算法对字符串进行哈希,并使用指定的字符串作为"盐"

Ansible 条件判断(When)

基本判断运算符

==`, `!=`, `>`, `<`, `>=`, `<=`, `and`, `or`, `not`, `is`, `in

每次执行完一个任务,不管成功与失败,都会将执行的结果进行注册,可以使用这个注册的变量来when

变量判断 Tests

  • defined:变量已定义返回真
  • undefined:变量未定义返回真
  • none:变量值为空返回真

示例:

---
- name: testhosts: node1vars:aa: 11cc:tasks:- name: create debug1debug:msg: awhen: aa is defined- name: create debug2debug:msg: abwhen: bb is undefined- name: create debug3debug:msg: abcwhen: cc is none

任务执行结果判断 Tests

  • success/successed:通过任务的返回信息判断执行状态,任务执行成功返回真
  • failure/failed:通过任务的返回信息判断执行状态,任务执行失败返回真
  • change/changed:通过任务的返回信息判断执行状态,任务状态为 changed 返回真
  • skip/skipped:通过任务的返回信息判断执行状态,任务被跳过返回真

路径判断 Tests

注意:这些判断针对的是 Ansible 控制机上的路径,不是目标主机。

  • file:判断路径是否是一个文件
  • directory:判断路径是否是一个目录
  • link:判断路径是否是一个软连接
  • mount:判断路径是否是一个挂载点
  • exists:判断路径是否存在

字符串判断 Tests

  • lower:判断包含字母的字符串中的字母是否纯小写
  • upper:判断包含字母的字符串中的字母是否纯大写

其他 Tests

  • string:判断对象是否是一个字符串
  • number:判断对象是否一个数字

错误处理与流程控制

block/rescue/always

用于异常处理:先执行 block,失败则执行 rescue,最后执行 always

无论是block还是rescue执行失败还是成功,在最后都执行always

例题:

创建一个名为/etc/ansible/lv.yml 的playbook,它将在所有受管节点上运行以执行下列任务:

​ 创建符合以下要求的逻辑卷:

​ 逻辑卷创建在research卷组中

​ 逻辑卷名称为data

​ 逻辑卷大小为1500MiB

​ 使用ext4文件系统格式化逻辑卷

​ 如果无法创建请求的逻辑卷大小,应显示错误消息

​ Could not create logical volume of that size,并且应改为使用大小 800MiB。

​ 如果卷组research 不存在 ,应显示错误消息

​ Volume group does not exist。

​ 不要以任何方式挂载逻辑卷

前提:在node1、node2上添加一块硬盘,然后新建卷组

Node1的卷组大小为2G 卷组名为research

Node2的卷组大小为1G 卷组名为research

示例:创建逻辑卷

---
- name: create vg for node1hosts: node1tasks:- name: create partitionparted:device: /dev/vdbnumber: 1part_type: primarypart_start: 10MiBpart_end: 2058MiBstate: present- name: create vg researchlvg:vg: researchpvs: /dev/vdb1- name: create vg for node2hosts: node2tasks:- name: create partition for node2parted:device: /dev/vdbnumber: 1part_type: primarypart_start: 10MiBpart_end: 1034MiBstate: present- name: create vg research for node2lvg:vg: researchpvs: /dev/vdb1

新建lv.yml,满足题目需求

---
- name: create lvmhosts: node1,node2tasks:- name: create lvblock:- name: create lvm 1500Mlvol:vg: researchlv: datasize: 1500Mrescue:- name: output fail messagedebug:msg: Could not create logical volume of that size- name: create lvm 800Mlvol:vg: researchlv: datasize: 800Malways:- name: format lvmfilesystem:fstype: ext4dev: /dev/research/datawhen: "'research' in ansible_facts.lvm.vgs"#也可以用when: "'research' in ansible_lvm.vgs"- name: serach not existsdebug:msg: Volume group does not existwhen: "'research' not in ansible_facts.lvm.vgs"#也可以用when: "'research'  not in ansible_lvm.vgs"

fail 模块

用于在满足条件时中断 playbook 执行。

但我们一般是不会无故中断,除非在满足条件的情况下可以中断,经常和when一起用

示例:

---
- name: testhosts: node1tasks:- name: shellshell:cmd: echo 'this is a string for testing--error'register: return_value- name: failfail:msg: Conditions established, Interrupt running playbookwhen: "'error' in return_value.stdout"- name: debugdebug:msg: I never execute, because the playbook has stopped

failed_when

---
- name: testhosts: node1tasks:- name: debugdebug:msg: I execute normally- name: shellshell:cmd: echo 'this is a string testing--error'register: return_valuefailed_when: "'error' in return_value.stdout"- name: debug2debug:msg: chenyu

直接指定任务失败的条件。

ignore_errors

---
- name: testhosts: node1tasks:- name: debug1debug:msg: "{{ansible_fqdn}}"- name: debug2debug:msg: "{{ansible_ip}}"ignore_errors: yes- name: create filefile:path: /tmp/abcstate: touch

忽略任务错误继续执行。

changed_when

---
- name: testhosts: node1tasks:- name: debug1debug:msg: "{{ansible_fqdn}}"changed_when: true#或者可以让任务执行状态显示失败
---
- name: testhosts: node1tasks:- name: shellshell:cmd: ls /tmpchanged_when: false
http://www.xdnf.cn/news/19696.html

相关文章:

  • SQL Server--提取性能最差的查询
  • Redisson分布式锁会发生死锁问题吗?怎么发生的?
  • 嵌入式系统与51单片机全解析
  • 20.Linux进程信号(一)
  • 深入浅出 RabbitMQ - SpringBoot2.X整合RabbitMQ实战
  • 数据结构——顺序表和单向链表(1)
  • WPF 开发必备技巧:TreeView 自动展开全攻略
  • 豪华酒店品牌自营APP差异对比分析到产品重构
  • Qt6实现绘图工具:12种绘图工具全家桶!这个项目满足全部2D场景
  • 国产化部署的it运维平台:功能全面,操作便捷
  • OpenCV Python
  • 新手也能轻松选!秒出PPT和豆包AI PPT优缺点解析
  • 《Python Flask 实战:构建一个可交互的 Web 应用,从用户输入到智能响应》
  • 企业如何实现零工用工零风险?盖雅全自动化合规管控
  • 2024 年 AI 产业格局复盘:头部企业竞逐方向与中小玩家生存破局点
  • K8s HPA自动扩缩容实战指南
  • 广东某地非金属矿山自动化监测服务项目
  • Android 16k页面大小适配
  • Rust SQLx 开发指南:利用 Tokio 进行性能优化
  • VUE基础
  • 代码随想录---动态规划篇
  • 机器学习辅助的Backtrader资产配置优化策略
  • 人脸识别在智能安防中的实践路径
  • nodejs文件读写操作完整版
  • 国标落地!中小学生午休课桌椅迎来规范,聚焦舒适与耐用
  • 2025年十大主流HR管理系统全面评测:功能、价格、适用场景完整对比
  • C++ 中类模板参数的使用详解
  • webpack打包优化都有哪些
  • PromptHunt- 简单易用的AI提示词网站
  • PowerPoint和WPS演示如何循环放映PPT