ansible语句详解

一、when判断

就是符合条件的,就可以执行任务

when里面,默认是识别变量名的,不需要使用{{}}来引用变量,但是如果是值的就需要双引号或者单引号

when是判断模块的,与模块对齐即可

when: "'test' in group_names"  # test是值,需要引号,groups_names是魔法变量,不需要引号,when会自动的识别

1、判断的表达式(非常的多)

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

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

  • >= 判断左边是否大于等于右边

  • <= 判断左边是否小于等于右边

  • > 判断左边是否大于右边

  • < 判断左边是否小于右边

2、逻辑运算符

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

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

  • not 逻辑否 对结果取反,为真,则结果为假,在表达式的前面

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

when: not inventory_hostname == "node1" # 不是node1主机执行任务

3、根据rc的返回值

通过注册变量来获取模块的返回值,register

- shell: ls /etc/passwd
  register: get_status
- debug:
    msg: "rc is 0"
  when: get_status.rc == 0  # 返回结果为0,就执行
- debug:
    msg: "rc is not 0"
  when: get_status.rc != 0

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

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

  • directory 是否为一个目录

  • link 判断是否为软连接

  • mount 判断是否为挂载点

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

vars:
  file: /etc/passwd
- debug:
    mgs: exist
  when: "file is exists"

5、通过判断tasks任务的执行结果

  • 还是通过注册变量实现的

  • 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  # 判断结果的状态

6、通过对变量进行判断

通过判断变量是否定义了来执行语句

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

[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 不存在,判断不存在的

# 判断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"
}


二、其他关键字

1、block关键字

  • 如果有多个模块且判断的条件都是一样的,就可以使用block,将模块都放在一个块里面,直接对块进行判断

  • 判断成功执行,否则不执行

[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    # 报错,执行rescue块下的内容
      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中使用

  • fail是一个模块,就是符合条件的话,就主动终止剧本,后面的内容不会继续执行

- name: 检查操作系统必须是 CentOS
  ansible.builtin.fail:
    msg: "本剧本只支持 CentOS,当前系统: {{ ansible_distribution }}"
  when: ansible_distribution != "CentOS"

- name: 后面的任务只有系统是 CentOS 才会执行
  ansible.builtin.debug:
    msg: "系统检查通过,继续执行..."
  • fail_when 属于一个关键字

    • 默认情况下,ansible看rc返回值,rc=0表示成功

    • 但是fail_when 会覆盖默认规则,条件为真,任务标记失败

    • 条件为假,任务标记为真

    • 只是重新定义任务的状态,任务会继续执行的

- name: 检查应用状态(自定义失败)
  ansible.builtin.command: /usr/bin/check_app.sh
  register: app_result
  # 定义:只要输出里有 ERROR,就算任务失败
  failed_when: "'ERROR' in app_result.stdout"

- name: 对比两个文件(diff 特例)
  ansible.builtin.command: diff file1 file2
  register: diff_result
  # diff:
  # rc=0 → 相同(我们认为失败)
  # rc=1 → 不同(正常)
  # rc≥2 → 真错误(失败)
  failed_when: diff_result.rc == 0 or diff_result.rc >= 2

三、循环语句

1、with_items

  • item变量就是每次遍历(循环)所得到的值
[root@master test]# cat loop.yml 
- hosts: node1
  vars:
    users:
      - zhang
      - wang
      - li
  tasks:
    - debug:
        msg: "{{item}}"
      with_items: "{{users}}"


# 循环输出三次

另外一种写法

with_items:
    - zhang
    - wang
    - li

2、with_dict

主要就是循环字典的

item.key 或者 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

# 遍历一个列表
[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')}}"  # 直接进行加密,前面的密码必须是一个变量,系统设定的

posted @ 2026-04-11 19:53  乔的港口  阅读(3)  评论(0)    收藏  举报