[Ansible系列]ansible playbook的条件语句

这篇具有很好参考价值的文章主要介绍了[Ansible系列]ansible playbook的条件语句。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

简介

when关键字

1.  when的基本使用 

2.   比较运算符

3.  逻辑运算符

4.   判断变量

5.  判断执行结果

 6.  判断路径

 7.  判断字符串

 8.  判断整除

 9.  其他

9.1  version 

9.2   subset

 9.3  superset

 9.4  in

 9.5  string  和 number

 条件判断与block

1.  block 

2.  rescue 

3.  always 

 条件判断与错误处理

1.  fail模块

2.  failed_when

3.  changed_when 

 在循环语句中使用条件语句


简介

         在写playbook时,有时候playbook的结果依赖于变量,fact或者前一个任务执行的结果,或者有的时候我们会基于上一个task执行返回的结果而决定如何执行后续的task,这个时候我们就需要用到条件语句,而在ansible-playbook中条件语句的关键字就是when。

条件语句在Ansible中使用场景:

·   在目标主机上定义一个硬限制,比如目标主机的最小内存必须达到多少,再能执行该task;

·  捕获一个命令的输出,根据命令的输出结果的不同来触发不同的task;

·  根据不同目标主机的facts,以定义不同的task;

·  根据目标主机的cpu的大小,以调优相关应用性能;

·  用于判断某个服务的配置文件是否发生变更,以确定是否重启服务。

when关键字

1.  when的基本使用 

         在ansible中,使用条件判断的关键字就是when。如在安装包的时候,需要指定主机的操作系统类型,或者是当操作系统的硬盘满了之后,需要清空文件等,可以使用when语句来做判断。when关键字后面跟着的是python的表达式,在表达式中你能够使用任何的变量或者fact,当表达式的返回结果为false,便会跳过本次任务。

示例:判断系统类型,如果是centos这使用yum安装http,如果是ubunt就使用apt安装apache2。

- hosts: test
  gather_facts: yes

  tasks:
    - name: install apache2 with os is ubuntu
      apt:
        name: apache2
        state: present
        update_cache: yes
        enabled: yes
      when: ansible_distribution == 'Ubuntu'

    - name: install http with os is centos
      yum:
        name: httpd
        state: present
      when: ansible_distribution == 'CentOS'
    
    - name: Unexpected os family
      debug:
        msg: "OS Family {{ ansible_distribution }} is not supported"
      when: not (ansible_distribution == 'CentOS' or  ansible_distribution == 'Ubuntu')

2.   比较运算符

·   == :比较两个对象是否相等,相等则返回真。可用于比较字符串和数字,两个变量也可以比较。

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

·  > :比较两个对象的大小,左边的值大于右边的值,则为真。

·  < :比较两个对象的大小,左边的值小于右边的值,则为真。

·  >= :比较两个对象的大小,左边的值大于等于右边的值,则为真。

·  <= :比较两个对象的大小,左边的值小于等于右边的值,则为真。

 基础示例:

 ·  when   ansible_machine == "x86"

·  when  max_memory >= 1024

3.  逻辑运算符

        在ansibe中,除了比较运算符,还支持逻辑运算符: 

·  and :逻辑与,当左边和右边两个表达式同时为真,则返回真。

·  or :逻辑或,当左边和右边 两个表达式任意一个为真,则返回真。

·  not :逻辑否,对表达式取反。

·  ():当一组表达式组合在一起,形成一个更大的表达式,组合内的所有表达式都是逻辑与的关系。

示例:

 # 逻辑或

·  when: ansible_distribution == "RedHat" or ansible_distribution == "Fedora"

# 逻辑与

·  when: ansible_distribution_version == "7.5" and ansible_kernel == "3.10.0‐327.el7.x86_64"

·  when:

        ‐ ansible_distribution_version == "7.5"

        ‐ ansible_kernel == "3.10.0‐327.el7.x86_64"

# 组合

when: =>

        ( ansible_distribution == "RedHat" and ansible_distribution_major_version == "7" )

        or

        ( ansible_distribution == "Fedora" and ansible_distribution_major_version == "28")

4.   判断变量

·  is   exist :判断路径是否存在,存在则为真。

·  is  not  exist :判断路径是否存在,不存在则为真。

·   defined:判断变量是否已定义,已定义则返回真。

·  undefined:判断变量是否未定义,未定义则返回真。

·  none:判断变量的值是否为空,如果变量已定义且值为空,则返回真。

示例1: 判断路径是否存在。

- hosts: test
  gather_facts: no
  vars:
    testpath1: /client
    testpath2: /route

  tasks:
    - name: 判断路径是否存在
      debug:
        msg: 'file  is  exist'
      when: testpath1 is  exists

    - name: 判断路径是否存在
      debug:
        msg: 'file  is not  exist'
      when: testpath2 is not  exists

 示例2: 判断变量是否被定义。

‐ hosts: test
  gather_facts: no
  vars:
    testvar: "test"
    testvar1:

  tasks:
    ‐ debug:
        msg: "testvar is defined"
      when: testvar is defined
    ‐ debug:
        msg: "testvar2 is undefined"
      when: testvar2 is undefined
    ‐ debug:
        msg: "testvar1 is none"
      when: testvar1 is none

5.  判断执行结果

·  sucess或succeeded:通过任务执行结果返回的信息判断任务的执行状态,任务执行成功则返回true

· failure或failed:任务执行失败则返回true

·  change或changed:任务执行状态为changed则返回true

·  skip或skipped:任务被跳过则返回true

- hosts: test
  gather_facts: no
  vars:
    doshell: true

  tasks:
    - name: 执行shell语句
      shell: cat /testdir/aaa
      register: result
      ignore_errors: true
      when: doshell

    - name: debug message1
      debug:
        msg: 'success'
      when: result is success
    
    - name: debug message2
      debug:
        msg: 'failed'
      when: result is failed

    - name: debug message3
      debug:
        msg: 'changed'
      when: result is changed

    - name: debug message4
      debug:
        msg: 'skip'
      when: result is skip

 6.  判断路径

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

·  directory :判断指定路径是否为一个目录,是则为真;

·  link :判断指定路径是否为一个软连接,是则为真;

·  mount:判断指定路径是否为一个挂载点,是则为真;

· exists: 判断指定路径是否存在,存在则为真

注意: 关于路径的所有判断均是判断主控端上的路径,而非被控端上的路径。

- hosts: test
  gather_facts: no
  vars:
    path1: "/root/ansible_test/ansible_2/hosts"
    path2: "/root/ansible_test/ansible_2"
    path3: "/usr/lib64/libedit.so.0"
    path4: "/home"
    path5: "/var/www123"

  tasks:
    - name: 判断指定路径是否为文件
      debug:
        msg: 'this path is file'
      when: path1 is file

    - name: 判断指定路径是否为目录
      debug:
        msg: 'this path is directory'
      when: path2 is directory

    - name: 判断指定路径是否为软连接
      debug:
        msg: 'this path is links'
      when: path3 is link

    - name: 判断指定路径是否为挂载点
      debug:
        msg: 'this path is mount'
      when: path4 is mount

    - name: 判断指定路径是否存在
      debug:
        msg: 'this path is exists'
      when: path2 is exists

    - name: 判断指定路径是否不存在
      debug:
        msg: 'this path is exists'
      when: path5 is not exists

 7.  判断字符串

·  lower :判断字符串中的所有字母是否为小写,是则为真;

·  upper :判断字符串中的所有字母是否都是大写,是则为真。 

 注意: 字母键可以夹杂数字,判断的时候只会判断字母

- hosts: test
  gather_facts: no
  vars:
    str1: "a12b43c"
    str2: "J32DK09UV"

  tasks:
    - name: debug lower
      debug:
        msg: 'str1 is all lowercase'
      when: str1 is lower

    - name: debug upper
      debug:
        msg: "str2 is all uppercase"
      when: str2 is upper

 8.  判断整除

·  even :判断数值是否为偶数,是则为真;

·  odd :判断数值 是否为奇数,是则为真;

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

‐ hosts: test
  gather_facts: no
  vars:
    num1: 6
    num2: 8
    num3: 15
  tasks:
    ‐ debug:
        msg: "num1 is an even number"
      when: num1 is even
      
    ‐ debug:
        msg: "num2 is an odd number"
      when: num2 is odd

    ‐ debug:
        msg: "num3 can be divided exactly by"
      when: num3 is divisibleby(3)

 9.  其他

9.1  version 

         可用于对比两个版本号的大小,或者与指定的版本号进行对比,使用语法为version("版本号","比 较操作符")

‐ hosts: test
  vars:
    ver1: 1.2
    ver2: 1.3
  tasks:
    ‐ debug:
        msg: "ver1 is greater than ver2"
      when: ver1 is version(ver2,">")
      
    ‐ debug:
        msg: "system version {{ ansible_distribution_version }} greater than 7.3"
      when: ansible_distribution_version is version("7.3","gt")

 version中使用的比较运算符:

 ·  大于: >, gt

·  大于等于: >=, ge

·  小于:<, lt

·  等于: =, ==, eq

·  不等于: !=, <>, ne

9.2   subset

         subset 判断一个list是不是另一个list的子集

- hosts: test
  gather_facts: no
  vars:
    list1: [1,2,3,4]
    list2: [2,4]
  
  tasks:
    - name: debug massage
      debug:
        msg: 'list2 in list1'
      when: list2 is subset(list1) 

 9.3  superset

         superset 判断一个list是不是另一个list的父集。

- hosts: test
  gather_facts: no
  vars:
    list1: [1,2,3,4]
    list2: [2,4]
  
  tasks:
    - name: debug massage
      debug:
        msg: 'list1 is list2 parent'
      when: list1 is superset(list2)

 9.4  in

        in 判断一个字符串是否存在于另一个字符串中,也可用于判断某个特定的值是否存在于列表中 。

‐ hosts: test
  vars:
    supported_distros:
      ‐ RedHat
      ‐ CentOS
  tasks:
    ‐ debug:
        msg: "{{ ansible_distribution }} in supported_distros"
      when: ansible_distribution in supported_distros

 9.5  string  和 number

 ·  string 判断对象是否为一个字符串,是则为真。

·  number 判断对象是否为一个数字,是则为真。

‐ hosts: test
  gather_facts: no
  vars:
    var1: 1
    var2: "1"
    var3: a
  tasks:
    ‐ debug:
        msg: "var1 is a number"
      when: var1 is number
    ‐ debug:
        msg: "var2 is a string"
      when: var2 is string
    ‐ debug:
        msg: "var3 is a string"
      when: var3 is string

 条件判断与block

1.  block 

         我们在前面使用when做条件判断时,如果条件成立则执行对应的任务。但这就面临一个问题,当我 们要使用同一个条件判断执行多个任务的时候,就意味着我们要在某一个任务下面都写一下when语 句,而且判断条件完全一样。这种方式不仅麻烦而且显得low。

        Ansible提供了一种更好的方式来解决 这个问题,即block。 在ansible中,使用block将多个任务进行组合,当作一个整体。我们可以对这一个整体做条件判断, 当条件成立时,则执行块中的所有任务:

‐ hosts: test
  tasks:
    ‐ debug:
        msg: "task1 not in block"
    ‐ block:
      ‐ debug:
          msg: "task2 in block1"
      ‐ debug:
          msg: "task3 in block1"
    when: 2 > 1

 示例1: ubuntu上配置dns服务

‐ hosts: test
  tasks:
  ‐ name: set /etc/resolv.conf
    template:
      src: resolv.conf.j2
      dest: /etc/resolv.conf
      owner: root
      group: root
      mode: 0644

  ‐ block:
    ‐ name: ensure /etc/resolvconf/resolv.conf.d/base file for ubuntu 16.04
      template:
        src: resolv.conf.j2
        dest: /etc/resolvconf/resolv.conf.d/base

    ‐ name: config dns for ubuntu 16.04
      template:
        src: resolv.conf.j2
        dest: /etc/resolv.conf
  when: ansible_distribution == "Ubuntu" and ansible_distribution_major_version == "16"

 使用block注意事项:

        1. 可以为block定义name(ansible 2.3增加的特性)
 

        2. 可以直接对block使用when,但不能直接对block使用loop

2.  rescue 

         block除了能和when一起使用之外,还能作错误处理。这个时候就需要用到rescue关键字:

‐ hosts: test
  tasks:
    ‐ block:
        ‐ shell: 'ls /testdir'

      rescue:
        ‐ debug:
            msg: '/testdir is not exists'

         在上面的例子中,当block中的任务执行失败时,则运行rescue中的任务。如果block中的任务正常执 行,则rescue的任务就不会被执行。如果block中有多个任务,则任何一个任务执行失败,都会执行 rescue。block中可以定义多个任务,同样rescue当中也可以定义多个任务。

3.  always 

        当block执行失败时,rescue中的任务才会被执行;而无论block执行成功还是失败,always中的任 务都会被执行: 

‐ hosts: test
  tasks:
    ‐ block:
        ‐ shell: 'ls /testdir'
    rescue:
      ‐ debug:
          msg: '/testdir is not exists'
    always:
      ‐ debug:
          msg: 'This task always executes'

 条件判断与错误处理

         在上面讲block的使用方法的时候,我们说block除了可以将多个任务组合到一起,还有错误处理的功 能。接下来我们继续说一说错误处理。

1.  fail模块

         在shell中,可能会有这样的需求:当脚本执行至某个阶段时,需要对某个条件进行判断,如果条件成 立,则立即终止脚本的运行。在shell中,可以直接调用"exit"即可执行退出。事实上,在playbook中 也有类似的模块可以做这件事。即fail模块。

        fail模块用于终止当前playbook的执行,通常与条件语句组合使用,当满足条件时,终止当前play的 运行。

选项只有一个:

·  msg:终止前打印出信息 

# 使用fail模块中断playbook输出
‐ hosts: test
  tasks:
    ‐ shell: echo "Just a test‐‐error"
      register: result

    ‐ fail:
        msg: "Conditions established,Interrupt running playbook"
      when: "'error' in result.stdout"

    ‐ debug:
        msg: "Inever execute,Because the playbook has stopped"

2.  failed_when

         事实上,当fail和when组合使用的时候,还有一个更简单的写法,即 failed_when ,当满足某个条件 时,ansible主动触发失败。

# 如果在command_result存在错误输出,且错误输出中,包含了`FAILED`字串,即返回失败状态:
‐ name: this command prints FAILED when it fails
  command: /usr/bin/example‐command ‐x ‐y ‐z
  register: command_result
  failed_when: "'FAILED' in command_result.stderr"

也可以直接通过 fail 模块和 when 条件语句,写成如下:

‐ name: this command prints FAILED when it fails
  command: /usr/bin/example‐command ‐x ‐y ‐z
  register: command_result
  ignore_errors: True

‐ name: fail the play if the previous command did not succeed
  fail: msg="the command failed"
  when: " command_result.stderr and 'FAILED' in command_result.stderr"

        ansible一旦执行返回失败,后续操作就会中止,所以failed_when通常可以用于满足某种条件时 主动中止playbook运行的一种方式。

        ansible默认处理错误的机制是遇到错误就停止执行。但有些时候,有些错误是计划之中的。我 们希望忽略这些错误,以让playbook继续往下执行。这个时候就可以使用 ignore_errors 忽略 错误,从而让playbook继续往下执行。

3.  changed_when 

        当我们控制一些远程主机执行某些任务时,当任务在远程主机上成功执行,状态发生更改时,会返回 changed状态响应,状态未发生更改时,会返回OK状态响应,当任务被跳过时,会返回skipped状态 响应。我们可以通过 changed_when 来手动更改 changed 响应状态。示例如下: 

- hosts: test
  gather_facts: no

  tasks:
    - name: command
      shell: ls -l /home
      register: result
      changed_when: result.rc == 2  #只有该条task执行以后,result.rc的值为2时,才
会返回changed状态(此时实际上result.rc == 0)

 在循环语句中使用条件语句

 示例:只有当系统为ubuntu的时候才创建相应的用户文章来源地址https://www.toymoban.com/news/detail-778807.html

[root@clinet ansible_2]# cat vars_file/file1.yml 
users:
  - name: bob
    shell: /sbin/nologin
    home: /home/bob
    state: present
 
  - name: alice
    home: /tmp/alice
    state: present
 
  - name: tom
    shell: /bin/bash
    state: present

[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml 
- hosts: mdb
  gather_facts: no
  vars_files:
    - /root/ansible_test/ansible_2/vars_file/file1.yml
  tasks:
    - name: create user group
      group:
        name: "{{ item['name'] }}"
        state: "{{ item['state'] }}"
      with_items: "{{ users }}"
      when: : ansible_distribution == "Ubuntu"
 
    - name: create user with_items
      user:
        name: "{{ item['name'] }}"
        shell: "{{ item['shell'] |default(omit) }}"
        home: "{{ item['home'] |default(omit) }}"
        state: "{{ item['state'] }}"
      with_items: "{{ users }}"
      when: : ansible_distribution == "Ubuntu"
[root@clinet ansible_2]# 

到了这里,关于[Ansible系列]ansible playbook的条件语句的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【playbook】Ansible的脚本----playbook剧本

    (1) Tasks :任务,即 通过task调用ansible的模板将多个操作组织在一个playbook中运行 (2) Variables :变量 (3) Templates :模板 (4) Handlers :处理器, 当changed状态条件满足时,(notify)触发执行的操作 (5) Roles :角色 在ansible服务器主机,给远程被管理主机制作安装Apach

    2024年02月14日
    浏览(38)
  • 【Ansible】Ansible自动化运维工具之playbook剧本

      简单来说,playbooks是一种简单的配置管理系统与多机器部署系统的基础。与现有的其他系统有不同之处,且非常适合复杂应用的部署。   Playbooks 可用于声明配置,更强大的地方在于,playbooks可以编排有序的去执行过程,甚至做到多组机器间来回有序的执行特别指定的

    2024年02月14日
    浏览(30)
  • Ansible之playbooks剧本

    (1)playbooks是ansible用于配置,部署,和管理被控节点的剧本。 (2)通过playbooks的详细描述,执行其中的tasks,可以让远端主机达到预期的状态。playbooks是由一个或多个”play”组成的列表。 当对一台机器做环境初始化的时候往往需要不止做一件事情,使用playbooks。 (3)通过

    2024年02月09日
    浏览(38)
  • Ansible playbook ----- 剧本

    playbooks 本身由以下各部分组成 (1)Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行 (2)Variables:变量 (3)Templates:模板 (4)Handlers:处理器,当changed状态条件满足时,(notify)触发执行的操作 (5)Roles:角色 //示例: vim test1.yaml ---    

    2024年02月10日
    浏览(35)
  • [ansible] playbook角色

    Roles又称为角色,playbook被称为剧本。Roles角色是自1.2版本之后引入的新特性,用于层次性、结构化的组织剧本   roles能够根据层次型结构自动装载变量文件、任务集、以及触发的动作等,要使用roles只需要在剧本中使用include命令引入即可 简单的来说,roles就是分别将变量、文

    2024年02月21日
    浏览(34)
  • [ansible] playbook运用

        2.1 基础变量的定义与引用 在yaml文件中,我们可以在初始配置的模块中用var去定义变量的存在,变量的格式为key:value,以此来确定该变量在剧本中的存在   2.2 引用fact信息中的变量   首先我们知道  使用 ansible 组  -m setup   可以收集该组中所有的节点信息 , 所以setup中

    2024年02月20日
    浏览(28)
  • Ansible playbook编写

    Tasks :任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行 Variables :变量 Templates :模板 Handlers :处理器,当changed状态条件满足时,(notify)触发执行的操作 Roles :角色

    2024年02月14日
    浏览(28)
  • Ansible之Playbook

    1.简介 Playbook 也通常被⼤家翻译成剧本。 可以认为它是Ansible ⾃定义的⼀⻔语⾔(可以将 Playbook ⽐作Linux 中的 shell,⽽ Ansible 中的 Module 可以⽐作为 Linux 中的各种命令。) 2.Play的定义 PlayBook遵循YAML 的语法格式。 由于Playbook 是由⼀个或者多个Play组成,那么如果我们熟悉Play的写

    2024年02月11日
    浏览(31)
  • 使用Ansible中的playbook

    目录 1.Playbook的功能 2.YAML 3.YAML列表 4.YAML的字典 5.playbook执行命令 6.playbook的核心组件 7.vim 设定技巧 示例 playbook 是由一个或多个play组成的列表 Playboot 文件使用YAML来写的 #简介# 是一种表达资料序列的格式,类似XML #特点# 1、可读性好 2、和脚本语言交互性号 3、易于实现 4、适用

    2024年02月06日
    浏览(26)
  • Ansible之playbook剧本

    playbook 是 ansible 用于配置,部署,和管理被控节点的剧本。通过 playbook 的详细描述,执行其中的一系列 tasks ,可以让远端主机达到预期的状态。playbook 就像 Ansible 控制器给被控节点列出的的一系列 to-do-list ,而被控节点必须要完成。也可以这么理解,playbook 字面意思,即剧

    2024年02月09日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包