ansible语句

when判断

  • 就是符合条件的话,就可以执行这个模块的内容了

  • 默认的when判断,识别变量名,不需要{{}}来引用变量,但是如果是值的话,就需要双引号或者单引号才行

vars:
  name: rhel9

when: name # 不需要引号

when: "'test' in group_names"  # 值的话就需要单引号
  • 判断的话,也是有一个返回值的

  • when 是判断模块的,因此的话,与模块对齐即可

1、判断的表达式

1、比较运算符

  • == 比较2边是否相等,比较字符串和数字

  • != 2边是否一致,不一致则为真

  • >= 比较大小,左边大于为真

  • <= 右边大于为真

  • > 左边大于为真

  • < 右边大于为真

[devops@master when]$ cat 1.yml 
- hosts: node
  tasks:
    - debug:
        var: ansible_all_ipv4_addresses  # 可以直接使用事实变量,系统自带的
      when: ansible_hostname == "master"  # 主机为master执行任务,其他主机不执行

# 输出结果为
TASK [debug] *************************************************************************
skipping: [node1]
ok: [master] => {
    "ansible_all_ipv4_addresses": [
        "192.168.50.10"
    ]
}

2、逻辑运算符

  • and 逻辑与,2边都为真,则返回为真

  • or 逻辑或,只有一个为真,则返回为真

  • not 逻辑或,对结果取反,真为假,假为真,位置在表达式前面

  • () 当一组的表达式组合在一起后,看成一个整体

# and使用
[devops@master when]$ cat 2.yml 
- hosts: node
  tasks:
    - debug:
        msg: this is rhel 9
      when: ansible_distribution_version == "9.0" and ansible_distribution == "RedHat"

# or 用法
# 可以直接使用ansible_ens160.ipv4.address
[devops@master when]$ cat 3.yml 
- hosts: node
  tasks:
    - debug:
        msg: this is or
      when: inventory_hostname == "node1" or ansible_ens160.ipv4.address == '192.168.50.10'


# not用法

[devops@master when]$ cat 3.yml 
- hosts: node
  tasks:
    - debug:
        msg: this is not
      when: not  inventory_hostname == "node1" # 不是node1主机的执行任务

TASK [debug] *************************************************************************
skipping: [node1] # node1跳过了
ok: [master] => {
    "msg": "this is not"
}


3、根据rc的返回值

  • file,copy等模块没有rc返回值,设计模块的时候定义的

  • 命令模块有rc的返回值

[devops@master when]$ cat 4.yml 
- hosts: node
  tasks:
    - shell: ls /etc/passwdqq
      register: get_status
      ignore_errors: yes
    - debug:
        msg: rc is 0
      when: get_status.rc == 0  # 结果的rc为0,执行这个模块
    - debug:
        msg: rc is not 0
      when: get_status.rc != 0  # 结果的rc不为0,执行这个模块


TASK [debug] *************************************************************************
skipping: [node1]
skipping: [master]

TASK [debug] *************************************************************************
ok: [node1] => {
    "msg": "rc is not 0"
}
ok: [master] => {
    "msg": "rc is not 0"
}

4、通过条件判断路径是否存在

  • file 判断指定路径是否为一个文件,是文件则为真

  • directory 是否为目录

  • link 是否为软链接

  • mount 是否为挂载点

  • exists 判断路径是否存在,存在则为真

[devops@master when]$ cat 5.yml 
- hosts: node
  tasks:
    - debug:
        msg: exist
      when: "'/etc/passwd' is exists"

TASK [debug] *************************************************************************
ok: [node1] => {
    "msg": "exist"
}
ok: [master] => {
    "msg": "exist"
}


[devops@master when]$ cat 5.yml 
- hosts: node
  vars:
    file: /etc/passwd
  tasks:
    - debug:
        msg: exist
      when: "file is exists"

5、通过判断tasks任务的执行结果(是对整个task任务进行判断)

  • 判断的是整个的任务的执行结果,因此使用就是注册变量这个就能实现

  • 就是执行剧本的时候,tasks左边的ok

  • changed 发生了改变

  • succeeded 任务执行成功了

  • failed 任务失败

  • skipped 任务跳过,注意一个错误的任务使用ignore_errors忽略了这个错误,虽然是跳过的,但是这个任务执行是失败的,并没有跳过(这个是本质),虽然外像是跳过的状态

- hosts: node
  tasks:
    - shell: ls /etc/passwdqqq
      register: get_status
      ignore_errors: yes
    - debug:
        var: get_status
      when: get_status is skip


# 执行结果
# 任务是跳过的
TASK [debug] *************************************************************************
skipping: [node1]
skipping: [master]

6、通过对变量进行判断

  • 变量没有定义,是一个什么样的情况

  • defined 变量定义了返回真

  • undefined 变量没有定义,返回假

# 变量定义了,但是没有赋值,仍然是定义过的

[devops@master when]$ cat 7.yml 
- hosts: node
  vars:
    rhel:
  tasks:
    - debug:
        msg: is none
      when: rhel is defined

7、通过字符串进行判断大小写字母

  • lower 判断小写字母

  • upper 判断大写字母

[devops@master when]$ cat 15.yml 
- hosts: node1
  vars:
    rhel: qqq
  tasks:
    - debug:
        msg: lower
      when: rhel is lower
  
# 输出信息
TASK [debug] ***************************************************************************
ok: [node1] => {
    "msg": "lower"
}

8、通过数字来进行判断

  • even 判断数值是否为偶数,是则为真

  • odd 判断数值是否为奇数,是则为真

  • divisibleby(num)判断是否可以整除指定的数值,是则为真

[root@controller mnt]# cat f12.yml
- hosts: node1
  vars:
    rhel: 10
  tasks:
    - debug:
       msg: oushu
      when: rhel is divisibleby(2)

9、通过判断是否是子集或者是父集,in的判断

  • in判断的是非常常用的,判断是否存在

  • not in 不存在,判断不存在的,也很用

  • 判断磁盘名是否在ansible_device中

  • 磁盘判断案例

# 判断ens160是否存在这个接口上
[devops@master when]$ cat 8.yml 
- hosts: node
  tasks:
    - debug:
        msg: ens160 exists
      when: "'ens160' in ansible_interfaces"

TASK [debug] ***************************************************************************
ok: [node1] => {
    "msg": "ens160 exists"
}
ok: [master] => {
    "msg": "ens160 exists"
}

10、判断对象是否是字符串或者数字

  • string:判断是否是字符串

  • numbber:判断是否是数字

[root@controller mnt]# cat f14.yml
- hosts: node1
  vars:
    rhel: 9
  tasks:
    - debug:
       msg: 9 is number
      when: rhel is number

2、其他的关键字

1、block关键字

  • 如果有多个模块,并且多写几个when的话,就会非常的麻烦

  • 因此的话,使用这个block直接判断好几个模块,这样的话就非常的方便了

--sy 可以检测yaml的语法

[devops@master when]$ cat 9.yml 
- hosts: node
  tasks:
    - block:
      - debug:
          msg: block1
      - debug:
          msg: block2
      when: ansible_hostname == 'node1'


TASK [debug] ***************************************************************************
ok: [node1] => {
    "msg": "block2"
}
skipping: [master]

2、rescue关键字

  • 如果block包含的模块中出现了错误,就跳过这个错误,执行rescue这个关键字模块的内容

  • 会继续执行后面的所有任务,不会停止任务,知道结束所有任务

[devops@master when]$ cat 9.yml 
- hosts: node
  tasks:
    - block:
      - debug:
          msg: block1
      - debug:
          msg: block2
      - shell: ls /etc/passwd111
      when: ansible_hostname == 'node1'
      rescue:
        - debug:
            msg: tasks is error
    # 有rescue这个关键字,就会跳过错误任务,继续执行后面的所有任务,不会停止
    - shell: ls /etc/passwd


fatal: [node1]: FAILED! 

TASK [debug] **************************************************************************
ok: [node1] => {
    "msg": "tasks is error"
}

3、always关键字

  • 不管block中是否错误,都会执行这个关键字下面的模块内容
[devops@master when]$ cat 9.yml 
- hosts: node
  tasks:
    - block:
      - debug:
          msg: block1
      - debug:
          msg: block2
      - shell: ls /etc/passwd111
      when: ansible_hostname == 'node1'
      rescue:
        - debug:
            msg: tasks is error
      always:
        - debug:
             msg: is always

4、fail和fail_when

  • fail终止剧本的执行,如果报错的话,后面就不需要执行了

  • 就是如果当镜像都没有挂载的话,那么就不需要执行后面的所有任务了,没有一意义,直接跳过所有的即可

  • 不能在block中用

[devops@master when]$ cat 10.yml 
- hosts: node
  tasks:
      - debug:
          msg: block1
      - debug:
          msg: block2
      - shell: ls /etc/passwd111
        register: get_status
          #  ignore_errors: yes
        failed_when: get_status.rc != 0
      - shell: ls /etc/passwd



[devops@master when]$ cat 11.yml 
- hosts: node
  tasks:
      - debug:
          msg: block1
      - shell: ls /etc/passwd111
        register: get_status
        ignore_errors: yes
      - fail:
          msg: juben exist  # 显示这个错误信息,后面的模块不执行
        when: get_status.rc != 0
      - shell: ls /etc/passwd



循环语句

1、with_items

  • 这个item可不可以换成其他的呢,必须是item,系统定义的

  • 只能是这个item变量吗

  • 与模块进行对齐

  • item 就等于每一次循环得到的值

  • 将列表和字典的信息都打印出来,看一下

# 
[devops@master when]$ cat 12.yml 
- hosts: node
  vars:
    users:
      - zhang
      - wang
      - li
  tasks:
    - debug:
        msg: "{{item}}"
      with_items: "{{users}}"

# 输出结果
ok: [node1] => (item=zhang) => {
    "msg": "zhang"
}
ok: [node1] => (item=wang) => {
    "msg": "wang"
}
ok: [node1] => (item=li) => {
    "msg": "li"
}
ok: [master] => (item=zhang) => {
    "msg": "zhang"
}
ok: [master] => (item=wang) => {
    "msg": "wang"
}
ok: [master] => (item=li) => {
    "msg": "li"
}


# 这样的写法也是对的
[devops@master when]$ cat 12.yml 
- hosts: node
  tasks:
    - debug:
        msg: "{{item}}"
      with_items:
        - zhang
        - wang
        - li


2、with_dict

  • 循环的字典

  • 先直接打印这个item字段,看一下输出结果即可

  • item.key或者item.value 有key和value

  • 与模块的对齐

  • item.value.字段 获取这个value指定的值

  • item什么都不添加的话,输出的就是key和value都有

[devops@master when]$ cat 13.yml 
- hosts: node1
  vars:
    users:
      q1:
        uid: 2022
        name: zhang
      q2:
        uid: 2023
        name: li
  tasks:
    - debug:
        msg: "{{item}}"
      with_dict: "{{users}}"

# 输出结果
TASK [debug] ***************************************************************************
ok: [node1] => (item={'key': 'q1', 'value': {'uid': 2022, 'name': 'zhang'}}) => {
    "msg": {
        "key": "q1",
        "value": {
            "name": "zhang",
            "uid": 2022
        }
    }
}
ok: [node1] => (item={'key': 'q2', 'value': {'uid': 2023, 'name': 'li'}}) => {
    "msg": {
        "key": "q2",
        "value": {
            "name": "li",
            "uid": 2023
        }
    }
}


# 获取key
[devops@master when]$ cat 13.yml 
- hosts: node1
  vars:
    users:
      q1:
        uid: 2022
        name: zhang
      q2:
        uid: 2023
        name: li
  tasks:
    - debug:
        msg: "{{item.key}}"
      with_dict: "{{users}}"

# 输出信息
TASK [debug] ***************************************************************************
ok: [node1] => (item={'key': 'q1', 'value': {'uid': 2022, 'name': 'zhang'}}) => {
    "msg": "q1"
}
ok: [node1] => (item={'key': 'q2', 'value': {'uid': 2023, 'name': 'li'}}) => {
    "msg": "q2"
}


[devops@master when]$ cat 13.yml 
- hosts: node1
  vars:
    users:
      q1:
        uid: 2022
        name: zhang
      q2:
        uid: 2023
        name: li
  tasks:
    - debug:
        msg: "{{item.value.name}}"  # item.value.name 获取值
      with_dict: "{{users}}"


# 获取了这个value值
TASK [debug] ***************************************************************************
ok: [node1] => (item={'key': 'q1', 'value': {'uid': 2022, 'name': 'zhang'}}) => {
    "msg": "zhang"
}
ok: [node1] => (item={'key': 'q2', 'value': {'uid': 2023, 'name': 'li'}}) => {
    "msg": "li"
}

3、loop

  • 最常用的,字典和列表都能进行循环

  • 天生能循环列表

  • 循环字典的话,就需要使用过滤器

  • dict2items,有的版本没有,因此需要安装更高的版本

  • rhel9安装2.9的版本,太低了,应该安装高的版本

  • 常见的过滤器

    • password_hash('sha512'),识别成了一个变量

    • default

    • dict2items 字典的过滤器

# 遍历一个列表
[devops@master when]$ cat 13.yml 
- hosts: node1
  vars:
    users:
      - zhang
      - wang
      - li
  tasks:
    - debug:
        msg: "{{item}}"
      loop: "{{users}}"
      # 或者其他的写法
      loop:
        - zhang
        - wang
        - lisi

TASK [debug] ***************************************************************************
ok: [node1] => (item=zhang) => {
    "msg": "zhang"
}
ok: [node1] => (item=wang) => {
    "msg": "wang"
}
ok: [node1] => (item=li) => {
    "msg": "li"
}

# 遍历字典
[devops@master when]$ cat 13.yml 
- hosts: node1
  vars:
    users:
      q1:
        uid: 2022
        name: zhang
      q2:
        uid: 2023
        name: li
  tasks:
    - debug:
        msg: "{{item.value.name}}"
      loop: "{{users|dict2items}}"  # 过滤器,可以使用字典

TASK [debug] ***************************************************************************
ok: [node1] => (item={'key': 'q1', 'value': {'uid': 2022, 'name': 'zhang'}}) => {
    "msg": "zhang"
}
ok: [node1] => (item={'key': 'q2', 'value': {'uid': 2023, 'name': 'li'}}) => {
    "msg": "li"
}

# 密码过滤器
[devops@master when]$ cat 14.yml 
- hosts: node1
  vars:
    rhel: "123"
  tasks:
    - user:
        name: ppp
        password: "{{rhel|password_hash('sha512')}}"  # 直接进行加密,前面的密码必须是一个变量,系统设定的


总结

  • when 里面的变量需不需要引号

  • 如果是系统变量,或者vars其他定义好的变量,不需要双引号,可以直接使用,when是识别的

  • 如果是值的话,就需要 "'/etc/passwd is exists'" 双引号,然后单引号括值即可

posted @ 2025-09-21 21:53  w7nn  阅读(9)  评论(0)    收藏  举报