Ansible基础五——条件语句、循环语句、handlers、任务失败处理

news/2024/11/6 13:59:32/

文章目录

  • 一、 循环语句
    • 1.1 单量循环
    • 1.2 多量循环
    • 1.3 老版本用法
    • 1.4 loop+register
  • 二、条件判断
    • 2.1 根据变量状态判断
    • 2.2 根据变量是否存在判断
    • 2.3 根据事实判断
    • 2.4 多条件判断
      • 2.4.1 and用法
      • 2.4.2 or用法
    • 2.5 循环判断
    • 2.6 根据上个任务结果判断
  • 三、handlers处理程序
  • 四、任务失败处理方法
    • 4.1 忽略失败任务
    • 4.2 强制执行失败任务

一、 循环语句

  • 可以使用item循环变量+loop模块组合使用,实现普通循环。
  • 常用于一键操作,比如一键安装所有组件服务。

1.1 单量循环

  • 只对一个变量进行循环

1.一键停止受控机上的两个服务。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 一键操作hosts: 192.168.130.161tasks:- name:  停止服务service:name: "{{ item }}"     ##引用循环变量。state: stoppedloop:              ##使用loop模块,要操作的对象列表。- postfix- crond 

在这里插入图片描述
2.推荐写法,定义变量,一键启动受控机上的两个服务。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 一键操作vars:service_name:         ##定义变量,填写操作对象列表。- crond- postfixhosts: 192.168.130.161tasks:- name:  停止服务service:name: "{{ item }}"state: startedloop: "{{ service_name }}"    ##模块直接引用变量。

在这里插入图片描述
3.使用变量文件定义,停止受控机上的两个服务。
在这里插入图片描述
在这里插入图片描述

1.2 多量循环

  • 对多个变量进行循环。

1.在受控机上创建两个用户,baimu1和baimu2,属组分别是root、qingjun。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 一键操作hosts: 192.168.130.161tasks:- name:  停止服务user:name: "{{ item.name }}"     ##循环变量。group: "{{ item.group  }}"state: presentloop:           - name: baimu1group: root- name: baimu2group: qingjun

在这里插入图片描述

1.3 老版本用法

  • 之前版本的循环是通过以下字段来实现的。
循环关键字描述
with_items行为与简单列表的loop关键字相同,例如字符串列表或散列/字典列表。但与loop不同的是,如果为with_items提供了列表的列表,它们将被扁平化为单级列表。循环变量item保存每次迭代过程中使用的列表项。
with_file此关键字需要控制节点文件名列表。循环变量item在每次迭代过程中保存文件列表中相应文件的内容。
with_sequence此关键字不需要列表,而是需要参数来根据数字序列生成值列表。循环变量item在每次迭代过程中保存生成的序列中的一个生成项的值。

1.列出受控机的/opt目录下文件内容。
在这里插入图片描述
2.主控机编写剧本,验证查看。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 一键操作hosts: 192.168.130.161vars:qingjun:                ##定义变量qingjun。- /opt/baimu.txt- /opt/baimu1.txt- /opt/baimu2.txttasks:- name:  获取文件内容shell: |cat "{{ item  }}"    ##循环变量。with_items: "{{ qingjun  }}"    ##使用with_items循环模块,应用变量qingjun,作用与loop模块相似。register: jis          ##将获取的结果注册到变量jis里去。- debug: var=jis    ##将jis变量内容打印出来。

在这里插入图片描述

1.4 loop+register

  • 配合打印循环。

1.打印出“zhangsan喜欢吃牛排”、“lisi喜欢吃牛排”的的信息。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 一键操作hosts: 192.168.130.161tasks:- name:  获取文件内容shell: |echo  "{{ item  }}" 特别喜欢吃牛排!      ##循环变量,依次跟局loop循环模块列表来执行。loop:- zhangsan- lisiregister: qingjun      ##将获取的结果注册到循环变量里去。- name: Print  debug: var: qingjun         ##打印输出。

在这里插入图片描述
2.从打印的结果再取值。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 一键操作hosts: 192.168.130.161tasks:- name:  获取文件内容shell: |echo  "{{ item  }}" 特别喜欢吃牛排!loop:- zhangsan- lisiregister: qingjun- name: Print  debug: msg: |"结果是:{{ item.start  }}"     ##取results里面的start的值,再进行打印。loop: "{{ qingjun['results'] }}"     ##从打印的整体结果里卖弄再取results部分里面的值。##loop: "{{ qingjun.results }}"  ##第二种写法。

在这里插入图片描述
在这里插入图片描述

二、条件判断

  • 使用when语句来进行条件判断,若条件满足,则运行任务;若条件不满足,则跳过任务。
  • when语句放在任务名称和模块(及模块参数)的后面。
标识符示例
等于(值为字符串)ansible_machine == “x86_64”
等于(值为数字)max_memory == 512
小于min_memory < 128
大于min_memory > 256
小于等于min_memory <= 256
大于等于min_memory >= 512
不等于min_memory != 512
变量存在min_memory is defined
变量不存在min_memory is not defined
布尔变量是True。1、True或yes的求值为Truememory_available
布尔变量是False。0、False或no的求值为Falsenot memory_available
第一个变量的值存在,作为第二个变量的列表中的值ansible_distribution in supported_distros

2.1 根据变量状态判断

1.根据某个变量的取值状态判断是否执行某个任务。这里根据变量service_status是否等于true来判断是否要安装httpd服务。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161vars:service_status: true    ##定义一个变量。tasks:- name: 判断apache是否安装yum:name: httpdstate: presentwhen: service_status      ##判断这个变量,条件语句里不能存在{{ }}引用符号。        

在这里插入图片描述

2.2 根据变量是否存在判断

1.根据上下文是否定义某个变量来判断是否执行某个任务。这里根据是否定义了变量service_name来判断是否要安装httpd服务。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161tasks:- name: 判断apache是否安装yum:name: "{{ service_name }}"    ##虽然引用变量,但此变量未被定义。state: absentwhen: service_name is defined

在这里插入图片描述

2.变量service_name为空,则不执行任务。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161vars:service_name: " "          ##定义变量,但值为空。tasks:- name: 判断apache是否安装yum:name: "{{ service_name }}"    ##引用变量。state: absentwhen: service_name is defined        ##判断变量是否为空,为空则不执行任务。        

在这里插入图片描述
3.变量存在,执行任务,卸载httpd。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161vars:service_name:- httpdtasks:- name: 判断apache是否安装yum:name: "{{ service_name }}"state: absentwhen: service_name is defined

在这里插入图片描述

2.3 根据事实判断

  • 根据取出的事实来判断是否在对受控机执行任务。

1.先取受控机的事实相关参数,比如这里我就根据系统版本来判断。

[root@localhost ansible]# ansible all -m setup -i inventory.ini |less

在这里插入图片描述
2.当系统版本等于7.5时,才执行条件循环语句,依次停止变量列表中的服务。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161vars:service_name:- firewalldtasks:- name: 判断apache是否安装service:name: "{{ item }}"state: startedloop: "{{ service_name  }}"when: ansible_facts['distribution_version'] == "7.5"

在这里插入图片描述

2.4 多条件判断

  • 使用and表示所有条件满足时,才执行任务。
  • or表示满足任意一个条件时,就可执行任务。

2.4.1 and用法

1.当系统版本为7.5,且python版本大于2.7时才会执行任务。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161vars:service_name:- firewalldtasks:- name: 判断apache是否安装service:name: "{{ item }}"state: stoppedloop: "{{ service_name  }}"when: ansible_facts['distribution_version'] == "7.5" and ansible_facts['python_version'] > 2.7

在这里插入图片描述
2.也可以多行写法。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161vars:service_name:- firewalldtasks:- name: 判断apache是否安装service:name: "{{ item }}"state: startedloop: "{{ service_name  }}"when: - ansible_facts['distribution_version'] == "7.5"- ansible_facts['python_version'] > 2.7

在这里插入图片描述

2.4.2 or用法

1.当系统版本为7.5,或python版本大于3时才会执行任务。我这里只满足了第一个条件,所以可以执行任务。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161vars:service_name:- firewalldtasks:- name: 判断apache是否安装service:name: "{{ item }}"state: startedloop: "{{ service_name  }}"when: ansible_facts['distribution_version'] == "7.5" or ansible_facts['python_version'] > 3

在这里插入图片描述
2.也可以多行写法。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161vars:service_name:- firewalldtasks:- name: 判断apache是否安装service:name: "{{ item }}"state: stoppedloop: "{{ service_name  }}"when: ansible_facts['distribution_version'] == "7.5"oransible_facts['python_version'] > 3

在这里插入图片描述

2.5 循环判断

  • 结合loop模块实现循环判断。

1.循环事实里的条件,条件满足执行任务。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161tasks:- name: 判断apache是否安装yum:name: httpdstate: presentloop: "{{ ansible_facts['mounts'] }}"  ##取事实里的mounts内的内容,其下面有多个挂载点,根据when条件来判断是否执行任务。when: - item.mount == "/"           ##ansible_facts['mounts']['mount'] 的值是否为“/”。- item.size_available > 700    ##ansible_facts['mounts'][’size_avaliable‘]的值是否大于700.

在这里插入图片描述

2.6 根据上个任务结果判断

  • 根据上个任务结果来判断是否要执行后面的任务。
  • 比如,第一个任务是安装服务,若是安装成功则执行第二步启动服务;若是安装失败,就不需要继续执行任务了。

1.rc是任务执行后输出的一个值,当rc=0时,代表任务执行成功。
在这里插入图片描述
2.当第一步安装httpd服务成功时,会输出rc=0,之后才会执行第二步。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161tasks:- name: 判断服务是否安装yum:name: httpdstate: presentignore_errors: yes   ##任务执行失败直接跳过,可以继续执行后面任务。register: qingjun     ##获取任务输出的结果,讲结果注册到变量qingjun里去。- name: 启动服务service:name: httpdstate: startedwhen: - qingjun.rc == 0   ##变量qingjun里的内容有个rc值,rc=0时才会执行第二步。

在这里插入图片描述

三、handlers处理程序

基本了解:

  • handlers和tasks功能一样,也是用于处理任务的,只是它常用于更改服务配置文件后需要重启服务这种场景常用。
  • handlers和tasks是同级别,需要在tasks任务里定义notify语句,当notify语句所在的任务结果显示为changed时,才会触发handlers任务。

注意事项:

  1. 当tasks中有多个任务定义notify语句时,触发任务会按照handlers任务里的顺序来执行。
  2. 若tasks中定义多个notify语句具备相同的名称时,最终只会触发一个handlers任务。
  3. 即使有多个任务通知处理程序,该处理程序依然仅运行一次。如果没有任务通知处理程序,它就不会运行。

1.主控机的playbook目录下有个专门存放受控机配置文件的目录,此时配置文件http.conf是原文件,监听端口未被修改。
在这里插入图片描述
2.编写playbook,当notify所在的任务发生了改变就会触发handlers任务,从而重启服务。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161tasks:- name: 判断服务是否安装yum:name: httpdstate: presentignore_errors: yes- name: 更改服务配置文件template:src: ./file/httpd.conf               ##将主控机上的文件传到受控机上,若文件内容发生改变则触发任务。dest: /etc/httpd/conf/httpd.confnotify:- restart httpd   ##需要与handlers名称一致。- name: 启动服务service:name: httpdstate: startedhandlers:- name: restart httpd     ##需与notify名称一致。service:name: httpdstate: restarted

3.执行playbook,此时主控机上的http.conf文件内容未被修改,传到受控机上也不会出现覆盖动作,所以notify是直接返回的ok,此时不触发handlers任务。
在这里插入图片描述
4.访问受控机安装的httpd服务,默认80端口。
在这里插入图片描述

5.此时修改主控机上的http.conf文件内容,将监听端口改成88,执行playbook会触发handlers任务,因为两边文件内容不一样,传过去会覆盖受控机上的原文件。
在这里插入图片描述
在这里插入图片描述
6.再次访问受控机安装的httpd服务,需要88端口。
在这里插入图片描述

四、任务失败处理方法

4.1 忽略失败任务

  • 添加参数ignore_errors: yes,可以让playbook在任务失败时继续执行。

1.安装一个不存在的任务会失败,添加ignore_errors会忽略继续执行后面任务。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161tasks:- name: 判断服务是否安装yum:name: httpdsstate: presentignore_errors: yes- name: 更改服务配置文件template:src: ./file/httpd.confdest: /etc/httpd/conf/httpd.confnotify:- restart httpd- name: 启动服务service:name: httpdstate: startedhandlers:- name: restart httpdservice:name: httpdstate: restarted

在这里插入图片描述

4.2 强制执行失败任务

  • 添加参数force_handlers: yes,针对性的适用handlers处理程序的场景。
  • 正常情况下,当某一个任务执行失败时就会停止其他程序处理;当使用此参数时,即时前面有任务执行失败,后面的handlers也会在notify函数所在的任务发生改变时正常执行。

1.中间的启动服务步骤会失败,但不影响后面的handlers任务正常执行。当修改配置文件监听端口为90,notify语句会触发handlers执行程序任务,从而重启服务,可以使用90端口访问web页。

[root@localhost playbook]# cat qingjun.yml 
---
- name: 安装服务hosts: 192.168.130.161force_handlers: yestasks:- name: 判断服务是否安装yum:name: httpdstate: present- name: 更改服务配置文件template:src: ./file/httpd.confdest: /etc/httpd/conf/httpd.confnotify:- restart httpd- name: 启动服务service:name: httpdsstate: startedhandlers:- name: restart httpdservice:name: httpdstate: restarted

在这里插入图片描述
2.使用受控机ip:90访问web。
在这里插入图片描述


http://www.ppmy.cn/news/169286.html

相关文章

GitLab从旧服务器迁移到新服务器(空间不足,gitlab安装报错)

注意事项&#xff1a;迁移前首先要保证新旧服务器上的GitLab版本号一致&#xff0c;而且gitlab的包要符合安装的系统gitlab安装&#xff0c;系统与安装包不一致导致的安装错误。 1.查看当前GitLab版本 cat /opt/gitlab/embedded/service/gitlab-rails/VERSION显示为 12.5.5。…

C++11:智能指针

目录 1、智能指针含义 2、智能指针的分类 1、智能指针含义 &#xff08;1&#xff09;C智能指针是一种用于管理动态内存的指针&#xff0c;可以自动进行内存管理&#xff0c;避免了手动管理内存所带来的问题。 &#xff08;2&#xff09;智能指针的核心思想是资源分配即初始…

IP地址、子网划分

目录 一、IP地址1.IP地址表示2.分类IP地址3.无分类编址 CIDR4.特殊IP地址 二、子网划分1.子网、子网掩码、子网划分VLSM2.网络地址、广播地址3.示例1&#xff1a;等分为两个子网3.1 划分前&#xff1a;3.2 划分后&#xff1a; 4.示例2&#xff1a;等分为四个子网3.1 划分前&…

Arthas 的简单使用

安装 Arthas 根据操作系统&#xff0c;从Arthas 官方 GitHub 仓库下载相应的 Arthas 安装包。 执行 Arthas 打开命令行工具&#xff0c;进入 Arthas 安装目录并执行以下命令&#xff1a; java -jar arthas-boot.jar 在启动时&#xff0c;Arthas 会自动检测到本机上所有运行…

2021年全球与中国净水器行业市场规模及发展前景分析

2021年全球与中国净水器行业市场规模及发展前景分析 本报告研究全球与中国市场净水器的发展现状及未来发展趋势&#xff0c;分别从生产和消费的角度分析净水器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品…

反渗透、超滤和电渗析技术的区别

净水器的品牌系列比较多&#xff0c;大多采用两种过滤技术&#xff0c;即反渗透和超滤&#xff0c;所以&#xff0c;净水器产品也按技术分为两类&#xff0c;其一是以RO反渗透净水器为代表的纯净水机&#xff0c;另一种是以超滤机为代表的超滤净水机。 反渗透 反渗透&#xf…

小米净水器更换滤芯步骤和水龙头亮黄灯的解决办法

【开篇序言】 众所周知&#xff0c;无论何种品牌的净水器&#xff0c;滤芯都是有一定使用寿命的&#xff0c;而不是一次性安装可永久使用&#xff0c;如果遇到无需换滤芯这类宣布&#xff0c;请远离&#xff0c;不靠谱。换滤芯&#xff0c;小米净水器也不例外&#xff0c;小米…

小米净水器更换php教程,小米净水器如何更换滤芯 小米净水器怎么连接手机

受环境污染的影响&#xff0c;现在的水质也是逐渐变差&#xff0c;未经过净化的水&#xff0c;很多都是无法直接饮用的&#xff0c;因此越来越多的家庭选择在家里安装上净水器&#xff0c;确保饮用水的安全。小米净水器在众多品牌中脱颖而出&#xff0c;那小米净水器如何更换滤…