Loading... # Ansible 变量管理完全指南 # 一、概述 ## 1. 简介 ### A. 是什么 Ansible 变量是 Playbook 中实现参数化配置的核心机制,通过变量可以实现同一套 Playbook 适配不同环境的配置需求。 ### B. 为什么学 - 解决多环境配置复用问题,避免为 dev/test/prod 维护多份相似 Playbook - 理解变量优先级规则,避免同名变量导致的不可预测行为 - 掌握变量工程化组织方法,让项目可维护、可扩展、可协作 ### C. 学完能做什么 - 使用三种方式定义变量(Playbook vars / Inventory 组变量 / 命令行 -e) - 通过实验验证变量优先级,不再靠猜 - 使用 vars_files 和 group_vars 实现工程化变量管理 - 使用 register 捕获命令执行结果并在后续任务中使用 - 按"环境差异/角色共性/主机个例"组织变量结构 ## 2. 前置知识 ### A. 必备技能 - 了解 Playbook 基本结构和语法 - 掌握 Inventory 主机分组概念 - 熟悉基本模块使用方法 ### B. 推荐知识 - YAML 基础语法 - Linux 命令行操作 # 二、实验环境 ## 1. 系统要求 控制端:Rocky Linux 9.6,IP 192.168.10.10 受控端环境配置: | 环境 | 角色 | 主机名 | IP | |------|------|--------|-----| | dev | web | dev-web1 | 192.168.10.11 | | dev | web | dev-web2 | 192.168.10.12 | | dev | db | dev-db1 | 192.168.10.21 | | test | web | test-web1 | 192.168.10.31 | | test | db | test-db1 | 192.168.10.41 | | prod | web | prod-web1 | 192.168.10.51 | | prod | web | prod-web2 | 192.168.10.52 | | prod | db | prod-db1 | 192.168.10.61 | ## 2. 环境准备 创建工作目录: ```bash mkdir -p ~/ansible-07/{vars,group_vars} cd ~/ansible-07 ``` 创建包含环境组和角色组的 Inventory: ```bash cat > inventory <<'EOF' [dev_web] dev-web1 ansible_host=192.168.10.11 dev-web2 ansible_host=192.168.10.12 [dev_db] dev-db1 ansible_host=192.168.10.21 [test_web] test-web1 ansible_host=192.168.10.31 [test_db] test-db1 ansible_host=192.168.10.41 [prod_web] prod-web1 ansible_host=192.168.10.51 prod-web2 ansible_host=192.168.10.52 [prod_db] prod-db1 ansible_host=192.168.10.61 [dev:children] dev_web dev_db [test:children] test_web test_db [prod:children] prod_web prod_db [web:children] dev_web test_web prod_web [db:children] dev_db test_db prod_db EOF ``` 验证连通性: ```bash ansible all -i inventory -m ping ``` # 三、变量定义方式 ## 1. 基本术语 - vars:Playbook 内定义的变量 - Inventory 组变量:在 Inventory 文件中为组定义的变量 - 命令行变量:通过 -e 参数临时传入的变量 - vars_files:独立变量文件 - group_vars:按组自动加载的变量目录 - register:注册变量,用于存储任务执行结果 ## 2. 三种基础定义方式 ### A. Playbook 内定义变量(vars) 适用场景:演示、小实验、变量很少的情况 示例:vars_in_playbook.yml ```yaml - name: Vars in playbook demo hosts: dev_web vars: app_name: demoapp app_port: 8080 tasks: - name: Show app config command: echo "app={{ app_name }} port={{ app_port }}" ``` 执行: ```bash ansible-playbook -i inventory vars_in_playbook.yml ``` ### B. Inventory 定义组变量 适用场景:多环境配置,工程中最常用 在 Inventory 末尾添加组变量: ```bash cat >> inventory <<'EOF' [dev:vars] env=development app_port=8080 [prod:vars] env=production app_port=80 EOF ``` 示例:vars_from_inventory.yml ```yaml - name: Vars from inventory demo hosts: web tasks: - name: Show env and port command: echo "env={{ env }} port={{ app_port }}" ``` 分别执行不同环境: ```bash ansible-playbook -i inventory vars_from_inventory.yml -l dev ansible-playbook -i inventory vars_from_inventory.yml -l prod ``` 同一 Playbook 不改一行,输出随环境自动切换,这就是工程化"可复用"的关键能力。 ### C. 命令行传变量(-e) 适用场景:临时调试 ```bash ansible-playbook -i inventory vars_from_inventory.yml -l dev -e "app_port=9999" ``` 注意:工程中大量依赖 -e 会导致"不可追溯",后期排错很痛苦。 ## 3. 变量优先级规则 ```mermaid graph TD A[变量优先级] --> B[组变量<br/>Inventory / group_vars] A --> C[主机变量] A --> D[Playbook vars] A --> E[命令行 -e<br/>最高优先级] B --> F[优先级: 低] C --> G[优先级: 中低] D --> H[优先级: 中高] E --> I[优先级: 高] style F fill:#e1f5fe style G fill:#b3e5fc style H fill:#81d4fa style I fill:#4fc3f7 ```   ### A. 验证实验 1:Playbook vars 覆盖 Inventory 组变量 Inventory 中 dev 已有 app_port=8080,在 Playbook 中定义同名变量 app_port=1234: ```yaml cat > priority_test.yml <<'EOF' - name: Priority test hosts: dev vars: app_port: 1234 tasks: - name: Show app_port command: echo "app_port={{ app_port }}" EOF ``` 执行: ```bash ansible-playbook -i inventory priority_test.yml ``` 预期输出:app_port=1234,说明 Playbook vars 优先级高于 Inventory 组变量。 ### B. 验证实验 2:命令行 -e 覆盖一切 ```bash ansible-playbook -i inventory priority_test.yml -e "app_port=9999" ``` 预期输出:app_port=9999,说明 -e 是最高优先级。 ### C. 记忆法 越临时的越优先。记忆顺序:组变量 < 主机变量 < Playbook vars < 命令行 -e # 四、变量工程化三件套 ## 1. 工程化演进路径 变量少:使用 vars 变量变多:使用 vars_files 真上项目:使用 group_vars ## 2. vars_files:变量文件化 创建变量文件 vars/app.yml: ```yaml cat > vars/app.yml <<'EOF' app_name: demoapp app_user: deploy EOF ``` 示例:vars_files_demo.yml ```yaml - name: vars_files demo hosts: dev_web vars_files: - vars/app.yml tasks: - name: Show app vars command: echo "name={{ app_name }} user={{ app_user }}" ``` 适用场景:多个 Playbook 共享一份变量,但变量不随组/环境自动切换。 ## 3. group_vars:按组自动加载 在 group_vars/ 目录下创建与组名同名的文件: ```bash cat > group_vars/dev.yml <<'EOF' env: development app_port: 8080 EOF cat > group_vars/prod.yml <<'EOF' env: production app_port: 80 EOF cat > group_vars/web.yml <<'EOF' app_name: demoapp EOF ``` 示例:group_vars_demo.yml ```yaml - name: group_vars demo hosts: web tasks: - name: Show config from group_vars command: echo "env={{ env }} app={{ app_name }} port={{ app_port }}" ``` 分别执行: ```bash ansible-playbook -i inventory group_vars_demo.yml -l dev ansible-playbook -i inventory group_vars_demo.yml -l prod ``` 效果: - 环境差异:dev.yml / prod.yml 自动切换 - 角色共性:web.yml 统一复用 - Playbook 不改一行 # 五、注册变量 ## 1. 工作原理 ```mermaid graph LR A[执行命令任务] --> B[register 注册结果] B --> C[访问输出字段] C --> D[后续任务使用] ```   ## 2. 最小可用示例 示例:register_demo.yml ```yaml - name: register demo hosts: dev tasks: - name: Get hostname command: hostname register: hostinfo - name: Print hostname and rc command: echo "hostname={{ hostinfo.stdout }} rc={{ hostinfo.rc }}" ``` 执行: ```bash ansible-playbook -i inventory register_demo.yml ``` 关键字段: - stdout:命令标准输出 - rc:返回码(0 通常表示成功) # 六、变量设计最佳实践 ## 1. 五条黄金规则 ### A. 环境差异放 group_vars/dev.yml、group_vars/prod.yml 例如:端口、域名、开关参数、数据库连接信息 ### B. 角色共性放 group_vars/web.yml、group_vars/db.yml 例如:应用名、日志目录、配置路径 ### C. 主机变量只解决"个例" 例如:某台机器 SSH 用户不同、端口不同。不要把环境差异写成一堆主机变量。 ### D. 同名变量只在一个地方定义 同名变量出现在多个文件/位置是排错噩梦。工程中建议用"约定"固定变量定义位置。 ### E. 变量命名要可读,避免缩写 推荐:app_port、db_host 避免:p、h ## 2. 变量组织架构 ```mermaid graph TD A[变量分类] --> B[环境差异变量] A --> C[角色共性变量] A --> D[主机个例变量] B --> E[group_vars/dev.yml] B --> F[group_vars/prod.yml] C --> G[group_vars/web.yml] C --> H[group_vars/db.yml] D --> I[Inventory 主机变量] style B fill:#fff3e0 style C fill:#e8f5e9 style D fill:#fce4ec ```   # 七、学习检查清单 学完本篇内容,你应该能够做到: - 会用三种方式定义变量(vars / Inventory / -e) - 通过实验验证优先级,不再靠猜 - 会用 vars_files 和 group_vars 做变量工程化 - 会用 register 拿到命令输出并继续使用 - 变量结构按环境差异/角色共性/主机个例组织 如果你已经能做到:一套 Playbook 适配 dev/prod 不改一行,那这篇就学到位了。 *** ## 参考资料 1. [变量用不好,Ansible 就废了一半-第7篇](https://mp.weixin.qq.com/s/gplBFxYb5UbqwOzjxuk3sg) 最后修改:2026 年 01 月 15 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏