首页 > 其他分享 >Playbook条件语句

Playbook条件语句

时间:2024-06-21 10:45:32浏览次数:3  
标签:语句 ok name 192.168 ansible Playbook 条件 msg block

目录

Playbook条件语句

  • 在有的时候play会依赖于变量,fact或者前一个任务的执行结果,或者基于上一个任务执行返回的结果而决定如何执行后续的任务,这个时候就需要用到条件判断
  • 应用场景
    • 某个任务要求运行的主机最少要有1G内存或者10G的磁盘
    • 捕获一个命令的输出,根据输出来触发不同的任务
    • 根据不同的操作系统来定义不同的任务
    • 根据目标主机的CPU来定义调优参数

1. when的基本使用

  • 在ansible中,使用的条件判断是when

1.1 when的基本示例

[ansible@master ansible]$ vim when-rhel.yaml
- name: install vim
  hosts: test
  tasks:
    - name: install vim via yum
      yum:
        name: vim
        state: present
      when: ansible_os_family == "RedHat"
  • ansible_os_family 这个变量可以在setup收集的信息里面找到

    为什么需要用到判断呢?

    因为只有在红帽系的发行版中,包管理工具使用的是yum,而在debian的系列中,使用的apt,所以如果你管理的主机有红帽系的,也有debian系的,那么就需要写一个判断来让他们分开执行

[ansible@master ansible]$ ansible-playbook when-rhel.yaml 
TASK [install vim via yum] *****************************************************
ok: [192.168.200.200]
ok: [192.168.200.210]
PLAY RECAP *********************************************************************
192.168.200.200            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.200.210            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

通过这个回显我们可以得知,任务他是要执行的,但是由于我们的系统上有vim,所以他没有发生改变,显示的是ok

那我们将ansible_os_family == "RedHat" 改为Debian看看呢

- name: install vim
  hosts: test
  tasks:
    - name: install vim via yum
      yum:
        name: vim
        state: present
      when: ansible_os_family == "Debain"

执行剧本

[ansible@master ansible]$ ansible-playbook when-rhel.yaml 

PLAY [install vim] *************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.200.200]
ok: [192.168.200.210]

TASK [install vim via yum] *****************************************************
skipping: [192.168.200.210]
skipping: [192.168.200.200]

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

可以看到,他的状态是skipping,也就说跳过的意思,因为他没有跟条件语句匹配上,所以他不会执行

1.2比较运算符

在ansible中,支持以下比较运算符

  • ==:比较两个对象是否相等
  • !=:比较两个对象是否不相等
  • >:比较两个对象的大小
  • <
  • >=
  • <=

1.3 比较运算符示例

  • when: ansible_machine == "x86_64"
  • when: ansible_memtotal_mb >= 1024

1.4 逻辑运算符

  • and: 逻辑与,当两边都为真时为真
  • or:逻辑或,当有一边为真时为真
  • not:逻辑否,对表达式取反
  • ():可以将多个语句写到一个括号里面,括号内的表达式都是逻辑与的关系

1.5 逻辑运算符示例

  • when: ansible_distribution == "openEuler" or nsible_distribution == "RedHat"
    • 表示判断操作系统是openEuler或者RedHat任意一者都行
  • when: ansible_machine == "x86_64" and ansible_memtotal_mb > 1024
    • 表示架构必须是x86并且机器的内存得大于1024m才行

2. 条件判断与block

  • 假设现在的场景是这样的,操作系统刚装完,现在需要你对这些系统进行一些初始化的操作,比如安装一些必要的软件包,关闭防火墙,selinux,但是现在有一个问题,就是这些操作系统并不一定都是红帽,可能还有Debian,Debian上面的操作跟红帽的操作就又不一样了啊

  • 如果我们按照之前的思维,那么就是安装软件包的时候有一个判断语句,关闭selinux又是一个判断语句,这样下来我们就需要写很多一模一样的判断语句了,能不能只写一条,这条判断语句过了之后直接执行对应的一系列任务呢? 是可以的

2.1 block示例

[ansible@master ansible]$ vim block.yaml
- name: block
  hosts: test
  tasks:
    - block:
      - name: install software
        yum:
          name: vim
          state: present
      - name: disable Selinux
        selinux:
          policy: targeted
          state: disabled
      - name: disabled firewalld
        systemd:
          name: firewalld
          state: stopped
          enabled: no
      when: ansible_os_family == "RedHat"

    - block:
      - name: install software
        apt:
          name: vim
          state: present
      when: ansible_os_family == "Debian"

通过加上block之后,在block里面定义的任务就是一个整体了,那么条件判断也是针对这个block的,如果条件判断返回为真之后,那么这个block里面的所有任务都会被执行

  • 我们的第一个block就是来判断是否为红帽系的系统,如果是的话那么就会执行那3个任务
  • 如果我们使用的系统是Debian系列的话,那么就会执行第二个block了

2.2 rescue

block除了能和when一起使用之外,还可以和rescue一起使用,作用是能做错误处理

[ansible@master ansible]$ vim rescue.yaml 
- name: rescue
  hosts: test
  tasks:
    - block:
        - name: test file exist
          shell: "ls /aaa.txt"
      rescue:
        - name: print file is not exist
          debug:
            msg: 'file is not exist'                               

我们的文件 /aaa.txt是不存在的,所以他执行这个任务会报错,但是正常情况下,举报报错就会停止执行了,后面的任务也就不会有输出了,rescue就是来做错误处理的,如果这里面有错误的话,他不会影响剧本执行,反而还会触发resue字段里的任务

[ansible@master ansible]$ ansible-playbook rescue.yaml 

PLAY [rescue] ******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.200.200]
ok: [192.168.200.210]

TASK [test file exist] *********************************************************
fatal: [192.168.200.210]: FAILED! => {"changed": true, "cmd": "ls /aaa.txt", "delta": "0:00:00.002396", "end": "2024-06-21 10:20:25.001243", "msg": "non-zero return code", "rc": 2, "start": "2024-06-21 10:20:24.998847", "stderr": "ls: cannot access '/aaa.txt': No such file or directory", "stderr_lines": ["ls: cannot access '/aaa.txt': No such file or directory"], "stdout": "", "stdout_lines": []}
fatal: [192.168.200.200]: FAILED! => {"changed": true, "cmd": "ls /aaa.txt", "delta": "0:00:01.003922", "end": "2024-06-21 10:20:25.992768", "msg": "non-zero return code", "rc": 2, "start": "2024-06-21 10:20:24.988846", "stderr": "ls: cannot access '/aaa.txt': No such file or directory", "stderr_lines": ["ls: cannot access '/aaa.txt': No such file or directory"], "stdout": "", "stdout_lines": []}

TASK [print file is not exist] *************************************************
ok: [192.168.200.210] => {
    "msg": "file is not exist"
}
ok: [192.168.200.200] => {
    "msg": "file is not exist"
}

PLAY RECAP *********************************************************************
192.168.200.200            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=1    ignored=0   
192.168.200.210            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=1    ignored=0   

我们可以看到,执行命令报错了,但是任务剧本没有被打断,后面还输出了file is not exist

那我们来将文件改为存在的,看看rescue还会执行吗

[ansible@master ansible]$ vim rescue.yaml 
- name: rescue
  hosts: test
  tasks:
    - block:
        - name: test file exist
          shell: "ls /etc/passwd"
      rescue:
        - name: print file is not exist
          debug:
            msg: 'file is not exist'

执行这个剧本

[ansible@master ansible]$ ansible-playbook rescue.yaml 
[ansible@master ansible]$ ansible-playbook rescue.yaml 

PLAY [rescue] ******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.200.210]
ok: [192.168.200.200]

TASK [test file exist] *********************************************************
changed: [192.168.200.200]
changed: [192.168.200.210]

PLAY RECAP *********************************************************************
192.168.200.200            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.200.210            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

我们可以看到,这个任务执行成功了,他没有输出rescue里面定义的任务

也就是说,只有block里面的任务出错的时候rescue才会接管任务,平时是不会执行的

2.3 always

当block执行失败,rescue才会执行;而无论block失败还是成功,always里面的任务都将会执行

- name: always
  hosts: test
  tasks:
    - block:
        - name: success
          debug:
            msg: "this is success task"
        - name: faild
          debug:
            msg: "{{ aaa }}"
      rescue:
        - name: print faile
          debug:
            msg: "Task failure"
      always:
        - name: print always
          debug:
            msg: "This task is always performed"

这个剧本定义了一个成功的任务,一个失败的任务,当有任务失败的时候会触发rescue,当所以任务执行完之后会执行always

[ansible@master ansible]$ ansible-playbook always.yaml 
[ansible@master ansible]$ ansible-playbook always.yaml 

PLAY [always] ******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.200.210]
ok: [192.168.200.200]

TASK [success] *****************************************************************
ok: [192.168.200.210] => {
    "msg": "this is success task"
}
ok: [192.168.200.200] => {
    "msg": "this is success task"
}

TASK [faild] *******************************************************************
fatal: [192.168.200.210]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'aaa' is undefined\n\nThe error appears to be in '/home/ansible/ansible/always.yaml': line 8, column 11, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n            msg: \"this is success task\"\n        - name: faild\n          ^ here\n"}
fatal: [192.168.200.200]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'aaa' is undefined\n\nThe error appears to be in '/home/ansible/ansible/always.yaml': line 8, column 11, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n            msg: \"this is success task\"\n        - name: faild\n          ^ here\n"}

TASK [print faile] *************************************************************
ok: [192.168.200.210] => {
    "msg": "Task failure"
}
ok: [192.168.200.200] => {
    "msg": "Task failure"
}

TASK [print always] ************************************************************
ok: [192.168.200.210] => {
    "msg": "This task is always performed"
}
ok: [192.168.200.200] => {
    "msg": "This task is always performed"
}

标签:语句,ok,name,192.168,ansible,Playbook,条件,msg,block
From: https://www.cnblogs.com/fsdstudy/p/18260065

相关文章

  • mybatis批量更新(where的条件越少,最好是主键,效率越高)
    <updateid="updateBatch"databaseId="sqlserver">updateT_RISK_TASK_SERVICE<trimprefix="set"suffixOverrides=","><trimprefix="TASK_REALITY_START_TIME=case......
  • [Mysql] 的基础知识和sql 语句.教你速成(上)——逻辑清晰,涵盖完整
    目录前言上篇的内容概况下篇的内容概况 数据库的分类关系型数据库常见的关系型数据库系统非关系型数据库1.键值对数据库(Key-ValueStores)特点:常见的键值对数据库:2.文档数据库(DocumentStores)特点:常见的文档数据库:3.列族数据库(Column-FamilyStores)特点:常......
  • MySQL高级SQL语句
    目录一.准备两个表二.高级查询方式1.select2.distinct3.where4.andor5.in6.between7.通配符8.like三.运用函数查询1.常用数学函数2.聚合函数3.字符串函数四.高级查询函数1.orderby2.groupby3.having4.别名设置查询4.1.字段别名4.2.表别名5.子查询语句......
  • MySQL高级SQL语句
    目录1.MySQL进阶查询1.1select1.2distinct1.3where1.4andor1.5in1.6between1.7通配符1.8like1.9ORDERBY2.MySQL数据库函数2.1数学函数2.2聚合函数2.3字符串函数2.3.1upper、lower大小写转换2.3.2concat拼接2.3.3substr字符串截取2.3.3len......
  • Ansible playbook
    目录Playbook(剧本)1.yaml1.1yaml的语法规则1.2yaml的数据类型1.3yaml的示例2.ansible-playbook2.1playbook入门2.2执行playbook2.3使用playbook安装软件3.更多示例Playbook(剧本)我们之前执行ansble是通过ad-hoc的方式来执行的,这样执行的好处就是我的任务只有1个的时......
  • shell - 流程控制语句
    if条件语句ifconditionthen #dosth.elifconditionthen #doanother.else #doothers.fi#有些人喜欢这样写,看起来更紧凑一些ifcondition;then #dosth.elifcondition;then #doanother.else #doothers.fi样例:a=10;b=20;#下面这一句,方括号是......
  • Python最常见的语句、函数,想学好Python必须要懂得!
    1.函数的概念概念写了一段代码实现了某个小功能;然后把这些代码集中到一块,起一个名字,下一次就可以根据这个名字再次使用这个代码,这就是函数。作用方便代码的重复使用。分解任务,简化程序逻辑使代码更加模块化函数分类内建函数三方函数自定义函数2.函数的基本使用简单定......
  • <编译器> 7. 中间代码 | 4. 主要语句的IR树
    1.调用output:=concat(output,s)2.数组,赋值a[i+1]:=0数组变量a[i]为a(基地址)+i*w(偏移量)3.while循环伪代码:whilecnddobodystart:ifnotcndgotodonebodygotostartdone两种实现:4.for循环:变量声明+while循......
  • 数据库常见 SQL 语句及语法
    数据库操作创建数据库语法CREATEDATABASEdatabase_name;删除数据库语法DROPDATABASEdatabase_name;选择数据库语法USEdatabase_name;表操作创建表语法CREATETABLEtable_name(column1(字段)datatype(数据类型)constraints(约束条件),column2d......
  • Shell编程之循环语句
    Shell编程之循环语句一、for循环语句for语句的结构for语句应用示例二、while循环语句while语句的结构while语句应用示例三、until循环语句until语句结构until语句应用示例注意:在Shell编程中,循环语句是一个非常重要的组成部分,它允许我们重复执行某段代码,直到满......