LabHub
学习 学习路径 课程

Ansible 实战

用条件与循环把分支压扁

在 LabHub 中继续学习

目标

把因复制粘贴而不断增加的 task 收拢为数据和循环,并能通过条件筛选条目。

为什么重要

多个几乎相同的 task 中,迟早会有一个被误改得与其他项不同,而且仅靠阅读代码很难发现。把 task 合并成一个,出错的位置也只剩一个;数据像表格一样排列,缺项会一目了然。实际使用循环时,经常遇到三个问题:日志泄露——直接遍历字典会把其中所有值写入日志,因此需要 loop_control.label幂等性——循环十次,非幂等造成的影响也会扩大十倍;组合爆炸——两个列表的笛卡尔积会迅速膨胀。使用 until 等待某个条件时,还应让重试次数体现“在这段时间内仍未成功,就说明确实有问题”的判断。

步骤

  1. /root/ans/loops/site.yml 中使用 loop,在 /root/ans/loops/simple/ 下创建 alphabetagamma 三个目录。只能使用一个 task。
  2. 读取 /opt/lab/fixtures/ansible/users.yml 中的 app_users,根据每个条目的 dir 创建目录,并设置为 mode 权限:/root/ans/loops/deploy(0750)、/root/ans/loops/metrics(0755)、/root/ans/loops/backup(0700)。
  3. 在同一循环中添加 when,仅在权限比 0755 更严格的条目目录中留下 PRIVILEGED 文件:必须创建 /root/ans/loops/deploy/PRIVILEGED/root/ans/loops/backup/PRIVILEGED,不得创建 /root/ans/loops/metrics/PRIVILEGED
  4. 使用 loop_controllabel 整理日志,并将执行输出保存到 /root/ans/loops/out/run.txt。日志中应出现 item=deploy 形式的简短标签,不得显示整个字典。
  5. 创建使用 until/retries/delay 的等待 task,并将成功结果写入 /root/ans/loops/out/ready.txt,内容为 ready
  6. 根据环境(dev,stage,prod)×组件(app,worker)的组合,在 /root/ans/loops/matrix/<환경>-<컴포넌트>.conf 下创建 6 个文件(例如 /root/ans/loops/matrix/dev-app.conf/root/ans/loops/matrix/prod-worker.conf)。每个文件包含 env=<환경>component=<컴포넌트> 两行。
  7. 使用模式匹配,将文件收集并复制到 /root/ans/loops/collected/,目标是 matrix 中的 6 个 .conf 文件。不得逐个列出文件名。
  8. 创建 /root/ans/loops/out/loops.json,其中包含 users(3 项,每项都有布尔值 privileged)和 matrix_files(6)。再把第二次执行结果保存到 /root/ans/loops/out/run2.txt,且必须为 changed=0

参考

用列表循环创建三个目录

/root/ans/loops/site.yml 中使用 loop,在 /root/ans/loops/simple/ 下创建 alphabetagamma 三个目录。只能使用一个 task。

loop: 提供列表,并通过 item 引用当前项。不要复制 task。

遍历字典列表

读取 /opt/lab/fixtures/ansible/users.yml 中的 app_users,根据每个条目的 dir 创建目录,并设置为 mode 权限:/root/ans/loops/deploy(0750)、/root/ans/loops/metrics(0755)、/root/ans/loops/backup(0700)。

通过 vars_files 读取 fixture 中的 app_users。使用 item.nameitem.mode 这样的字段访问方式。

只处理符合条件的条目

在同一循环中添加 when,仅在权限比 0755 更严格的条目目录中留下 PRIVILEGED 文件:必须创建 /root/ans/loops/deploy/PRIVILEGED/root/ans/loops/backup/PRIVILEGED,不得创建 /root/ans/loops/metrics/PRIVILEGED

loop 与 when 一起使用时,会对每个条目分别判断条件。mode 为 0755 的条目必须被排除。

整理日志中的循环标签

使用 loop_controllabel 整理日志,并将执行输出保存到 /root/ans/loops/out/run.txt。日志中应出现 item=deploy 形式的简短标签,不得显示整个字典。

使用 loop_control 的 label 缩短显示内容。日志中不能出现完整字典。

重试直到条件成立

创建使用 until/retries/delay 的等待 task,并将成功结果写入 /root/ans/loops/out/ready.txt,内容为 ready

until/retries/delay 三项缺一不可。请将成功结果保存到文件。

生成两个列表的全部组合

根据环境(dev,stage,prod)×组件(app,worker)的组合,在 /root/ans/loops/matrix/<환경>-<컴포넌트>.conf 下创建 6 个文件(例如 /root/ans/loops/matrix/dev-app.conf/root/ans/loops/matrix/prod-worker.conf)。每个文件包含 env=<환경>component=<컴포넌트> 两行。

使用 product 过滤器生成组合。3 个环境 × 2 个组件 = 6 个文件。

通过模式收集文件

使用模式匹配,将文件收集并复制到 /root/ans/loops/collected/,目标是 matrix 中的 6 个 .conf 文件。不得逐个列出文件名。

不要逐个写出文件名,而要通过模式获取文件列表。复制后的内容必须与原文件一致。

生成循环结果报告并验证重跑

创建 /root/ans/loops/out/loops.json,其中包含 users(3 项,每项都有布尔值 privileged)和 matrix_files(6)。再把第二次执行结果保存到 /root/ans/loops/out/run2.txt,且必须为 changed=0

将每个用户的 privileged 状态和组合文件数量整理为 JSON,并确认第二次执行为 changed=0。