Ansible Playbook 进阶探秘:Handlers、变量、循环及条件判断全解析

news2025/4/16 22:54:59
192.168.60.100ansible.com
192.168.60.110

client-1.com

192.168.60.120client-2.com
192.168.60.130client-1.com

一、Handlers

介绍:在发生改变时执行的操作(类似puppet通知机制)

示例:

当apache的配置文件发生改变时,apache服务才会重启。

- hosts: webservers
  remote_user: root
  tasks:
  - name: apache
    yum: name=httpd state=present
  - name: apache config
    copy: src=/config/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify:
      - start httpd

  handlers:
  - name: start httpd
    service: name=httpd state=restarted

测试:

配置文件没有改变——

(可以看到没有重启服务的任务)

修改apache的配置——

[root@ansible playbook]# vim /config/httpd.conf        #修改端口

Listen 8080 

 (当配置发生修改后,可以看到重启服务的任务已经被执行)

二、变量的使用

常用的变量一般就两种:

  • 一种为用户自己定义的变量
  • 一种为facts获取的变量(即ansible webserver -m setup查到的变量)

 1.自定义变量

 (1)用户在.yaml文件自定义变量

示例:

[root@ansible playbook]# vim test1.yaml 

- hosts: webservers
  remote_user: root
  vars:
  - var1: "abc"
  - var2: 123
  tasks:
  - name: test vars
    shell: echo "{{ var1 }} {{ var2 }}" >> /tmp/var.txt

测试:

 

(定义的变量成功写入到被管控端主机的var.txt文件)

(2)通过-e参数传递变量

 示例:

 [root@ansible playbook]# vim test2.yaml

- hosts: webservers
  remote_user: root
  tasks:
  - name: install package
    yum: name={{ packname }} state=present

测试:

 (使用-e传递参数安装namp)

(3)通过主机/主机组配置文件传递变量

主机——

示例:

[root@ansible playbook]# vim /etc/ansible/hosts 

192.168.60.110 packname=nmap

[root@ansible playbook]# vim test3.yaml

- hosts: 192.168.60.110
  remote_user: root
  tasks:
  - name: install package
    yum: name={{ packname }} state=present

测试: 

(参数成功传递) 

主机组——

示例: 

[root@ansible playbook]# vim /etc/ansible/hosts

[webservers]
192.168.60.110
192.168.60.120
192.168.60.130
[webservers:vars]
packname=nmap

[root@ansible playbook]# vim test4.yaml 

测试: 

(参数传递成功)

2.通过facts获取的系统的变量

(1)获取系统变量

即ansible webserver -m setup查到的变量

使用方法:

[root@ansible playbook]# ansible webservers -m setup > /tmp/fact.txt

[root@ansible playbook]# vim /tmp/fact.txt

在剧本中直接调用这些变量名就行,但是注意这些变量名是分级别的,对齐的就是同一级,比如ansible_default_ipv4和ansible_nodename就是同一级,address是ansible_default_ipv4的 下一级,要调用它就需要在ansible_default_ipv4后面加上一个“.”,就是写成这样ansible_default_ipv4.address。

(其实就是字典,以键值对的方式关联起来,这里说变量是为了帮助理解) 

 示例:

[root@ansible playbook]# vim facts.yaml        #获取ip、主机名等系统变量信息

- hosts: webservers
  remote_user: root
  tasks:
  - name: hostname ipaddrss
    shell: echo "{{ ansible_default_ipv4.address }} {{ ansible_nodename }}" > /tmp/facts.txt
  - name: fetch file /tmp/facts
    fetch: src=/tmp/facts.txt dest=/tmp

测试:

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

(2)本地facts(facts.d)自定义系统变量

解释:就是定义ansible webserver -m setup查到的变量

示例:

[root@client-1 ~]# mkdir -p /etc/ansible/facts.d        #在被管控端创建如下目录 

[root@client-1 ~]# touch /etc/ansible/facts.d/test.fact        #创建文件

[root@client-1 ~]# vim /etc/ansible/facts.d/test.fact        #写入要定义的变量名

[general]
test_test1=123
test_test2=abc 

测试:

 [root@ansible playbook]# ansible 192.168.60.110 -m setup | grep test_test       

#获取自定义的系统变量

(获取成功!)

3.变量注册 

介绍:在 Ansible 的 Playbook 里,变量注册是一项非常实用的功能。借助它,我们能够把某个命令的执行结果存储到变量中,方便后续使用。这一特性能够在很多场景下避免编写特定于站点的复杂逻辑。比如,你可以利用变量注册来检查系统中是否存在某个特定程序。具体操作时,只需使用 register 关键字指定用于存储结果的变量即可。通过这种方式,你可以在后续任务中根据存储的结果进行条件判断和进一步操作。

示例:

[root@ansible playbook]# vim test5.yaml

- hosts: webservers
  remote_user: root
  tasks:
  - name: get user info
    shell: grep ^root /etc/passwd
    register: pass_content
  - name: save info
    shell: echo {{ pass_content }} > /tmp/user.txt

(获取root用户信息存进pass_content里面)

测试: 

(可以看到存入客户端/tmp/user.txt文件下的信息是以键值对的形式,我们可以用来调用这些键值对,这个需要和后面要学的判断结合起来使用,单独看确实没什么用,下面是如何调用)

[root@ansible playbook]# vim test5.yaml         #调用

- hosts: webservers
  remote_user: root
  tasks:
  - name: get user info
    shell: grep ^root /etc/passwd
    register: pass_content
  - name: save info
    shell: echo {{ pass_content.stdout }} > /tmp/user1.txt 

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

[root@client-1 ~]# cat /tmp/user1.txt 

三、剧本中的条件判断

ansible和puppet软件相同 是可以支持条件判断,使用when语句。

示例1

 [root@ansible playbook]# vim test6.yaml

- hosts: webservers
  remote_user: root
  tasks:
  - name: install tree
    yum: name=tree state=present
    when: ansible_nodename == "client-1.com"
  - name: install nmap
    yum: name=nmap state=present
    when: ansible_nodename == "client-2.com"

(设置条件判断,当被管控端的主机名叫client-1.com时安装tree,叫client-2.com时安装nmap)

测试:

(可以看到条件判断将不符合条件的主机全部跳过去了)

示例2

条件判断+变量注册

 [root@ansible playbook]# vim apache_test.yaml

- hosts: webservers
  remote_user: root
  tasks:
  - name: get pkg info
    shell: rpm -qa | grep httpd | awk -F'-' 'NR == 1 {print$1}'
    register: pkginfo
  - name: install httpd
    yum: name=httpd state=present
    when: pkginfo.stdout != "httpd"

测试:

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

(由于我的三台被管控机都安装过了httpd,所以可以看到都跳过去了) 

(紫色字体的警告不用管,没有影响,如果嫌烦可以按照下面的方式去掉)

[root@ansible playbook]# vim /etc/ansible/ansible.cfg 

command_warnings=False 

 

(这样执行就没有警告了)

示例3

源码部署nginx并启动服务

1.规划 

基础功能:

  • 本地部署,打包
  • 需要判断目标主机是否已经安装nginx

扩展:

  • 通过配置文件是否改动触发启动

2.准备本地源码包nginx

[root@ansible /]# wget https://nginx.org/download/nginx-1.27.4.tar.gz       

(复制链接直接wget就行,这样就在本地下载下来了nginx的源码包)

[root@ansible /]# tar -xvf /nginx-1.27.4.tar.gz -C /usr/local/src/

[root@ansible /]# cd /usr/local/src/nginx-1.27.4/

[root@ansible nginx-1.27.4]# yum install gcc gcc-c++ pcre-devel zlib-devel

[root@ansible nginx-1.27.4]# useradd -m -s /sbin/nologin nginx

[root@ansible nginx-1.27.4]# ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx

[root@ansible nginx-1.27.4]# make

[root@ansible nginx-1.27.4]# make install

[root@ansible local]# cd /usr/local

[root@ansible local]# tar -zcvf /playbook/nginx.tar.gz nginx/

3.编写剧本

[root@ansible playbook]# vim snginx_install.yaml

- hosts: webservers
  remote_user: root
  tasks:
  - name: copy nginx
    copy: src=/playbook/nginx.tar.gz dest=/tmp
  - name: get nginx info
    shell: ls -d /usr/local/nginx
    register: nginx_info
    ignore_errors: yes
  - name: unzip nginx
    shell: tar -xvf /tmp/nginx.tar.gz -C /usr/local
    when: nginx_info.rc == 2
  - name: add user
    user: name=nginx state=present
  - name: modify nginx
    file: path=/usr/local/nginx owner=nginx group=nginx recurse=yes state=directory

剧本说明: 

- hosts: webservers
  remote_user: root
  tasks:
  - name: copy nginx        #拷贝源码到到管控机
    copy: src=/playbook/nginx.tar.gz dest=/tmp
  - name: get nginx info        #注册变量用于判断是否安装了nginx
    shell: ls -d /usr/local/nginx
    register: nginx_info
    ignore_errors: yes        #未安装过nginx会报错,这里用来跳过保存,继续执行剧本
  - name: unzip nginx        #解压安装nginx
    shell: tar -xvf /tmp/nginx.tar.gz -C /usr/local        
    when: nginx_info.rc == 2        #判断是否安装过nginx
  - name: add user        #添加nginx用户
    user: name=nginx state=present
  - name: modify nginx        #递归设置用户和所属组为nginx
    file: path=/usr/local/nginx owner=nginx group=nginx recurse=yes state=directory

相关说明:

ignore_errors: yes        #当某个任务执行时出现错误,ignore_errors模块等于yes时,不会让整个剧本执行中断,而是会忽略这个错误,继续执行后续的任务

nginx.rc == 2        #这个是register的返回值,当返回值等于2的时候表明/usr/local/nginx目录已经存在

recurse=yes        #这个是递归的修改权限

测试:

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

(可以看到注册变量任务的报错,因为没有安装过nginx,但是因为添加了ignore_errors模块,成功跳过了错误,继续执行剧本后面剩下的任务)

(被管控端的所有主机安装成功)

(这时候再执行就可以看到,注册变量模块没有再报错,因为所有节点都已经安装了nginx,而且解压nginx的任务判断成功也生效,安装过nginx的被管控机没有再次执行解压nginx的任务,这就节约了在实际运维场景下的时间)

4.扩展

[root@ansible playbook]# vim snginx_install.yaml 

- hosts: webservers
  remote_user: root
  tasks:
  - name: copy nginx
    copy: src=/playbook/nginx.tar.gz dest=/tmp
  - name: get nginx info
    shell: ls -d /usr/local/nginx
    register: nginx_info
    ignore_errors: yes
  - name: unzip nginx
    shell: tar -xvf /tmp/nginx.tar.gz -C /usr/local
    when: nginx_info.rc == 2
  - name: add user
    user: name=nginx state=present
  - name: modify nginx
    file: path=/usr/local/nginx owner=nginx group=nginx recurse=yes state=directory
  - name: nginx config
    copy: src=/playbook/nginx.conf dest=/usr/local/nginx/conf
    notify:
    - restart nginx

  handlers:
  - name: restart nginx
    shell: /usr/local/nginx/sbin/nginx -s reload
 

测试:

启动管控端的nginx服务—— 

[root@client-1 ~]# /usr/local/nginx/sbin/nginx

[root@client-2 ~]# /usr/local/nginx/sbin/nginx

[root@client-3 ~]# /usr/local/nginx/sbin/nginx 

配置文件nginx.conf没有修改——

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

 (因为配置没有修改,所以nginx服务不会被重启,这样节约了时间)

修改nginx.conf的配置,将nginx的端口设置为8080——

[root@ansible playbook]# vim nginx.conf 

 listen       8080; 

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

 (配置文件发生改动,管控端重启被管控端所有主机的nginx服务)

四、剧本中的循环

 剧本的循环是使用with_items关键字实现的。

(这个功能使用很少,判断功能用到的比较多)

示例1

 添加abc1-abc3用户

[root@ansible playbook]# vim cycle.yaml

- hosts: webservers
  remote_user: root
  tasks:
  - name: add user
    user: name={{ item }} state=present
    with_items:
    - abc1
    - abc2
    - abc3

测试:

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

 

(用户再被管控端创建成功!) 

示例2 

依次安装软件 nmap wget tree 

[root@ansible playbook]# vim cycle-1.yaml 

- hosts: webservers
  remote_user: root
  tasks:
  - name: pack install
    user: name={{ item }} state=present
    with_items:
    - tree
    - namp
    - vsftpd 

 测试:

 (软件安装成功!)


ansible自动化运维工具的介绍-CSDN博客

深度剖析 ansible:从部署基础到模块运用及剧本编写-CSDN博客

Ansible 实战:Roles,运维的 “魔法函数”-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2330984.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MATLAB的24脉波整流器Simulink仿真与故障诊断

本博客来源于CSDN机器鱼,未同意任何人转载。 更多内容,欢迎点击本专栏目录,查看更多内容。 目录 0 引言 1 故障数据采集 2 故障特征提取 3 故障诊断分类 4 结语 本博客内容是在MATLAB2023下完成。 0 引言 对于电力电子电路的故障诊断…

linux第三次作业

1、将你的虚拟机的网卡模式设置为nat模式,给虚拟机网卡配置三个主机位分别为100、200、168的ip地址 2、测试你的虚拟机是否能够ping通网关和dns,如果不能请修改网关和dns的地址 3、将如下内容写入/etc/hosts文件中(如果有多个ip地址则写多行&…

国标GB28181视频平台EasyCVR顺应智慧农业自动化趋势,打造大棚实时视频监控防线

一、方案背景 近年来,温室大棚种植技术凭借其显著的优势,在提升农作物产量和质量、丰富农产品供应方面发挥了重要的作用,极大改善了人们的生活水平,得到了广泛的推广和应用。大棚内的温度、湿度、光照度和二氧化碳浓度等环境因素…

HOOPS Visualize:跨平台、高性能的三维图形渲染技术解析

在当今数字化时代,三维可视化技术已成为众多行业的核心竞争力。HOOPS Visualize作为一款功能强大的三维图形渲染引擎,凭借其卓越的渲染能力、跨平台支持、丰富的交互功能、高度定制化以及快速部署等特性,为开发人员提供了构建高质量、高性能3…

蓝桥杯 C/C++ 组历届真题合集速刷(一)

一、1.单词分析 - 蓝桥云课 &#xff08;模拟、枚举&#xff09;算法代码&#xff1a; #include <bits/stdc.h> using namespace std;int main() {string s;cin>>s;unordered_map<char,int> mp;for(auto ch:s){mp[ch];}char result_charz;int max_count0;fo…

多类型医疗自助终端智能化升级路径(代码版.上)

大型医疗自助终端的智能化升级是医疗信息化发展的重要方向,其思维链一体化路径需要围绕技术架构、数据流协同、算法优化和用户体验展开: 一、技术架构层:分布式边缘计算与云端协同 以下针对技术架构层的分布式边缘计算与云端协同模块,提供具体编程实现方案: 一、边缘节点…

区间 DP 详解

文章目录 区间 DP分割型合并型环形合并 区间 DP 区间 DP&#xff0c;就是在对一段区间进行了若干次操作后的最小代价&#xff0c;一般是合并和拆分类型。 分割型 分割型&#xff0c;指把一个区间内的几项分开拆成一份一份的&#xff0c;再全部合起来就是当前答案&#xff0c…

QAM 信号的距离以及能量归一化

QAM星座图平均功率能量_星座图功率计算-CSDN博客 正交幅度调制(QAM) - Vinson88 - 博客园 不同阶QAM调制星座图中&#xff0c;符号能量的归一化计算原理_qpsk的星座图归一化-CSDN博客 https://zhuanlan.zhihu.com/p/690157236

Reactive编程框架与工具

文章目录 6.2 后端 Reactive 框架6.2.1 Spring WebFlux核心架构核心组件实际应用高级特性性能优化适用场景与限制 6.2.2 Akka&#xff08;Actor模型&#xff09;Actor模型基础基本用法高级特性响应式特性实现性能优化实际应用场景优势与挑战 6.2.3 Vert.x&#xff08;事件驱动&…

Python爬虫第7节-requests库的高级用法

目录 前言 一、文件上传 二、Cookies 三、会话维持 四、SSL证书验证 五、代理设置 六、超时设置 七、身份认证 八、Prepared Request 前言 上一节&#xff0c;我们认识了requests库的基本用法&#xff0c;像发起GET、POST请求&#xff0c;以及了解Response对象是什么。…

Maven的安装配置-项目管理工具

各位看官&#xff0c;大家早安午安晚安呀~~~ 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连&#xff0c;小编尽全力做到更好 欢迎您分享给更多人哦 今天我们来学习&#xff1a;Maven的安装配置-项目管理工具 目录 1.什么是Maven&#xff1f;Maven用来干什么的&#xff1f…

智能 SQL 优化工具 PawSQL 月度更新 | 2025年3月

&#x1f4cc; 更新速览 本月更新包含 21项功能增强 和 9项问题修复&#xff0c;重点提升SQL解析精度与优化建议覆盖率。 一、SQL解析能力扩展 ✨ 新增SQL语法解析支持 SELECT...INTO TABLE 语法解析&#xff08;3/26&#xff09; ALTER INDEX RENAME/VISIBLE 语句解析&#…

Ubuntu虚拟机编译安装部分OpenCV模块方法实现——保姆级教程

Ubuntu虚拟机的安装过程可以查看另一篇文章&#xff1a;VMware安装Ubuntu虚拟机实现COpenCV代码在虚拟机下运行教程-CSDN博客 目前我们已经下载好了OpenCV&#xff0c;这里以OpenCV4.5.2为例。 在内存要求尽可能小的情况下&#xff0c;可以尝试只编译安装代码中使用到的OpenC…

spring mvc @ResponseBody 注解转换为 JSON 的原理与实现详解

ResponseBody 注解转换为 JSON 的原理与实现详解 1. 核心作用 ResponseBody 是 Spring MVC 的一个注解&#xff0c;用于将方法返回的对象直接序列化为 HTTP 响应体&#xff08;如 JSON 或 XML&#xff09;&#xff0c;而不是通过视图解析器渲染为视图&#xff08;如 HTML&…

skynet.rawcall使用详解及应用场景

目录 核心特性函数原型使用场景场景 1&#xff1a;高性能二进制传输&#xff08;如文件转发&#xff09;场景 2&#xff1a;自定义序列化协议&#xff08;如 Protocol Buffers&#xff09;场景 3&#xff1a;跨服务共享内存&#xff08;避免拷贝&#xff09; 配套接收方实现与 …

使用SpringSecurity下,发生重定向异常

使用SpringSecurity下&#xff0c;发生空转异常 环境信息&#xff1a; Spring Boot 3.4.4 &#xff0c; jdk 17 &#xff0c; springSecurity 6.4.4 问题背景&#xff1a; 没有自定义controller &#xff0c;改写了login 页面&#xff0c;并且进行了成功后的跳转处理&#xf…

Elasticsearch | ES索引模板、索引和索引别名的创建与管理

关注&#xff1a;CodingTechWork 引言 在使用 Elasticsearch (ES) 和 Kibana 构建数据存储和分析系统时&#xff0c;索引模板、索引和索引别名的管理是关键步骤。本文将详细介绍如何通过 RESTful API 和 Kibana Dev Tools 创建索引模板、索引以及索引别名&#xff0c;并提供具…

力扣hot100_回溯(2)_python版本

一、39. 组合总和&#xff08;中等&#xff09; 代码&#xff1a; class Solution:def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:ans []path []def dfs(i: int, left: int) -> None:if left 0:# 找到一个合法组合ans.append(pa…

LPDDR4内存颗粒命名规则全解析:三星、镁光、海力士、南亚、长鑫等厂商型号解码与选型指南

由于之前DDR的系列选型文章有很好的反馈&#xff0c;所以补充LPDDR4低功耗内存的选型和命名规则&#xff0c;总结了目前市面上常用的内存&#xff0c;供硬件工程师及数码爱好者参考。 在智能手机、平板电脑和低功耗设备中&#xff0c;LPDDR4 SDRAM凭借其高带宽、低功耗特性成为…

【杂谈】Godot4.4导出到Android平台(正式导出)

学博而后可约&#xff0c;事历而后知要。 目录 一、准备二、Gradle构建三、配置Java SDK四、配置Android SDK五、配置密钥 一、准备 本文在前文【杂谈】Godot4.4导出到安卓平台&#xff08;调试导出&#xff09;的基础上&#xff0c;进行正式导出。调试导出并不是真正的编译导…