ansible————task控制

ops/2024/10/24 12:21:40/

一、loop循环

当某一个操作需要多次执行的时候,就需要用到循环

1、循环语句

安装多个安装包,启动多个应用

[root@control ansible_manage]# cat play_book/loop.yaml 
---
- name: loop exercisehosts: manage1vars_files:- var/loop_var.yamltasks:- name: install pkgyum:name: "{{ item }}"state: latestloop: "{{ web_related_pkg }}"- name: start serviceservice:name: "{{ item }}"enabled: truestate: startedloop:  "{{ web_related_service }}"

循环loop使"{{ item }}"位置的变量进行循环,loop位置的变量则使在变量文件中的变量

[root@control ansible_manage]# cat play_book/var/loop_var.yaml 
web_related_pkg:- httpd- firewalld- mariadb-server- vsftpd
web_related_service:- httpd- firewalld- vsftpd- mariadb

运行

[root@control ansible_manage]# ansible-playbook play_book/loop.yaml

2、loop循环和变量矩阵

user:   - name: jinnagroups: nana- name: cuigroups: nana

有"-"的为同一个级别

二、条件判断

使用场景

  • 基于可用内存,筛选主机

  • 基于命令输出,

  • 根据facts变量决定使用什么文件

  • 根据cpu的数量来调优web服务器

  • 比较register变量来决定是否一个服务状态要改变

when语句

写一个循环,当httpd没有安装的时候,就安装httpd

[root@control ansible_manage]# cat play_book/when.yaml 
---
- name: loop exercisehosts: manage1vars:my_service: httpdtasks:
## 当my_service没有被定义的时候执行- name: debug httpddebug:var: my_servicewhen: my_service is not defined
## 当service没有被定义的时候执行- name: debug httpd 2debug:var: my_servicewhen: service is not defined

根据表述可得知,第二个debug应该会被执行

[root@control ansible_manage]# ansible-playbook play_book/when.yamlPLAY [loop exercise] ********************************************************************************************TASK [Gathering Facts] ******************************************************************************************
ok: [manage1]TASK [debug httpd] **********************************************************************************************
skipping: [manage1]TASK [debug httpd 2] **********************************************************************************************
ok: [manage1] => {"my_service": "httpd"
}PLAY RECAP ******************************************************************************************************
manage1                    : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=
0

结果可用看到,第一个debug模块没有被执行

判断语句的判断

  • [变量] == [值]

  • [变量] < [值]

  • [变量] > [值]

  • [变量] <= [值]

  • [变量] >= [值]

  • [变量] != [值]

  • [变量] is defined:什么被定义

  • [变量] is not defined:什么没有被定义

  • true、yes、1:可用直接定义布尔值,执行

  • false、no、0:可用直接定义布尔值,不执行

  • [单变量] in [变量矩阵]:用在变量矩阵中,单变量在变量矩阵中的时候,执行

多重判断语句

and:两个条件都要满足

or:只需要满足一个

[root@control ansible_manage]# cat play_book/when2.yaml 
---
- name: loop exercisehosts: manage1vars:my_service: httpdmy_service2: nanatasks:
## 当my_service没有被定义或者my_service被定义的时候执行- name: debug httpddebug:var: my_servicewhen: my_service is not defined or my_service2 is defined
## 当service没有被定义和my_service2被定义的时候执行- name: debug httpd 2debug:var: my_servicewhen: service is not defined and my_service2 is defined

 运行

[root@control ansible_manage]# ansible-playbook play_book/when2.yaml PLAY [loop exercise] ********************************************************************************************TASK [Gathering Facts] ******************************************************************************************
ok: [manage1]TASK [debug httpd] **********************************************************************************************
ok: [manage1] => {"my_service": "httpd"
}TASK [debug httpd 2] ********************************************************************************************
ok: [manage1] => {"my_service": "httpd"
}PLAY RECAP ******************************************************************************************************
manage1                    : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=
0

可以看到两个debug模块都执行了

三、handlers

是一个特殊的处理器,作用是检测tasks的状态

当tasks出现changed状态的时候,可用做对应的操作

大量用于服务的重启

1、handlers控制服务的重启

当firewalld关闭的时候,重新启动firewalld

[root@control ansible_manage]# cat  play_book/handlers.yaml
---
- name: handlers exercisehosts: manage1tasks:- name: use systemd stop firewalldsystemd:name: firewalldstate: stoppednotify:- restart firewalld## 必须有在上方定义了notify,handlers才能生效handlers: 
## name的名字对应上方notify定义的名字- name: restart firewallddebug:msg: the firewalld is down, now open- name: restart firewalldservice:name: firewalldstate: restarted

开启manage1的防火墙

[root@manage1 ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemonLoaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; preset: enabled)Active: active (running) since Wed 2024-04-03 15:10:36 CST; 4s agoDocs: man:firewalld(1)Main PID: 109653 (firewalld)Tasks: 2 (limit: 10684)Memory: 25.1MCPU: 274msCGroup: /system.slice/firewalld.service└─109653 /usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopidApr 03 15:10:36 manage1 systemd[1]: Starting firewalld - dynamic firewall daemon...
Apr 03 15:10:36 manage1 systemd[1]: Started firewalld - dynamic firewall daemon.

运行ansible-playbook

[root@control ansible_manage]# ansible-playbook play_book/handlers.yaml PLAY [handlers exercise] ***************************************************************************************************TASK [Gathering Facts] *****************************************************************************************************
ok: [manage1]TASK [use systemd stop firewalld] ******************************************************************************************
changed: [manage1]RUNNING HANDLER [restart firewalld] ****************************************************************************************
ok: [manage1] => {"msg": "the firewalld is down, now open"
}PLAY RECAP *****************************************************************************************************************
manage1                    : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

当模块定义了notify,当状态发生改变的时候,就会启动handlers对firewalld进行重启

2、handlers强制执行

handlers只有在这个tasks执行完毕之后,才会执行,如果中间有错误,就无法执行

但是在前面定义一个force_handlers: yes,即使出现错误,也可以执行成功

[root@control ansible_manage]# cat play_book/handlers1.yaml 
---
- name: handlers exercisehosts: manage1
## force_handlers这参数可以定义即使下面的有错误,定义了notify的模块也会通知handlers,进行操作force_handlers: yestasks:- name: use systemd stop firewalldcommand: /bin/truenotify: restart the database- name: a tasj which fails because the package doesn't existyum:name: nnnnnnnnn  ## 这个软件不存在,就会有报错state: latsehandlers:- name: restart the databasedebug:msg: the firewalld is down, now open- name: restart the databaseservice:name: firewalldstate: restarted

 运行playbook四

[root@control ansible_manage]# ansible-playbook play_book/handlers1.yaml PLAY [handlers exercise] ***************************************************************************************************TASK [Gathering Facts] *****************************************************************************************************
ok: [manage1]TASK [use systemd stop firewalld] ******************************************************************************************
changed: [manage1]TASK [a tasj which fails because the package doesn't exist] ****************************************************************
fatal: [manage1]: FAILED! => {"changed": false, "msg": "value of state must be one of: absent, installed, latest, present, removed, got: latse"}RUNNING HANDLER [restart the database] *************************************************************************************
ok: [manage1] => {"msg": "the firewalld is down, now open"
}PLAY RECAP *****************************************************************************************************************
manage1                    : ok=3    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

四、ansible的错误控制

ansible playbook中会写一些预期错误的操作

比如:备份,当空间不够的时候,会报错,就会导致备份不成功

1、忽略task的错误:ignore_errors

使用ignore_errors就能忽略这个错误

写一个yaml文件,使用yum模块安装两个服务,其中第一个服务是随便写的,没有这个服务,第二个服务是httpd

正常情况下,第一个安装包安装失败,就会停止playbook,但是使用ignore_errors可以忽略第一个错误,安装第二个软件包

[root@control ansible_manage]# cat play_book/ignore_erors.yaml 
---
- name: ignore_errors playhosts: manage1tasks:- name: install pkgyum:name: nanananananstate: presentignore_errors: yes- name: install httpdyum:name: httpdstate: present

运行playbook

[root@control ansible_manage]# ansible-playbook play_book/ignore_erors.yaml PLAY [ignore_errors play] **************************************************************************************************TASK [Gathering Facts] *****************************************************************************************************
ok: [manage1]TASK [install pkg] *********************************************************************************************************
fatal: [manage1]: FAILED! => {"changed": false, "failures": ["No package nananananan available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}
...ignoringTASK [install httpd] *******************************************************************************************************
ok: [manage1]PLAY RECAP *****************************************************************************************************************
manage1                    : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1   

2、标记tasks状态:failed_when

failed_when一般用在ansible和脚本的结合

ansible和脚本结合可以使用shell模块

ansible执行脚本,每一次的直接结果都是changeed(只有在个别情况下才会报错,比如,没有调用权限,脚本不存在等),无法判断脚本是否运行成功

控制failed状态

可以使用register变量和failed_when结合进行对tasks状态的控制

可以通过标准输出来控制脚本运行的状态

1、简单写一个脚本,并赋予权限

[root@manage1 ~]# cat install_web.sh 
#!/bin/bash
## install webyum -y install httpd &>> /dev/null
{if [ "$?" == 0 ]thenstate=successelsestate=failfi
}
echo success
# start httpd
systemctl start httpd &>> /dev/null
systemctl enable httpd  &>> /dev/null
[root@manage1 ~]# chmod +x install_web.sh 

当执行脚本的时候,如果执行成功,返回的结果是success,失败返回的结果就是fail

2、写一个安装web的playbook

[root@control ansible_manage]# cat play_book/install_web.yaml 
---
- name: ignore_errors playhosts: manage1tasks:- name: install pkgshell: /root/install_web.shregister: command_resultfailed_when: " 'success' not in command_result.stdout "- name: debug command_resultdebug:var: command_result

使用register变量,如果在变量command_result.stdout中出现success,则表示脚本运行成功

failed_when: " 'success' not in command_result.stdout "是指,如果字段success不在变量command_result.stdout中,就不会报错

3、运行

[root@control ansible_manage]# ansible-playbook play_book/install_web.yaml PLAY [ignore_errors play] **************************************************************************************************TASK [Gathering Facts] *****************************************************************************************************
ok: [manage1]TASK [install pkg] *********************************************************************************************************
changed: [manage1]TASK [debug command_result] ************************************************************************************************
ok: [manage1] => {"command_result": {"changed": true,"cmd": "/root/install_web.sh","delta": "0:00:01.139397","end": "2024-04-03 17:49:18.804363","failed": false,"failed_when_result": false,"msg": "","rc": 0,"start": "2024-04-03 17:49:17.664966","stderr": "","stderr_lines": [],"stdout": "success","stdout_lines": ["success"]}
}PLAY RECAP *****************************************************************************************************************
manage1                    : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

task状态是changes状态,表示脚本执行成功

从debug模块可以看出,register变量中有command_result.stdout中有seccess字段

控制task的changed状态

只要使用了command模块,就会出现changed的状态

可以使用changed_when: false可以强制改变changed模块,为ok

changed_when: true将状态改变为changed

1、写一个command模块的playbook

[root@control ansible_manage]# cat play_book/change_changed.yaml 
---
- name: ignore_errors playhosts: manage1tasks:- name: commandcommand: echo "I love you"changed_when: false

2、执行

[root@control ansible_manage]# ansible-playbook play_book/change_changed.yaml PLAY [ignore_errors play] **************************************************************************************************TASK [Gathering Facts] *****************************************************************************************************
ok: [manage1]TASK [command] *************************************************************************************************************
ok: [manage1]PLAY RECAP *****************************************************************************************************************
manage1                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

可以看到状态不是changed,而是ok

如果把changed_when: false去掉,则就是changed的状态

root@control ansible_manage]# ansible-playbook play_book/change_changed.yaml PLAY [ignore_errors play] **************************************************************************************************TASK [Gathering Facts] *****************************************************************************************************
ok: [manage1]TASK [command] *************************************************************************************************************
changed: [manage1]PLAY RECAP *****************************************************************************************************************
manage1                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

五、block、rescue、always

block、rescue、always都可以定义一组task

  • block:定义一组task

  • rescue:当block块内的task执行失败的时候执行

  • always:无论上面两个执行成功还是失败,都执行

[root@control ansible_manage]# cat play_book/change_changed.yaml
---
- name: ignore_errors playhosts: manage1tasks:- name: use commandblock:- name: command echocommand: echo "sdasdddd"- name: command: echo "csdd sdsdd a"rescue:- name: commandcommand: echo "hahahahahha"- name: commandcommand: echo "aaaaaaaaa"always:- name: commandcommand: echo "aaaaaaaaaa"


http://www.ppmy.cn/ops/127699.html

相关文章

深入理解计算机系统阅读笔记-第十章

第十章 虚拟存储器 虚拟存储器是硬件异常、硬件地址翻译、主存、磁盘文件和内核软件的完美交互&#xff0c;它为每个进程提供了一个大的、一致的、私有地址空间。通过一个很清晰的机制&#xff0c;虚拟存储器 提供了三个重要能力&#xff1a; 1、它将主存看成是一个存储在磁盘…

【数据结构与算法】走进数据结构的“时间胶囊”——栈

大家好&#xff0c;我是小卡皮巴拉 文章目录 目录 引言 一.栈的基本概念 1.1 定义 1.2 特性 1.3 基本操作 二.栈的实现方式 2.1 顺序栈 2.2 链栈 三.顺序栈的实现 定义顺序栈的结构 初始化 入栈 检查栈是否为空 出栈 销毁 四.链栈的实现 定义链栈的结构 初始…

如何给SaaS应用做安全

SaaS&#xff08;软件即服务&#xff09;应用在过去几年中得到了迅速发展。截至2023年&#xff0c;全球已有超过30,000家SaaS初创公司。SaaS应用程序已成为无数行业在线业务的重要组成部分和首要选择。凭借着简化的流程&#xff0c;便捷的交付和可扩展性&#xff0c;越来越多的…

JavaEE----多线程(二)

文章目录 1.进程的状态2.线程的安全引入3.线程安全的问题产生原因4.synchronized关键字的引入4.1修饰代码块4.2修饰实例方法4.3修饰静态方法4.4对象头介绍4.5死锁-可重入的特性 5.关于死锁的分析总结5.1死锁的分析5.2死锁成因的必要条件5.3死锁的解决方案 1.进程的状态 public…

Golang笔记_day10

Go面试题&#xff08;三&#xff09; 1、什么是channel&#xff0c;为什么它可以做到线程安全 在Go语言中&#xff0c;channel是一种类型&#xff0c;它可以用来在协程之间传递数据通过共享内存来通信&#xff1a; 通过共享内存来通信是指多个线程或进程直接访问相同的内存区域…

【数据结构与算法】之有序链表去重(保留重复元素)

目录 1.问题描述 2.思路讲解 3.Java 代码实现 4.代码解释 5.复杂度分析 6.其它方法 6.1 递归实现 6.2 双指针 7.总结 相关教程&#xff1a; 有序链表去重&#xff08;不保留重复元素&#xff09; 数据结构之链表详解 递归详解 1.问题描述 给定一个已排序的单链表…

专题十三_记忆化搜索_算法专题详细总结

目录 1. 斐波那契数&#xff08;easy&#xff09; 那么这里就画出它的决策树 &#xff1a; 解法一&#xff1a;递归暴搜 解法二&#xff1a;记忆化搜索 解法三&#xff1a;动态规划 1.暴力解法&#xff08;暴搜&#xff09; 2.对优化解法的优化&#xff1a;把已经计算过的…

MT1361-MT1370 码题集 (c 语言详解)

MT1361重组字符串 c 语言代码实现 #include <stdio.h> #include <string.h> #define MAX_LENGTH 100 void filterOddChars(const char *input, char *output) {int j 0;for (int i 0; input[i] ! \0; i) {if (i % 2 ! 0 && (input[i] % 2 ! 0)) {output…