首页/系统与基础设施/自动化运维速查/多环境清单与变量的分离设计
Ansible 核心70 条

多环境清单与变量的分离设计

多环境共存的正确做法是按环境拆分清单与变量目录、让剧本保持环境无关、秘密与口令来源按环境隔离,并且不设默认清单、执行时显式指定环境,再在剧本开头用断言做一道环境自检,防止拿错清单。

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌​​​​‌​‌‌‌​‌​‌​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌​‌‌​‌​‌‌​​​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌‌‌​‌‌​‌‌​‌​‌‌‌​‌​‌​‌‌​‌‌​​​‌‌‌​‌​​​‌‌​‌​​‌​​‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌‌​‌‌​​‌‌​‌​​‌​‌‌‌​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌​​‌‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌‌​‌​​​​‌​‌‌​‌​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌‌​‌‌​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌‌​​‌​​‌‌‌‌​​‌​​‌​‌‌​‌​‌‌‌​‌‌​​‌‌​​​​‌​‌‌‌​​‌​​‌‌​‌​​‌​‌‌​​​​‌​‌‌​​​‌​​‌‌​‌‌​​​‌‌​​‌​‌​​‌​‌‌​‌​‌‌‌​​‌‌​‌‌​​‌​‌​‌‌‌​​​​​‌‌​​​​‌​‌‌‌​​‌​​‌‌​​​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​

环境隔离靠清单而不是靠判断

同一份 playbook 要在测试与生产上跑,最容易走偏的做法是在剧本里写一堆“如果是生产就怎样”的判断:久而久之两套逻辑交织,谁也不敢改。更清晰的方式是按环境拆分清单与变量:一套编排逻辑保持不变,环境差异全部落在各自的清单目录与变量文件里,切换环境只是换一个清单路径。

基本信息

清单组织inventory/<环境>/ 各一份清单,环境之间互不引用
变量组织每个环境目录下自带 group_vars 与 host_vars
剧本要求环境无关:不出现测试或生产的字面量判断
秘密隔离各环境独立的口令来源与加密文件,生产密钥单独管控
连接差异跳板机、端口、认证方式等按环境写在清单变量里
防误操作不给默认清单,执行时必须显式指定环境

典型使用场景

  • 三套环境(开发、预发、生产)共用一套角色与剧本
  • 生产与测试的连接方式不同:生产走跳板机、测试直连
  • 参数取值不同:副本数、限流阈值、备份保留策略按环境区分
  • 密钥隔离:生产凭据只对少数人可见,测试环境用另一套
  • 上线前演练:先在预发清单上跑同一份剧本,验证流程本身
  • 防止误操作:限制生产清单的访问与执行权限,测试清单保持可频繁重跑

清单与变量的分环境写法

清单与变量的分环境写法
# inventory/production/hosts.ini
# [web]
# web1.prod.internal
#
# inventory/production/group_vars/all/
#   vars.yml         副本数、限流、备份保留等生产取值
#   vault.yml        生产秘密,单独加密
#
# inventory/staging/hosts.ini
# [web]
# web1.stage.internal
#
# inventory/staging/group_vars/all/
#   vars.yml         测试取值(副本数更小、日志更详细)
#
# 执行时永远显式指定环境清单
# ansible-playbook -i inventory/staging site.yml --check --diff
# ansible-playbook -i inventory/production site.yml

# 环境自检任务(放进剧本开头,防止清单拿错)
# - name: 断言操作对象属于预期环境
#   ansible.builtin.assert:
#     that:
#       - inventory_hostname | regex_search(expected_env_suffix)
#     fail_msg: "当前清单与预期环境不一致,已中止"

差异该放在哪一层

差异类型放置位置理由
环境参数(阈值、副本数)环境目录下的分组变量与环境绑定,切换清单即生效
连接方式(跳板、端口)环境清单内联或清单级变量属于访问路径,不是业务参数
秘密值环境各自的加密文件与口令来源隔离访问权限与轮换节奏
主机个别差异host_vars避免污染分组级取值
编排流程本身保持共用流程差异说明分层没做干净
不要给 ansible.cfg 配一个指向生产的默认清单:任何忘记加 -i 的执行都会直接打到生产。宁可让工具在缺清单时报错,也不要让默认值替你选择一个环境。
多环境共用一个分组名时,变量优先级容易让人误判:两个环境的同名变量文件不会同时生效,但如果清单目录写错或清单被误改,实际取值会静默变成另一个环境的值,执行结果表面成功、配置却是错的。用开头断言做一道环境自检是低成本的保险。

怎么验证隔离是否彻底

做一次交叉实验:用预发清单跑生产参数的检查,看是否所有差异都来自清单与变量文件;再 grep 剧本里是否出现环境字面量。如果剧本里干净、差异全部落在清单目录里,隔离就到位了;反之,说明还有环境判断混在逻辑里,应当继续拆。

易错点

  • 在剧本里用环境名称做条件分支,逻辑随环境分叉,维护成本不断累积
  • 配置了默认清单指向生产,漏写清单参数时直接对生产执行
  • 环境之间共用一份加密文件与口令,权限隔离失效,秘密范围被放大
  • 两个环境重复定义同一变量且取值不同,改了一处却按另一处执行
  • 缺少环境自检,把生产清单当测试清单执行且未及时发现

数据来源与参考

  • Ansible 官方文档 How to build your inventory(多环境组织方式)
  • Ansible 官方文档 Variable precedence: where should I put a variable
  • Ansible 官方文档 ansible.builtin.assert 模块

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/automation/multi-environment-inventory-variable-separation.html

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌​​​​‌​‌‌‌​‌​‌​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌​‌‌​‌​‌‌​​​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌‌‌​‌‌​‌‌​‌​‌‌‌​‌​‌​‌‌​‌‌​​​‌‌‌​‌​​​‌‌​‌​​‌​​‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌‌​‌‌​​‌‌​‌​​‌​‌‌‌​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌​​‌‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌‌​‌​​​​‌​‌‌​‌​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌‌​‌‌​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌‌​​‌​​‌‌‌‌​​‌​​‌​‌‌​‌​‌‌‌​‌‌​​‌‌​​​​‌​‌‌‌​​‌​​‌‌​‌​​‌​‌‌​​​​‌​‌‌​​​‌​​‌‌​‌‌​​​‌‌​​‌​‌​​‌​‌‌​‌​‌‌‌​​‌‌​‌‌​​‌​‌​‌‌‌​​​​​‌‌​​​​‌​‌‌‌​​‌​​‌‌​​​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​