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

Ansible 变量全解析与实践

一、Ansible 变量基础

1.1 变量定义规则

  • 命名规范:由字母、数字、下划线组成,必须以字母开头,不可使用 Ansible 内置关键字(如 tasks、hosts 等)。
  • 变量优先级(从高到低)
  1. Global 范围:命令行传递(-e 选项)、Ansible 配置文件中设置的变量;
  2. Play 范围:Play 内 vars/vars_files 定义、角色(Role)内变量;
  3. Host 范围:Inventory 主机 / 组变量、事实变量(Facts)、注册变量(Register)。
    • 若变量重复定义,优先级高的变量会覆盖优先级低的变量。

二、变量定义与使用方式(含实操示例)

2.1 直接定义变量(vars/vars_files)

2.1.1 vars 直接定义(剧本内)

在 Play 中通过 vars 关键字定义变量,支持普通变量和字典型变量,仅在当前 Play 生效。

示例剧本(test.yml)

cat test.yml
---
- name: abhosts: node1vars: - aa: 11- bb: b1: 21b2: 22   tasks: - name: abbdebug: msg: "{{aa}}"-----输出11- name: accdebug: msg: "{{bb.b1}}"------输出21
2.1.2 vars_files 引用外部变量文件

当变量较多时,可将变量存入独立文件,通过 vars_files 引入剧本,便于维护。

步骤 1:创建外部变量文件(/etc/ansible/a.yml)

cat a.ymlaa: 11bb: b1: 21b2: 22

步骤 2:剧本引用变量文件

cat test.yml
---
- name: abhosts: node1vars_files: /home/student/ansible/a.yml   tasks: - name: abbdebug: msg: "{{aa}}"-----输出11- name: accdebug: msg: "{{bb.b2}}"------输出22

2.2 注册变量(register)

通过 register 将任务执行结果(如命令输出、返回码)赋值给变量,后续可调用结果中的子信息(如 stdout、rc)。

示例 1:注册命令执行结果
cat test.yml---
- name: abhosts: node1tasks: - name: acshell: cmd: echo aaregister: rz- name: addebug: var: rz

执行结果(关键部分)

"rz": {"changed": true,"cmd": "echo aa","delta": "0:00:00.014507","end": "2025-09-01 16:34:13.808155","failed": false,"msg": "","rc": 0,----命令返回码(0表示成功)"start": "2025-09-01 16:34:13.793648","stderr": "",---标准错误输出"stderr_lines": [],"stdout": "aa",----标准输出,输出内容"stdout_lines": ["aa"
示例 2:调用注册变量的子键(主变量.子变量)
cat test.yml---
- name: abhosts: node1tasks: - name: acshell: cmd: echo aaregister: rz- name: addebug: var: rz.stdout

2.3 事实变量(Facts)

事实变量是 Ansible 自动收集的 “受控主机系统信息”(如 IP 地址、主机名、内存大小),无需手动定义,可直接调用。通过 setup 模块可查看所有事实变量。

1. 查看所有事实变量
# 将 node1 的所有事实变量保存到文件(便于查找)ansible node1 -m setup > a.txt
2. 常用事实变量示例
cat test.yml---
- name: abhosts: node1tasks: - name: addebug: var: ansible_fqdn- name: acdebug: var: ansible_default_ipv4.address- name: afdebug:var: ansible_hostname- name: agdebug: var: ansible_memtotal_mb- name: ahdebug:var: ansible_bios_version- name: akdebug: var: ansible_devices.vda.size

结果:

ok: [node1] => {"ansible_fqdn": "node1.example.com"
}TASK [ac] *********************************************************************************************
ok: [node1] => {"ansible_default_ipv4.address": "192.168.122.10"
}TASK [af] *********************************************************************************************
ok: [node1] => {"ansible_hostname": "node1"
}TASK [ag] *********************************************************************************************
ok: [node1] => {"ansible_memtotal_mb": 1969
}TASK [ah] *********************************************************************************************
ok: [node1] => {"ansible_bios_version": "1.16.1-1.el9"
}TASK [ak] *********************************************************************************************
ok: [node1] => {"ansible_devices.vda.size": "20.00 GB"
}

2.4 命令行传递变量(-e 选项)

执行剧本时通过 -e 选项动态传递变量,优先级最高,适合临时修改变量值。

示例剧本
cat test.yml---
- name: abhosts: node1tasks: - name: addebug:msg: "{{ name1 }}"

执行命令(传递变量)

ansible-playbook test.yml -e 'name1=aa'

执行结果


2.5 主机清单中的变量

在 Inventory 文件(如 /home/student/ansible/inventory)或 host_vars/group_vars 目录中定义变量,对目标主机 / 组生效。

2.5.1 清单文件内直接定义( /home/student/ansible/inventory)
# 单个主机变量(直接跟在主机后)node1 name1=aanode2# 主机组 net 及组变量([组名:vars] 定义)[net]node1node2[net:vars]test1=hello # 组内所有主机共享的变量test2=hi
2.5.2 host_vars/group_vars 目录定义

在 /home/student/ansible 下创建 host_vars(主机专属变量)和 group_vars(组专属变量)目录,变量文件以 “主机名” 或 “组名” 命名(支持无后缀或 .yml 后缀)。

目录结构

/home/student/ansible

├── host_vars/ # 主机专属变量目录

│ ├── node1 # node1 专属变量文件(无后缀)

│ └── node1.yml # node1 专属变量文件(.yml 后缀)

└── group_vars/ # 组专属变量目录

└── net.yml # net 组专属变量文件

优先级验证

  • 若 node1 和 node1.yml 同时存在,node1 优先级更高(执行剧本时会优先使用 node1 中的变量);
  • 删除 node1 后,会自动使用 node1.yml 中的变量。
  • node1>node1.yml>主机清单单用户>主机清单主机组

2.6 内置变量

Ansible 内置变量用于获取 “Ansible 版本”“清单结构” 等信息,无需手动定义,常用内置变量如下:

内置变量

作用

示例结果

ansible_version

Ansible 版本信息

{"full": "2.9.18", "major": 2}

inventory_hostname

清单中定义的主机名

node1

play_hosts

当前 Play 涉及的所有主机列表

["node1", "node2"]

groups

所有主机组及组内主机

{"all": ["node1","node2"], "net": ["node1","node2"]}

group_names

当前主机所属的所有组

["net"]

inventory_dir

清单文件所在目录

/etc/ansible

示例剧本
cat test.yml---
- name: abhosts: node1tasks: - name: addebug:var: ansible_version----ansible版本- name: afdebug: var: inventory_hostname----输出清单主机名- name: agdebug: var: play_hosts---输出当前play主机列表- name: ahdebug: var: groups---输出所有主机组- name: ajdebug: var: group_names---输出当前主机所属组- name: akdebug:var: inventory_dir----输出清单目录

结果

ok: [node1] => {"ansible_version": {"full": "2.13.3","major": 2,"minor": 13,"revision": 3,"string": "2.13.3"}
}TASK [af] *******************************************************************************************************************
ok: [node1] => {"inventory_hostname": "node1"
}TASK [ag] *******************************************************************************************************************
ok: [node1] => {"play_hosts": ["node1"]
}TASK [ah] *******************************************************************************************************************
ok: [node1] => {"groups": {"all": ["node1","node2","node5","node3","node4"],"test01": ["node1"],"test02": ["node2"],"test05": ["node5"],"ungrouped": [],"web": ["node3","node4"],"webtest": ["node3","node4"]}
}TASK [aj] *******************************************************************************************************************
ok: [node1] => {"group_names": ["test01"]
}TASK [ak] *******************************************************************************************************************
ok: [node1] => {"inventory_dir": "/home/student/ansible"
}

2.7 叠加变量(with_items)

通过 with_items 为变量赋予多个值,任务会循环执行(每次取一个值),循环中固定用 item 表示当前值,支持注册循环结果并调用。

示例剧本
cat test.yml---
- name: abhosts: node1tasks: - name: adshell: cmd: echo "{{ item }}"with_items: - haha- heihei- heheregister: rz- name: afdebug: var: rz.results[0].stdout- name: agdebug: var: rz.results[1].stdout- name: ahdebug: var: rz.results[2].stdout

结果:

TASK [ad] *******************************************************************************************************************
changed: [node1] => (item=haha)
changed: [node1] => (item=heihei)
changed: [node1] => (item=hehe)TASK [af] *******************************************************************************************************************
ok: [node1] => {"rz.results[0].stdout": "haha"
}TASK [ag] *******************************************************************************************************************
ok: [node1] => {"rz.results[1].stdout": "heihei"
}TASK [ah] *******************************************************************************************************************
ok: [node1] => {"rz.results[2].stdout": "hehe"
}

三、Ansible 机密管理(ansible-vault)

当剧本 / 变量文件包含敏感信息(如密码、API 密钥)时,使用 ansible-vault 加密文件,防止信息泄露。支持创建、编辑、加解密文件等操作。

3.1 核心操作命令

命令

作用

示例

ansible-vault create 文件名

创建新的加密文件(默认用 vi 编辑)

ansible-vault create secret.yml

ansible-vault view 文件名

查看加密文件内容(需输入密码)

ansible-vault view secret.yml

ansible-vault edit 文件名

编辑加密文件(需输入密码)

ansible-vault edit secret.yml

ansible-vault encrypt 文件名

加密已存在的普通文件

ansible-vault encrypt plain.yml

ansible-vault decrypt 文件名

永久解密加密文件(需输入密码)

ansible-vault decrypt secret.yml

ansible-vault rekey 文件名

修改加密文件的密码

ansible-vault rekey secret.yml

ansible-vault encrypt 文件名 --vault-id 密码文件

用密码文件加密(无交互)

ansible-vault encrypt e.yml --vault-id secret.txt

3.2 执行加密剧本

加密后的文件无法直接执行,需通过以下方式提供密码:

方式 1:交互式输入密码(--ask-vault-pass)
ansible-playbook --ask-vault-pass secret.yml# 执行时会提示输入加密密码
方式 2:用密码文件执行(无交互,--vault-id)
  • 创建密码文件(仅 root 可读,确保安全):
echo "123456" > secret.txt # 密码为 123456chmod 600 secret.txt # 限制权限,防止他人读取
  • 用密码文件执行加密剧本:
ansible-playbook --vault-id secret.txt secret.yml

3.3 示例:创建并执行加密剧本

步骤 1:创建加密剧本

假设需要创建一个剧本 aa.yml,通过 ansible-vault create 直接创建加密文件:

# 创建加密剧本,执行后会提示输入密码(需牢记,后续执行/编辑需用到)ansible-vault create aa.yml

输入密码后,会进入 vi 编辑器,在编辑器中写入剧本内容

保存退出 vi 编辑器后,aa.yml 会以加密形式存储,直接用 cat 查看会显示乱码(确保敏感信息安全):


步骤 2:查看加密剧本内容

若需确认加密剧本中的内容,不能直接用 cat,需通过 ansible-vault view 并输入密码查看:

ansible-vault view aa.yml

输入创建时设置的密码后,会正常显示剧本内容

步骤 3:编辑加密剧本

若需修改加密剧本(如更新数据库密码),通过 ansible-vault edit 操作,同样需要输入密码:

ansible-vault edit aa.yml

输入密码后进入 vi 编辑器, 若修改过文件,保存退出后,加密文件会自动更新(无需重新加密)。

步骤 4:执行加密剧本

加密剧本无法直接用 ansible-playbook aa.yml 执行,会报错 “ERROR! Attempted to read encrypted file without password”,需通过以下两种方式提供密码:

方式 1:交互式输入密码(适合临时执行)

执行时加 --ask-vault-pass 选项,会提示输入密码:

ansible-playbook --ask-vault-pass aa.yml

输入正确密码后,剧本正常执行,输出结果

方式 2:无交互执行(适合自动化场景)

若需在脚本或自动化流程中执行加密剧本,可先创建 “密码文件”,避免手动输入密码:

  • 创建密码文件(仅 root 可读,防止密码泄露):
echo "123456" > secret.txt # 密码为 123456chmod 600 secret.txt # 限制权限,防止他人读取
  • 通过 --vault-id 指定密码文件执行:
ansible-playbook --vault-id secret.txt aa.yml

执行后无需手动输入密码,剧本会自动读取密码文件并执行。

步骤 5:解密 / 重新加密剧本(可选)
  • 永久解密:若后续无需加密,可将加密文件解密为普通文件(不可逆,需谨慎):
ansible-vault decrypt aa.yml

输入密码后,db_deploy.yml 会变为普通文件,可用 cat 直接查看。

  • 重新加密:若需修改加密密码,通过 ansible-vault rekey 操作:
ansible-vault rekey aa.yml

执行后会先提示输入 “旧密码”,验证通过后再输入 “新密码”,完成后文件会用新密码重新加密。

http://www.dtcms.com/a/361374.html

相关文章:

  • UniApp + SignalR + Asp.net Core 做一个聊天IM,含emoji 表情包
  • 53_基于深度学习的野生菌菇检测识别系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
  • 通义灵码+支付 MCP:30 分钟实现创作打赏智能体
  • 【算法】124.二叉树中的最大路径和--通俗讲解
  • React前端开发笔记合集
  • Kubernetes集群升级与etcd备份恢复指南
  • 【系统架构设计(七)】 需求工程之:面向对象需求分析方法:统一建模语言(UML)(下)
  • 2025年工作后值得考的财会行业证书推荐,尤其是第二个!
  • 光颉(Viking)电阻CS25FTFR008 1225 0.008R/8mR 3W 1%介绍-华年商城
  • 中心扩展算法
  • 知识产品和标准化
  • 一文通透!为什么 DBSCAN 能检测任意形状的簇 ?
  • 【GIS图像处理】有哪些SOTA方法可以用于将1.5米分辨率遥感图像超分辨率至0.8米精度的?
  • 第二十八天-DAC数模转换实验
  • Java类和对象(下)
  • 【Doris入门】Doris数据表模型:明细模型(Duplicate Key Model)详解
  • shell——函数与数组
  • Selenium自动化测试框架
  • 艾莉丝努力练剑的创作纪念日:星河初启,牧梦长空
  • 如何做好出入库管理工作,好用的出入库管理软件有哪些
  • AI+PLM如何重构特种/高端复杂装备行业的工艺管理?
  • 大数据行业调研: 1列举大数据涉及到的各种行业,以及该行业未来发展的优势和劣势? 2列举大数据相关的岗位、岗位职责及其需要的专业技能?
  • ES6手录02-字符串与函数的扩展
  • 埃文科技亮相2025中部数字经济产业发展大会暨数智创新博览会
  • 华宇TAS应用中间件与长城科技两款产品完成兼容互认证
  • 深入浅出 HarmonyOS 应用开发:掌握 ArkTS 声明式 UI 与高效状态管理
  • 从零开始学习n8n-定时器+HTTP+飞书多维表格(上)
  • 基于高量子效率sCMOS相机的激光光斑衍射计算成像实验
  • 基于Flask的企业级产品信息管理系统技术实现笔记
  • Git中批量恢复文件到之前提交状态