ansible常用模块学习之判断模块学习

1 简单条件判断

[root@ansible ansible]# cat when.yaml
---
- hosts: 192.168.10.20
  remote_user: root
  tasks:
    - debug:
         msg: "this is centos"
      when: ansible_distribution=="entOS"

执行如下
[root@ansible ansible]# ansible-playbook when.yaml 

PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************************************************************
ok: [192.168.10.20]

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => {
    "msg": "this is centos"
}

2 条件判断常见语法

==  :比较两个对象是否相等,相等为真

!=  :比较两个对象是否不等,不等为真

>   :比较两个值的大小,如果左边的值大于右边的值,则为真

<  :比较两个值的大小,如果左边的值小于右边的值,则为真

>=  :比较两个值的大小,如果左边的值大于右边的值或左右相等,则为真

<=  :比较两个值的大小,如果左边的值小于右边的值或左右相等,则为真

and  :逻辑与,当左边与右边同时为真,则返回真

or  :逻辑或,当左边与右边有任意一个为真,则返回真

not  :取反,对一个操作体取反

( )  :组合,将一组操作体包装在一起,形成一个较大的操作体

逻辑与例子:
---
- hosts: test
  remote_user: root
  tasks:
    - debug:
       msg: "thisis centos7"
      when: ansible_distribution=="CentOS" and ansible_distribution_major_version=="7" 

[root@ansible ansible]# ansible-playbook when_and.yaml 

PLAY [test] **************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************************************************************
ok: [192.168.10.21]
ok: [192.168.10.20]

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.21] => {
    "msg": "thisis centos7"
}

或者可以这样写
---
- hosts: test
  remote_user: root
  tasks:
    - debug:
       msg: "thisis centos7"
      when: 
        - ansible_distribution=="CentOS" 
        - ansible_distribution_major_version=="7" 

同时用到了逻辑与、逻辑或、分组组合
---
- hosts: test
  remote_user: root
  tasks:
    - debug:
       msg: "thisis centos7"
      when: ansible_distribution=="CentOS" and  (ansible_distribution_major_version=="7" or ansible_distribution_major_version=="6")

取反

--- - hosts: test remote_user: root tasks: - debug: msg: "thisis centos7" when: not ansible_distribution=="CentOS" and (ansible_distribution_major_version=="7" or ansible_distribution_major_version=="6") 结果: PLAY [test] ************************************************************************************************************************************************************************************************** TASK [Gathering Facts] *************************************************************************************************************************************************************************************** ok: [192.168.10.21] ok: [192.168.10.20] TASK [debug] ************************************************************************************************************************************************************************************************* skipping: [192.168.10.21] skipping: [192.168.10.20]
根据上一步的task执行shell的成功失败执行下面的语句
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  tasks:
   - name: task1
     shell: "ls /test/s"
     register: returnmsg
     ignore_errors: true

   - name: task2
     debug: msg="Command execution successful"
     when: returnmsg.rc == 0
   - name: task3
     debug: msg="Command execution failed"
     when: returnmsg.rc != 0  

直接结果如下
ansible-playbook when_dir.yaml 

PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK [task1] *************************************************************************************************************************************************************************************************
fatal: [192.168.10.20]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "cmd": "ls /test/s", "delta": "0:00:00.038202", "end": "2020-09-09 11:25:44.188590", "msg": "non-zero return code", "rc": 2, "start": "2020-09-09 11:25:44.150388", "stderr": "ls: 无法访问/test/s: 没有那个文件或目录", "stderr_lines": ["ls: 无法访问/test/s: 没有那个文件或目录"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [task2] *************************************************************************************************************************************************************************************************
skipping: [192.168.10.20]

TASK [task3] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => {
    "msg": "Command execution failed"
}

3 条件判断与tests(exists)

文件存在时,输出信息
[root@ansible ansible]# cat when_tests.yaml
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  vars:
    testpath: /test
  tasks: 
     - debug:
         msg: "file exit"
       when: testpath is exists 

结果:
[root@ansible ansible]# ansible-playbook when_tests.yaml 

PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK [debug] *************************************************************************************************************************************************************************************************
skipping: [192.168.10.20]

PLAY RECAP ***************************************************************************************************************************************************************************************************
192.168.10.20              : ok=0    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

文件不存在的时候,输出信息
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  vars:
    testpath: /test
  tasks: 
     - debug:
         msg: "file exit"
       when: not testpath is exists 

另一种写法
[root@ansible ansible]# cat when_tests.yaml
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  vars:
    testpath: /test
  tasks: 
     - debug:
         msg: "file not exit"
       when: testpath is  not  exists 

4 判断变量的一些tests(defined,undefined,none)



--- - hosts: 192.168.10.20 remote_user: root gather_facts: no vars: testvar: "test" testvar1: tasks: - debug: msg: "Variable is defined" when: testvar is defined - debug: msg: "Variable is undefined" when: testvar2 is undefined - debug: msg: "The variable is defined, but there is no value " when: testvar1 is none

5 判断执行结果的一些tests(success,failure,change,skip)

success 或 succeeded:通过任务的返回信息判断任务的执行状态,任务执行成功则返回真 failure 或 failed:通过任务的返回信息判断任务的执行状态,任务执行失败则返回真 change 或 changed:通过任务的返回信息判断任务的执行状态,任务执行状态为changed则返回真 skip 或 skipped:通过任务的返回信息判断任务的执行状态,当任务没有满足条件,而被跳过执行时,则返回真
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  vars: 
    testvar: "yes"
  tasks: 
   - shell: "cat /test/abc"
     when: testvar=="yes"
     register: returnmsg
     ignore_errors: true
   - debug: 
       msg: "success"
     when: returnmsg is success
   - debug: 
      msg: "failed"
     when: returnmsg is failure
   - debug: 
      msg: "changed"
     when: returnmsg is change
   - debug: 
      msg: "skip"
     when: returnmsg is skip
结果:
[root@ansible ansible]# ansible-playbook when_shell.yaml 

PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK  *************************************************************************************************************************************************************************************************
fatal: [192.168.10.20]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "cmd": "cat /test/abc", "delta": "0:00:00.040405", "end": "2020-09-09 17:27:03.537201", "msg": "non-zero return code", "rc": 1, "start": "2020-09-09 17:27:03.496796", "stderr": "cat: /test/abc: 没有那个文件或目录", "stderr_lines": ["cat: /test/abc: 没有那个文件或目录"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [debug] *************************************************************************************************************************************************************************************************
skipping: [192.168.10.20]

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => {
    "msg": "failed"
}

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => {
    "msg": "changed"
}

TASK [debug] *************************************************************************************************************************************************************************************************
skipping: [192.168.10.20]

PLAY RECAP ***************************************************************************************************************************************************************************************************
192.168.10.20              : ok=3    changed=1    unreachable=0    failed=0    skipped=2    rescued=0    ignored=1   

6 判断路径的一些tests(file,directory,link,mount,exists)

注:如下tests的判断均针对于ansible主机中的路径,与目标主机无关 file : 判断路径是否是一个文件,如果路径是一个文件则返回真 directory :判断路径是否是一个目录,如果路径是一个目录则返回真 link :判断路径是否是一个软链接,如果路径是一个软链接则返回真 mount:判断路径是否是一个挂载点,如果路径是一个挂载点则返回真 exists:判断路径是否存在,如果路径存在则返回真
---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    testpath1: "/testdir/test"
    testpath2: "/testdir/"
    testpath3: "/testdir/testsoftlink"
    testpath4: "/testdir/testhardlink"
    testpath5: "/boot"
  tasks:
  - debug:
      msg: "file"
    when: testpath1 is file
  - debug:
      msg: "directory"
    when: testpath2 is directory
  - debug:
      msg: "link"
    when: testpath3 is link
  - debug:
      msg: "link"
    when: testpath4 is link
  - debug:
      msg: "mount"
    when: testpath5 is mount
  - debug:
      msg: "exists"
    when: testpath1 is exists

7 判断字符串的一些tests(lower,upper)

lower:判断包含字母的字符串中的字母是否是纯小写,字符串中的字母全部为小写则返回真 upper:判断包含字母的字符串中的字母是否是纯大写,字符串中的字母全部为大写则返回真
---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    str1: "abc"
    str2: "ABC"
  tasks:
  - debug:
      msg: "This string is all lowercase"
    when: str1 is lower
  - debug:
      msg: "This string is all uppercase"
    when: str2 is upper

8 判断整除的一些tests(even,odd,divisibleby)

even :判断数值是否是偶数,是偶数则返回真 odd :判断数值是否是奇数,是奇数则返回真 divisibleby(num) :判断是否可以整除指定的数值,如果除以指定的值以后余数为0,则返回真
---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    num1: 4
    num2: 7
    num3: 64
  tasks:
  - debug:
      msg: "An even number"
    when: num1 is even
  - debug:
      msg: "An odd number"
    when: num2 is odd
  - debug:
      msg: "Can be divided exactly by"
    when: num3 is divisibleby(8)

9 version 比较判断版本号

version:可以用于对比两个版本号的大小,或者与指定的版本号进行对比,使用语法为 version('版本号', '比较操作符') 大于:>, gt 大于等于:>=, ge 小于:<, lt 小于等于:<=, le 等于: ==, =, eq 不等于:!=, <>, ne
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  tasks:
    - name: get git version
      shell: "git --version |awk '{print $3}'" 
      register: gitversion
      ignore_errors: true
    - name: chakan gitversion
      debug: msg="this is {{gitversion.stdout}}"

    - name: version test
      debug: msg="version is ok!"
      when: gitversion.stdout is version("1.8.3.1","eq")   

结果:

PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK [get git version] ***************************************************************************************************************************************************************************************
changed: [192.168.10.20]

TASK [chakan gitversion] *************************************************************************************************************************************************************************************
ok: [192.168.10.20] => {
    "msg": "this is 1.8.3.1"
}

TASK [version test] ******************************************************************************************************************************************************************************************
ok: [192.168.10.20] => {
    "msg": "version is ok!"
}

10 其他一些判断的tests (subset,superset,string,number)

subset:判断一个list是不是另一个list的子集,是另一个list的子集时返回真 superset : 判断一个list是不是另一个list的父集,是另一个list的父集时返回真 string:判断对象是否是一个字符串,是字符串则返回真 number:判断对象是否是一个数字,是数字则返回真
---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    testvar1: 1
    testvar2: "1"
    testvar3: 00.20
  tasks:
  - debug:
      msg: "This variable is number"
    when: testvar1 is number
  - debug:
      msg: "This variable is a number"
    when: testvar2 is number
  - debug:
      msg: "This variable is a number"
    when: testvar3 is number
上例playbook中只有testvar1和testvar3会被判断成数字,testvar2不会

11 block的用法

可以通过block将多个任务用同一个条件判断表示。 可以通过block对任务执行失败进行其他操作。(当block中的任务执行失败时,会执行rescue中的任务进行补救)

11.1 多条任务通过同一判断条件判断

---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  tasks:
    - debug: 
        msg: "TASK1 not in block"
    - block:
        - debug: 
             msg: "TASK2 in block" 
        - debug:
             msg: "TASK3 in block"  
      when: 2<1 

结果:
[root@ansible ansible]# ansible-playbook when_block.yaml 

PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => {
    "msg": "TASK1 not in block"
}

TASK [debug] *************************************************************************************************************************************************************************************************
skipping: [192.168.10.20]

TASK [debug] *************************************************************************************************************************************************************************************************
skipping: [192.168.10.20]
  

11.2 通过block捕捉错误

应用场景: 判断block中的任务是否成功,失败执行rescue中的任务
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  tasks:
    - block:
        - shell: "ls /opt"
        - shell: "ls /abc"
        - shell: "ls /c"
      rescue:
         - debug: 
            msg: "i caught an error" 

结果:
PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK  *************************************************************************************************************************************************************************************************
changed: [192.168.10.20]

TASK  *************************************************************************************************************************************************************************************************
fatal: [192.168.10.20]: FAILED! => {"changed": true, "cmd": "ls /abc", "delta": "0:00:00.038015", "end": "2020-09-11 15:17:58.487277", "msg": "non-zero return code", "rc": 2, "start": "2020-09-11 15:17:58.449262", "stderr": "ls: 无法访问/abc: 没有那个文件或目录", "stderr_lines": ["ls: 无法访问/abc: 没有那个文件或目录"], "stdout": "", "stdout_lines": []}

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => {
    "msg": "i caught an error"
}

11.3 block结合always

---
- hosts: test70
  remote_user: root
  tasks:
  - block:
      - debug:
          msg: 'I execute normally'
      - command: /bin/false
      - debug:
          msg: 'I never execute, due to the above task failing'
    rescue:
      - debug:
          msg: 'I caught an error'
      - command: /bin/false
      - debug:
          msg: 'I also never execute'
    always:
      - debug:
          msg: "This always executes"

12 fai模块

ansibl中可以用fail实现shell里的exit的功能
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  tasks:
    - shell: "echo 'this is a string for testing -- error'"
      register: return_value
    - fail: 
        msg: "Conditions established,Interrupt running playbook"
      when: "'error' in return_value.stdout" 
    - debug: 
         msg: "不会执行的!"  
备注:
使用'in'关键字判断一个字符串是否存在于另一个字符串中,也可以用于判断一个特定的值是否存在于列表中。
当使用"in"或者"not in"进行条件判断时,整个条件需要用引号引起。

13 failed_when


--- - hosts: 192.168.10.20 remote_user: root gather_facts: no tasks: - debug: msg="failed_when before" - shell: "echo 'this is a string for testing -- error'" register: return_value failed_when: "'error' in return_value.stdout" - debug: msg: "不会执行的!" 结果 TASK [debug] ************************************************************************************************************************************************************************************************* ok: [192.168.10.20] => { "msg": "failed_when before" } TASK ************************************************************************************************************************************************************************************************* fatal: [192.168.10.20]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "cmd": "echo 'this is a string for testing -- error'", "delta": "0:00:00.038963", "end": "2020-09-11 21:34:56.616519", "failed_when_result": true, "rc": 0, "start": "2020-09-11 21:34:56.577556", "stderr": "", "stderr_lines": [], "stdout": "this is a string for testing -- error", "stdout_lines": ["this is a string for testing -- error"]} PLAY RECAP *******************************************************************************************************************************

14 changed_when

'changed_when'关键字的作用是在条件成立时,将对应任务的执行状态设置为changed

[root@ansible ansible]# cat when_changed.yaml --- - hosts: 192.168.10.20 remote_user: root gather_facts: no tasks: - debug: msg="this is ok" 正常返回值是ok --- - hosts: 192.168.10.20 remote_user: root gather_facts: no tasks: - debug: msg="this is ok" changed_when: 2>1 结果: TASK [debug] ************************************************************************************************************************************************************************************************* changed: [192.168.10.20] => { "msg": "this is ok" } PLAY RECAP *************************************************************************************************************************************************************************************************** 192.168.10.20 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 'changed_when'关键字将debug模块的执行后的状态定义为了"changed" 只有任务作出了实际的操作时(执行后状态为changed),才会真正的执行对应的handlers 让对应的任务永远不能是changed状态 --- - hosts: 192.168.10.20 remote_user: root gather_facts: no tasks: - shell: "ls /opt" changed_when: false 如果不加changed_when,结果会返回为changed.加了之后 就不会返回为changed了。
  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin
avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: