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

Ansible 循环、过滤器与判断逻辑

Ansible 循环、过滤器与判断逻辑

一、Ansible 循环

循环用于批量执行重复任务,减少代码冗余,Ansible 提供多种迭代方式适配不同场景,核心类型及用法如下:

循环类型功能说明关键特点
with_items / loop列表循环loop 可完全替代 with_items,适用于简单列表(如用户、软件包)
with_dict迭代字典需同时使用键(key)和值(value),如 “路径 + 权限” 组合场景
with_fileglob迭代本地文件支持通配符(如 *.conf),用于批量处理本地配置文件
with_lines迭代命令输出的每一行处理命令行执行结果,如清理旧文件、读取日志内容
with_nested嵌套迭代(多重循环)多列表组合迭代,如 “用户名 + 用户组” 关联配置
with_sequence生成有序序列支持数字 / 字母序列,如创建 test1-test5 系列测试文件
with_random_choice随机选择列表中的元素执行从列表中随机挑选一个元素执行,如抽样测试节点连通性

二、Ansible 过滤器

过滤器用于对变量值进行加工处理(格式转换、加密等),核心语法为 {{ 变量名 | 过滤功能 }},支持链式调用(如 {{ 变量 | lower | trim }})。

2.1 基础过滤器

过滤器名称功能说明示例
upper将字符串转换为纯大写{{ “Ansible” | upper}}
lower将字符串转换为纯小写{{ “ANSIBLE” | lower}}
trim去除字符串首尾空格(含换行符){{ " hello ansible " | trim}}
length计算字符串长度或列表元素个数{{ “ansible” | length}}

2.2 安全过滤器(字符串哈希加密)

主要用于用户密码加密,避免明文存储,支持 sha512、md5 等哈希算法。

示例:创建用户并设置 SHA512 加密密码

---
- name: 创建用户 sl 并设置加密密码  hosts: node1  tasks:    - name: 新建用户 sl,密码为 123456(SHA512 加密)      user:        name: sl        password: "{{ '123456' | password_hash('sha512') }}"  # 核心加密逻辑        state: present

三、Ansible 判断逻辑

通过 when 关键字实现条件控制,根据 “变量状态、任务结果、路径属性” 等决定是否执行任务,支持多种内置测试器。

3.1 核心判断场景及测试器

3.1.1 变量状态判断

用于检查变量是否定义、是否为空值:

测试器功能说明示例(when 条件)
defined变量已定义则执行任务when: test_var is defined
undefined变量未定义则执行任务when: test_var is undefined
none变量已定义但为空值则执行任务when: test_var is none
3.1.2 任务执行结果判断

先通过 register 注册任务结果,再根据结果状态执行后续操作:

测试器功能说明示例(when 条件)
success任务执行成功则执行when: task_result is success
failed任务执行失败则执行when: task_result is failed
changed任务导致主机状态变化则执行when: task_result is changed
skipped任务被跳过则执行when: task_result is skipped
3.1.3 路径属性判断

判断文件 / 目录 / 链接等路径的属性:

测试器功能说明示例(when 条件)
file路径是普通文件则执行when: “/tmp/test.txt” is file
directory路径是目录则执行when: “/tmp/logs” is directory
link路径是软链接则执行when: “/tmp/current” is link
mount路径是挂载点则执行when: “/mnt/data” is mount
exists路径存在(无论类型)则执行when: “/tmp/test.txt” is exists
3.1.4 字符串与数据类型判断
测试器功能说明示例(when 条件)
lower字符串是纯小写则执行when: “ansible” is lower
upper字符串是纯大写则执行when: “ANSIBLE” is upper
string对象是字符串类型则执行when: test_var is string
number对象是数字类型(int/float)则执行when: test_var is number

3.2 高级判断:block-rescue-always(异常捕获)

类似 try-except-finally,用于捕获任务执行异常,实现 “正常执行→异常处理→收尾操作” 的逻辑:

  • block:正常尝试执行的任务块;

  • rescue:block 执行失败时触发的异常处理块;

  • always:无论 block 成功与否,都会执行的收尾块。

示例:逻辑卷创建与异常处理

---
- name: 逻辑卷创建(含异常处理)  hosts: all  tasks:- name: 逻辑卷操作主逻辑block:        # 正常尝试创建 1500MiB 逻辑卷- name: 在 research 卷组创建 1500MiB 逻辑卷 datalvol:vg: researchlv: datasize: 1500MiBstate: presentrescue:        # block 失败(如空间不足)时执行- name: 输出错误消息debug:msg: "Could not create logical volume of that size"# 降级创建 800MiB 逻辑卷- name: 改为创建 800MiB 逻辑卷 datalvol:vg: researchlv: datasize: 800MiBstate: presentalways:        # 无论成败,都格式化逻辑卷为 ext4- name: 格式化逻辑卷为 ext4 文件系统filesystem:dev: /dev/research/datafstype: ext4when: "'research' in ansible_lvm.vgs"  # 仅卷组存在时执行    
# 卷组不存在时输出提示    - name: 卷组不存在提示      debug:        msg: "Volume group does not exist"when: "'research' not in ansible_lvm.vgs"

3.3 任务状态控制(手动干预结果)

通过关键字手动控制任务执行结果,适配特殊场景:

关键字 / 模块功能说明示例
ignore_errors: yes忽略任务错误,继续执行后续任务执行 “读取不存在文件” 命令时,忽略错误不中断剧本
changed_when: 条件自定义任务 “是否变化” 的判断changed_when: false → 强制标记任务 “无变化”
failed_when: 条件自定义任务 “是否失败” 的判断failed_when: “‘error’ in result.stdout” → 输出含 error 则标记失败
fail 模块手动中断剧本,输出自定义错误关键变量为空时,中断剧本并提示

四、前提准备:LVM 卷组部署(lvm2.yml)

在 node1、node2 上添加硬盘后,通过剧本安装 LVM 工具并创建卷组:

---
# 所有节点安装 lvm2 软件
- name: 安装 lvm2 工具  hosts: all   tasks:      - name: 安装 lvm2 包      yum:         name: lvm2        state: present
# node1 创建 2G 卷组 research
- name: 为 node1 创建卷组  hosts: node1  tasks:    - name: 分区 /dev/vdb(10MiB-2010MiB 为主分区)      parted:         device: /dev/vdb        number: 1        part_type: primary        part_start: 10MiB        part_end: 2010MiB        state: present    - name: 创建物理卷(PV)      pvcreate:         devices: /dev/vdb1        state: present    - name: 创建卷组(VG)research       lvg:          vg: research        pvs: /dev/vdb1        state: present
# node2 创建 1G 卷组 research
- name: 为 node2 创建卷组  hosts: node2  tasks:     - name: 分区 /dev/vdb(10MiB-1010MiB 为主分区)      parted:         device: /dev/vdb        number: 1        part_type: primary       part_start: 10MiB        part_end: 1010MiB        state: present    - name: 创建物理卷(PV)      pvcreate:         devices: /dev/vdb1        state: present    - name: 创建卷组(VG)research      lvg:        vg: research        pvs: /dev/vdb1        state: present

五、实战练习

主机清单说明

[test01]
node1[test02]
node2[web]
node3
node4[test05]
node5[webtest:children]
web  # webtest 组包含 web 组的所有节点

5.1 练习 1:动态生成主机清单(newhosts.yml)

需求从 http://ansible.example.com/materials/newhosts.j2 下载模板文件
完成该模板文件,用来生成新主机清单(主机的显示顺序没有要求),结构如下:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.122.10 node1.example.com node1
192.168.122.20 node2.example.com node2
192.168.122.30 node3.example.com node3
192.168.122.40 node4.example.com node4
192.168.122.50 node5.example.com node5
创建剧本/home/student/ansible/newhosts.yml,它将使用上述模板在 test01 主机组的主机上
生成文件/etc/newhosts。

5.1.1 步骤 1:下载并编写模板(newhosts.j2)
  1. 下载模板:curl -o http://ansible.example.com/materials/newhosts.j2
  2. 编辑模板内容:
#cat newhosts.j2127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6{% for sl in groups.all %}
{{ hostvars[sl].ansible_default_ipv4.address }} {{ hostvars[sl].ansible_fqdn }} {{ hostvars[sl].ansible_hostname }}
{% endfor %}
5.2.2 步骤 2:编写剧本(newhosts.yml)
---# 先收集所有主机信息(需访问 all 主机组)
- name: 收集所有主机变量  hosts: all  
# 在 test01 组生成主机清单
- name: 生成 /etc/newhosts 文件  hosts: test01  tasks:     - name: 部署模板文件      template:         src: /home/student/ansible/newhosts.j2        dest: /etc/newhosts        
5.2.3 验证命令
ansible test01 -m shell -a 'cat /etc/newhosts'

在这里插入图片描述

5.3 练习 3:差异化修改 /etc/issue(newissue.yml)

需求:创建剧本 /home/student/ansible/newissue.yml,满足下列要求:
1)在所有清单主机上运行,替换/etc/issue 的内容
2)对于 test01 主机组中的主机,/etc/issue 文件内容为 test01
3)对于 test02 主机组中的主机,/etc/issue 文件内容为 test02
4)对于 web 主机组中的主机,/etc/issue 文件内容为 Webserver

---
- name: 差异化修改 /etc/issue  hosts: all  tasks:     - name: 设置 /etc/issue 内容      copy:         content: |          {% if "test01" in group_names %}          test01          {% elif "test02" in group_names %}          test02          {% elif "web" in group_names %}          Webserver          {% endif %}        dest: /etc/issue
验证命令
ansible all -m shell -a 'cat /etc/issue'

在这里插入图片描述

http://www.xdnf.cn/news/1432099.html

相关文章:

  • 小学一到六年级语文/英语/数学作业出题布置网站源码 支持生成PDF和打印
  • 基金交易量预测比赛_数据分析
  • MySQL 8.0 窗口函数详解:让数据分析更简单高效
  • 大数据毕业设计选题推荐-基于大数据的大学生就业因素数据分析系统-Spark-Hadoop-Bigdata
  • 华为OD最新机试真题-中庸行者-OD统一考试(C卷)
  • 【Unity Shader学习笔记】(二)图形显示系统
  • 从Web2到Web3:一场重塑数字未来的“静默革命”
  • mac 本地安装maven环境
  • LLM面试50问:NLP/RAG/部署/对齐/安全/多模态全覆盖
  • CentOS7.6
  • @Hadoop 介绍部署使用详细指南
  • Qt中QSettings的键值使用QDataStream进行存储
  • 【ComfyUI】SDXL Refiner 提示进一步提升生成图像的质量
  • Android的USB通信 (AOA Android开放配件协议)
  • CSS基础学习步骤
  • 蓝桥杯算法之基础知识(5)
  • GPU 优化 - tensor core 用swizzle 解决bank conflict
  • STM32HAL 快速入门(十六):UART 协议 —— 异步串行通信的底层逻辑
  • PyTorch 训练随机卡死复盘:DataLoader × OpenCV 多进程死锁,三步定位与彻底修复
  • 【lucene】advanceshallow就是遍历跳表的,可以看作是跳表的遍历器
  • vscode下leetcode插件cookie登录
  • MySQL进阶知识梳理
  • 如何用c来编写一个判断闰年平年的微程序呢
  • 静态网站生成利器 Eleventy
  • 大文件稳定上传:Spring Boot + MinIO 断点续传实践
  • leetcode算法刷题的第二十四天
  • 网络数据包是怎么在客户端和服务端之间进行传输的?
  • 【Go语言并发编程:Goroutine调度原理】
  • Flink - 基础学习(1)-三种时间语义
  • PDF翻译怎么弄?一篇文章告诉你答案