当前位置: 首页 > news >正文

学习Ansible Playbook 核心语法

一、变量:让 Playbook 更灵活

变量是 Playbook 的 "数据容器",用于存储和复用信息(如主机地址、软件版本、文件路径等),避免重复编写固定值。Ansible 中的变量按作用范围可分为五大类,不同类型的变量适用场景不同,且存在明确的优先级规则。

1.1 变量的命名规则

在定义变量前,需遵守以下规则:

  • 变量名由字母、数字和下划线组成,必须以字母开头(如web_port合法,123_port非法);
  • 不能使用 Ansible 的保留关键字(如taskplayvars等)。

1.2 五大变量类型及使用场景

(1)全局变量:临时传递的变量

全局变量通过ansibleansible-playbook命令的-e参数手动传递,适用于临时修改变量值的场景(如临时指定目标主机、软件版本)。

使用示例

  • 传递单个键值对:

    bash

    # 临时指定user变量的值为"admin",并执行debug模块
    ansible all -i localhost, -m debug -a "msg='当前用户:{{ user }}'" -e "user=admin"
    
  • 传递 JSON/YAML 文件:先创建vars.json文件:

    json

    {"name": "nginx", "version": "1.24.0"}
    
    再通过-e @文件路径传递:

    bash

    ansible-playbook -i hosts deploy.yml -e @vars.json
    
(2)剧本变量:定义在 Playbook 中的变量

剧本变量直接在 Playbook 内定义,作用范围仅限当前 Playbook,适用于固定在任务中的变量(如默认安装路径、服务名)。定义方式有两种:

  • 通过vars属性直接定义

    yaml

    ---
    - name: 安装Nginxhosts: web_serversvars:nginx_pkg: nginx  # 软件包名nginx_conf: /etc/nginx/nginx.conf  # 配置文件路径tasks:- name: 安装Nginx包yum:name: "{{ nginx_pkg }}"state: present
    
  • 通过vars_files引入外部文件:当变量较多时,可将变量抽离到单独的 YAML 文件(如vars/nginx.yml):

    yaml

    # vars/nginx.yml
    nginx_pkg: nginx
    nginx_conf: /etc/nginx/nginx.conf
    
    再在 Playbook 中引入:

    yaml

    ---
    - name: 安装Nginxhosts: web_serversvars_files:- vars/nginx.yml  # 引入外部变量文件tasks:- name: 安装Nginx包yum:name: "{{ nginx_pkg }}"state: present
    
(3)资产变量:针对主机 / 主机组的变量

资产变量定义在 Ansible 的 inventory(资产清单)中,分为主机变量(仅对单个主机生效)和主机组变量(对整个主机组生效),适用于不同主机的个性化配置(如不同主机的 SSH 端口、数据库密码)。

使用示例:编辑 inventory 文件hosts

ini

# 主机组:web_servers
[web_servers]
192.168.1.101 ssh_port=2222  # 主机变量:该主机的SSH端口为2222
192.168.1.102# 主机组变量:对web_servers组所有主机生效
[web_servers:vars]
db_host=192.168.1.200  # 数据库地址
db_port=3306           # 数据库端口

验证变量:

bash

# 查看192.168.1.101的ssh_port变量
ansible 192.168.1.101 -i hosts -m debug -a "var=ssh_port"
# 查看web_servers组的db_host变量
ansible web_servers -i hosts -m debug -a "var=db_host"
(4)Facts 变量:自动收集的主机信息

Facts 变量是 Ansible 通过setup模块自动收集的被管理主机信息(如操作系统版本、IP 地址、内存大小),无需手动定义,适用于基于主机状态的动态配置(如根据操作系统选择安装命令)。

使用示例

  • 手动收集 Facts 信息:

    bash

    # 收集localhost的所有Facts信息
    ansible localhost -m setup
    # 过滤内存相关信息(使用filter参数)
    ansible localhost -m setup -a "filter=*memory*"
    
  • 在 Playbook 中使用 Facts:

    yaml

    ---
    - name: 打印主机信息hosts: alltasks:- name: 输出操作系统版本和IP地址debug:msg: "操作系统:{{ ansible_os_family }},IP地址:{{ ansible_default_ipv4.address }}"
    

若 Playbook 中无需使用 Facts,可关闭收集以提升执行速度:

yaml

---
- name: 无需Facts的任务hosts: allgather_facts: no  # 关闭Facts收集tasks:- name: 安装Nginxyum: name=nginx state=present
(5)注册变量:保存任务执行结果

注册变量通过register关键字定义,用于保存某个任务的执行结果(如命令输出、模块返回值),适用于基于前序任务结果的后续操作(如判断命令是否执行成功、根据输出内容触发后续任务)。

使用示例

yaml

---
- name: 检查Nginx服务状态hosts: web_serverstasks:- name: 执行systemctl is-active命令command: /usr/bin/systemctl is-active nginxregister: nginx_status  # 将命令结果保存到nginx_status变量ignore_errors: yes      # 忽略命令执行失败(如Nginx未启动)- name: 输出Nginx状态debug:msg: "Nginx状态:{{ nginx_status.stdout }}"  # 打印命令标准输出

1.3 变量优先级规则

当不同类型的变量重名时,优先级从高到低为:全局变量(-e参数) > 剧本变量(vars/vars_files) > 主机变量 > 主机组变量

例如:若全局变量、剧本变量、主机组变量均定义了user,最终生效的是全局变量。

二、条件语句:根据状态执行任务

条件语句用于根据变量、Facts 或前序任务结果,决定是否执行某个任务,核心关键字是when。常见场景包括:基于操作系统选择安装命令、判断服务状态决定是否重启、检查文件是否存在等。

2.1 when关键字的基本使用

when后面跟随 Python 表达式,表达式结果为true时执行任务,false时跳过任务。

示例 1:根据操作系统安装软件

yaml

---
- name: 跨系统安装Nginxhosts: alltasks:# RedHat/CentOS系统使用yum安装- name: 安装Nginx(RedHat系列)yum:name: nginxstate: presentwhen: ansible_os_family == "RedHat"  # 条件:操作系统为RedHat系列# Debian/Ubuntu系统使用apt安装- name: 安装Nginx(Debian系列)apt:name: nginxstate: presentwhen: ansible_os_family == "Debian"  # 条件:操作系统为Debian系列

示例 2:根据注册变量结果执行任务

yaml

---
- name: 检查并重启Postfix服务hosts: mail_serverstasks:- name: 获取Postfix状态command: systemctl is-active postfixregister: postfix_statusignore_errors: yes# 若Postfix运行中(返回码rc=0),则重启Apache- name: 重启Apacheservice:name: httpdstate: restartedwhen: postfix_status.rc == 0

2.2 常用运算符

when表达式中,可使用比较运算符和逻辑运算符组合条件:

类型运算符说明示例
比较运算符==等于ansible_machine == "x86_64"
!=不等于ansible_distribution != "Ubuntu"
>/</>=/<=大小比较(数字 / 版本号)ansible_memory_mb.real.total > 2048
逻辑运算符and逻辑与(同时满足)a == 1 and b == 2
or逻辑或(满足一个即可)a == 1 or b == 2
not逻辑非(取反)not (a == 1)
()组合条件(提升优先级)(os == "RedHat" and ver == "7") or (os == "Ubuntu" and ver == "20.04")

示例:组合条件判断

yaml

---
- name: 版本兼容性检查hosts: web_serverstasks:- name: 仅在CentOS 7或Ubuntu 20.04上执行debug:msg: "当前系统符合要求"when:(ansible_distribution == "CentOS" and ansible_distribution_version == "7") or(ansible_distribution == "Ubuntu" and ansible_distribution_version == "20.04")

2.3 条件判断与 Tests

Ansible 支持使用 Jinja2 模板的tests功能,实现更丰富的条件判断(如判断变量是否定义、路径是否存在、字符串是否为小写)。

常用 Tests 场景:
Tests说明示例
defined/undefined判断变量是否已定义 / 未定义when: nginx_port is defined
exists判断路径是否存在(注意:检查主控端路径)when: "/etc/nginx" is exists
file/directory判断路径是否为文件 / 目录when: "/etc/nginx/nginx.conf" is file
lower/upper判断字符串是否全为小写 / 大写when: "hello" is lower
even/odd判断数字是否为偶数 / 奇数when: 6 is even
version版本号比较when: ansible_distribution_version is version("7.5", "ge") # 大于等于 7.5

示例:使用 Tests 判断文件是否存在

yaml

---
- name: 检查Nginx配置文件hosts: web_serversvars:nginx_conf_path: /etc/nginx/nginx.conftasks:- name: 若配置文件存在,则备份copy:src: "{{ nginx_conf_path }}"dest: "{{ nginx_conf_path }}.bak"remote_src: yeswhen: nginx_conf_path is exists  # 判断文件是否存在

2.4 条件块:block/rescue/always

当多个任务需要使用相同条件时,可通过block将任务分组,避免重复编写when。此外,block还支持rescue(任务失败时执行)和always(无论成功 / 失败都执行),实现错误处理。

示例 1:批量执行条件任务

yaml

---
- name: 配置Ubuntu 16.04的DNShosts: web_serverstasks:- name: 通用DNS配置(所有系统)template:src: resolv.conf.j2dest: /etc/resolv.conf# 仅Ubuntu 16.04执行以下两个任务- block:- name: 配置Ubuntu 16.04的DNS基础文件template:src: resolv.conf.j2dest: /etc/resolvconf/resolv.conf.d/base- name: 重启resolvconf服务service:name: resolvconfstate: restartedwhen: ansible_distribution == "Ubuntu" and ansible_distribution_major_version == "16"

示例 2:错误处理(rescue/always

yaml

---
- name: 检查/testdir目录hosts: alltasks:- block:# 尝试列出/testdir目录(若目录不存在则失败)- name: 列出/testdir内容command: ls /testdirrescue:# 若block任务失败,执行此处(如提示目录不存在)- name: 目录不存在时的提示debug:msg: "/testdir目录不存在!"always:# 无论block成功/失败,都执行此处(如记录日志)- name: 记录任务执行时间debug:msg: "任务执行时间:{{ ansible_date_time.iso8601 }}"

三、循环语句:批量执行重复任务

循环语句用于批量执行相同操作(如批量安装软件、创建用户、复制文件),核心关键字是loop(Ansible 2.5 + 推荐),替代了旧版的with_*语法(如with_itemswith_dict)。

3.1 loop关键字的基本使用

loop接收一个列表,通过{{ item }}引用列表中的每个元素,实现循环执行。

示例 1:批量启动服务

yaml

---
- name: 启动多个服务hosts: web_serverstasks:- name: 启动httpd、postfix、sshd服务service:name: "{{ item }}"state: startedloop:- httpd- postfix- sshd

示例 2:循环使用变量列表先定义变量列表,再在loop中引用:

yaml

---
- name: 批量创建用户hosts: web_serversvars:# 用户列表:每个元素是字典(包含用户名和所属组)users:- { name: "user1", groups: "wheel" }- { name: "user2", groups: "www" }- { name: "user3", groups: "ftp" }tasks:- name: 创建用户并指定所属组user:name: "{{ item.name }}"groups: "{{ item.groups }}"state: presentloop: "{{ users }}"  # 循环用户列表

3.2 循环中注册变量

若需保存循环中每个任务的执行结果,可在循环任务中使用register,结果会以列表形式存储在变量中。

示例:批量检查文件是否存在

yaml

---
- name: 检查多个文件hosts: localhosttasks:- name: 检查/etc/hosts、/etc/passwd、/etc/groupstat:path: "{{ item }}"loop:- /etc/hosts- /etc/passwd- /etc/groupregister: file_check_result  # 保存循环结果- name: 输出文件检查结果debug:msg: "文件{{ item.item }}是否存在:{{ item.stat.exists }}"loop: "{{ file_check_result.results }}"  # 遍历循环结果列表

3.3 旧版循环语法(with_*

Ansible 2.5 以前使用with_*语法实现循环,目前仍兼容但不推荐。以下是常见旧版循环的使用场景:

语法说明示例
with_items简单列表循环(等同于loopwith_items: [1,2,3]
with_dict循环字典(遍历键值对)with_dict: { "a":1, "b":2 }
with_fileglob循环指定目录的文件(主控端)with_fileglob: "/root/*.pub"
with_lines循环命令输出或文件内容(逐行)with_lines: "cat /tmp/users.txt"
with_sequence生成整数序列(指定起始 / 结束 / 步长)with_sequence: start=1 end=5 stride=2

示例:使用with_dict循环字典

yaml

---
- name: 遍历用户字典hosts: localhostvars:users:alice:age: 25role: developerbob:age: 30role: testertasks:- name: 输出用户信息debug:msg: "用户名:{{ item.key }},年龄:{{ item.value.age }},角色:{{ item.value.role }}"with_dict: "{{ users }}"  # 循环字典

3.4 循环与条件结合

可在循环中使用when,实现 "筛选式循环"(仅执行满足条件的循环项)。

示例:仅安装内存大于 2GB 的主机的 Nginx

yaml

---
- name: 按需安装Nginxhosts: alltasks:- name: 内存大于2GB时安装Nginxyum:name: nginxstate: present# 条件:内存总量(MB)> 2048when: ansible_memory_mb.real.total > 2048

示例:循环中筛选元素

yaml

---
- name: 仅打印大于5的数字hosts: localhosttasks:- name: 输出5以上的数字command: echo "{{ item }}"loop: [1,2,3,4,5,6,7,8]when: item > 5  # 仅循环项大于5时执行

四、总结

变量、条件语句和循环语句是 Ansible Playbook 的核心能力,三者结合可实现复杂的自动化场景:

  • 变量:解决数据复用问题,让 Playbook 更灵活;
  • 条件语句:解决 "按需执行" 问题,让任务更智能;
  • 循环语句:解决 "重复操作" 问题,让代码更简洁。
http://www.dtcms.com/a/618935.html

相关文章:

  • flink CDC 3.5.0
  • 阿里巴巴网站备案号用wordpress
  • 网站seo服务商seo文章外包
  • 微信网站设计运营用DW做的网站怎么分享给别人
  • 怎么建网站教程图解棋牌游戏开发多少钱
  • 广西智能网站建设哪家有h5页面设计是什么意思
  • AI 招聘智能体
  • 菏泽网站建设熊掌号微信怎么制作自己的小程序
  • 网站商城系统建设协会网站改版建议
  • CSS-2:CSS的元素显示模式
  • 国外互动网站wordpress使用邮箱
  • F280049C学习笔记之SCI
  • 17.背光PWM调节
  • RAID特性
  • ThreadLocal为什么会发生内存泄漏
  • 在阿里云建设一个网站的全流程华凯创意的展馆设计案例
  • 网站主页怎么做竞价排名适合百度这样的网络平台吗
  • 开源机器学习课程mlcourse.ai:理论与实践完美结合的AI学习指南
  • 网站怎么做站内美化城乡建设杂志社官方网站
  • 网站推广的主要方法腾讯云域名注册官网
  • MySQL 主从延迟问题深度解析:常见原因与解决方案(强总结 + 易懂版)
  • 【开题答辩全过程】以 基于springboot的在线影院系统设为例,包含答辩的问题和答案
  • 39.华为云运维类服务
  • 做个网站商场需要多少软件商店下载到手机
  • 【Java 基础】3 面向对象 - this
  • 网站开发赚钱方向做个app商城类的要多少钱
  • 代码随想录-day37
  • <MySQL——L2>
  • 建设银行网站首页口网站建设存在哪些问题
  • LeetCode94.二叉树的中序遍历、LeetCode144. 二叉树的前序遍历、LeetCode145. 二叉树的后序遍历