ansible 循环、判断

本文详细介绍了Ansible中用于循环的各种方法,包括with_items、with_dict、with_fileglob等,以及如何进行判断操作,如when条件、block/rescue/always结构、failed_when等。同时,文章还提到了如何处理错误,如ignore_errors和changed_when。最后,文章给出了一道关于添加硬盘的练习题,要求根据不同的主机需求创建不同大小的分区。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

循环

with_items 迭代列表

  • “{{ item }}”
  • with_items:

with_dict 迭代字典

  • “{{ item.key }}”
  • “{{ item.value }}”
  • with_dict:
    • KEY:VALUE

with_fileglob 迭代文件

可以使用多个文件。

  • “{{ item }}”
  • with_filegblob: /xxx/*.xx

with_lines 迭代行

  • “{{ item }}”
  • with_lines: find 路径 …

with_nested 套嵌迭代

从 0 开始。

  • “{{ item[NUM] }}”
  • with_nested: [xxx,xxx,xxx,…]

with_sequence 排序列

start:开始
end:结束
stride:每隔

  • “{{ item }}”
  • with_sequence:
    • start=NUM
    • start=NUM
    • stride=NUM

with_random_choice 随机获得列表中的一个值

  • “{{ item }}”
  • with_random_choice:

Loop

现在 loop 已经替代了 with,更多的是 loop 配合过滤器进行使用。

“{{ 变量 | 过滤器 }}”

字符串有关的过滤器:

  • upper 将字符串转换成纯大写。
  • lower 将字符串转换成纯小写。
  • trim 将字符串开头和结尾的空格去掉。
  • length 求字符串的长度。
  • capitalize 将字符串首字母大写,之后的所有字母纯小写。
  • first 返回字符串的第一个字符。
  • last 返回字符串的最后一个字符。
  • center(width=30) 将字符串放在中间,并且设置字符串的长度为 30,字符串两边用空格补齐 30 位长。
  • length OR count 返回字符串长度。
  • list 将字符串转换成列表,每个字符作为一个元素。
  • shuffle 将字符串转换成列表,每个字符作为一个元素,并且随机打乱顺序。

和数字有关的过滤器:
ansible 中,字符串和整形不能直接计算,比如 {{ 8+‘8’ }} 会报错。
如果无法转换,默认返回 0;使用 int(default=6) 或者 int(6) 时,如果无法转换 int 类型,则返回指定值 6。

  • int 整型。
  • float 浮点型。
  • abs 绝对值。
  • round 四舍五入,round(5) 取小数点后五位。
  • random 从 0 到 100 中随机返回一个随机数;“{{ 10 | random(start=5) }}” 从 5 到 10 中随机返回一个随机数;“{{ 15 | random(start=5,step=3) }}” 从 5 到 15 中随机返回一个随机数,步长为 3。

文件或目录类过滤器:

  • hash(‘sha1’) 使用 sha1 算法对字符串进行哈希。
  • hash(‘md5’) 使用 md5 算法对字符串进行哈希。
  • checksum 获取到字符串的校验和,与 md5 哈希值一致。
  • password_hash(‘sha256’) 使用 sha256 算法对字符串进行哈希,哈希过程中会生成随机"盐",以便无法直接对比出原值。
  • password_hash(‘sha256’,‘指定字符串’) 使用 sha256 算法对字符串进行哈希,并使用指定的字符串作为"盐"。
  • password_hash(‘sha512’) 使用 sha512 算法对字符串进行哈希,哈希过程中会生成随机"盐",以便无法直接对比出原值。

判断

  • When。
  • 判断运算符:“==” “!=” “>” “<” “>=” “<=” “and” “or” “not” “in” “not in” 。
  • 每次执行完一个任务,不管成功与失败,都会将执行的结果进行注册,可以使用这个注册的变量来 when。
  • 判断变量的一些 tests:
    • Defined:判断变量是否已经定义,已定义则返真。
    • Undefined:判断变量是否已经定义,未定义则返真。
    • 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,无论是 block 还是 rescue 执行失败还是成功,在最后都执行 always。

failed_when

hash 加密

例:
password: “{{ ‘redhat’ | password_hash(‘sha512’ )}}”

跳过错误、忽略错误

ignore_errors: yes

changed_when 修改任务执行后的最终状态

  • changed_when: true
  • changed_when: false

练习

要求:

  1. 给 node1 添加一块 5G 的硬盘;给 node2 添加一块 2G 的硬盘;node3 不添加硬盘。
  2. 写一个 partition.yml 的 playbook,满足如下要求:
    • 给所有的受控主机创建分区,创建 2500M 的分区,然后对分区进行格式化,格式化为 xfs 的文件系统。
    • 如果不能满足创建 2500M 的分区,则显示错误消息为:disk size not enough,接着改为创建 1000M。
    • 如果没有 /dev/sdb 硬盘,则显示错误消息为:the device is not sdb

添加硬盘

[root@node1 ~]# lsblk
NAME        MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda           8:0    0  20G  0 disk 
├─sda1        8:1    0   1G  0 part /boot
└─sda2        8:2    0  19G  0 part 
  ├─cs-root 253:0    0  17G  0 lvm  /
  └─cs-swap 253:1    0   2G  0 lvm  [SWAP]
sdb           8:16   0   5G  0 disk 
sr0          11:0    1   9G  0 rom  

[root@node2 ~]# lsblk
NAME        MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda           8:0    0  20G  0 disk 
├─sda1        8:1    0   1G  0 part /boot
└─sda2        8:2    0  19G  0 part 
  ├─cs-root 253:0    0  17G  0 lvm  /
  └─cs-swap 253:1    0   2G  0 lvm  [SWAP]
sdb           8:16   0   2G  0 disk 
sr0          11:0    1   9G  0 rom  

[root@node3 ~]# lsblk
NAME        MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda           8:0    0  20G  0 disk 
├─sda1        8:1    0   1G  0 part /boot
└─sda2        8:2    0  19G  0 part 
  ├─cs-root 253:0    0  17G  0 lvm  /
  └─cs-swap 253:1    0   2G  0 lvm  [SWAP]
sr0          11:0    1   9G  0 rom  

playbook

[root@server ~]# su - student
Last login: Fri Oct 28 15:08:17 CST 2022 on pts/0

[student@server ~]$ cd ansible/

[student@server ansible]$ vim partition.yml
---
- name: parted for node1 
  hosts: all
  tasks: 
    - name: create partition 2500M
      block: 
        - name: parted 
          parted: 
            device: /dev/sdb 
            number: 1 
            part_type: primary 
            part_start: 10MiB 
            part_end: 2510MiB 
            state: present 

      rescue: 
        - name: output fail message
          debug: 
            msg: disk size not enough.

        - name: create partition 1000M 
          parted: 
            device: /dev/sdb 
            number: 1 
            part_type: primary 
            part_start: 10MiB 
            part_end: 1010MiB 
            state: present 

      always:
        - name: format 
          filesystem: 
            fstype: xfs 
            dev: /dev/sdb 
      when: "ansible_devices.sdb is defined"

    - name: search not exists
      debug: 
        msg: the device is not sdb 
      when: "ansible_devices.sdb is not defined"

执行 playbook

[student@server ansible]$ ansible-playbook partition.yml

PLAY [parted for node1] ********************************************************

TASK [Gathering Facts] *********************************************************
ok: [node2]
ok: [node3]
ok: [node1]

TASK [parted] ******************************************************************
skipping: [node3]
fatal: [node2]: FAILED! => {"changed": false, "err": "Error: The location 2510MiB is outside of the device /dev/sdb.\n", "msg": "Error while running parted script: /sbin/parted -s -m -a optimal /dev/sdb -- unit KiB mklabel msdos mkpart primary 10MiB 2510MiB", "out": "", "rc": 1}
changed: [node1]

TASK [output fail message] *****************************************************
ok: [node2] => {
    "msg": "disk size not enough."
}

TASK [create partition 1000M] **************************************************
changed: [node2]

TASK [format] ******************************************************************
skipping: [node3]
changed: [node2]
changed: [node1]

TASK [search not exists] *******************************************************
skipping: [node1]
skipping: [node2]
ok: [node3] => {
    "msg": "the device is not sdb"
}

PLAY RECAP *********************************************************************
node1                      : ok=3    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
node2                      : ok=4    changed=2    unreachable=0    failed=0    skipped=1    rescued=1    ignored=0   
node3                      : ok=2    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值