首页/系统与基础设施/自动化运维速查/同剧本跨发行版复用的方法
Ansible 核心70 条

同剧本跨发行版复用的方法

跨发行版复用同一份剧本的核心是把差异变成数据:用发行版家族事实查映射表定位包名、服务名与配置路径,优先使用通用包与服务模块,分支要有兜底或显式失败,并用多系统测试矩阵验证幂等与结果。

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

同一套剧本跑不同发行版

Linux 发行版之间,包名、服务名、配置路径、默认参数都可能不同。让一份剧本同时适配多发行版,靠的不是到处写条件判断,而是把差异集中成数据:用事实里的发行版信息去查一张取值表,任务逻辑保持不变。这样新增一个发行版只是往表里加一行,而不是再改一遍剧本。

基本信息

判断依据事实中的发行版家族与发行版名称字段(采集后可用)
数据组织角色变量里按家族分组的取值表,兜底值单独列一项
通用模块优先用软件包、服务管理的通用模块,由它适配具体系统
常见差异包名、服务单元名、配置路径、仓库配置方式、安全机制
验证方式在每种目标系统上跑检查模式,并连跑两次验证幂等
版本边界同一发行版的不同大版本行为也可能不同,以官方文档为准

典型使用场景

  • 企业内混合环境:既有主流商业发行版也有社区发行版,共用一套基线角色
  • 逐步迁移:老系统尚未下线、新系统已上线,只维护一份配置逻辑
  • 容器与虚拟机组合:镜像基线与裸机基线共用同一套角色
  • 第三方交付:角色交给不同客户环境执行,需要适配对方系统
  • 云上多镜像:同一云厂商的不同基础镜像也常来自不同家族
  • 回归验证:新增一种目标系统时,把验证结果固化成测试矩阵

差异用数据表达

差异用数据表达
- name: 按发行版家族取包名(映射表放角色变量里)
  ansible.builtin.package:
    name: "{{ pkg_map[ansible_os_family] | default(pkg_map['default']) }}"
    state: present
  vars:
    pkg_map:
      Debian: apache2          # 同一个软件在不同家族里叫法不同
      RedHat: httpd
      Suse: apache2
      default: httpd

- name: 配置目录同样走映射表,不在任务里写条件
  ansible.builtin.template:
    src: app.conf.j2
    dest: "{{ conf_map[ansible_os_family] | default(conf_map['default']) }}/app.conf"
  vars:
    conf_map:
      Debian: /etc/apache2
      RedHat: /etc/httpd
      default: /etc/apache2

- name: 服务名也走变量,避免写死在任务里
  ansible.builtin.service:
    name: "{{ svc_name }}"
    state: started
    enabled: true

常见差异维度

维度表现处理方式
包名同名软件在不同发行版里叫法不同映射表按家族取值,保留兜底项
包管理器命令与模块不同优先用通用包模块,必要时按家族分支
服务单元名服务名与单元文件位置不同服务名变量化,不要写死在任务里
配置路径同一软件的配置目录布局不同路径变量化或按家族取值
安全机制强制访问控制与防火墙工具不同差异封在独立任务文件里按家族引入
初始化系统新旧系统初始化方式不同先确认目标系统实际情况再决定写法
“通用模块优先”是降低差异维护量的关键:软件包与服务管理这类模块本身就会适配目标系统,只有模块覆盖不到的地方才需要按家族分支。把分支控制在少数几个取值点,比在任务里到处判断更易验证。
按发行版分支的逻辑必须有兜底或显式失败:遇到未覆盖的家族时,宁可任务立刻报错,也不要静默套用默认值,否则会在某台机器上以看似成功的方式写入错误配置,事后极难发现。

验证与维护

每支持一种新系统,都跑一遍完整验证:检查模式看预演结果、连跑两次看幂等、抽样核对配置文件的实际内容。把这些验证固化成一份测试矩阵(哪种系统、哪个版本、覆盖哪些角色),后续改角色时按矩阵回归,才不会出现“修好了新系统、弄坏了老系统”。

易错点

  • 把包名、服务名、配置路径写死在任务里,换一个发行版就要改剧本
  • 按家族分支却没有兜底与显式失败,未覆盖的系统静默套用默认值
  • 依赖某个发行版专有的命令或工具,在其它系统上直接命令不存在
  • 只在一种系统上验证就宣称通用,其它系统上线后集中暴露差异
  • 判断逻辑散落在几十个任务里,取值表失去单一来源,改一处漏一处

数据来源与参考

  • Ansible 官方文档 ansible.builtin.package 与 ansible.builtin.service 模块
  • Ansible 官方文档 Facts and magic variables(ansible_os_family 等)
  • Ansible 官方文档 Roles 变量与 defaults 说明

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/automation/cross-distribution-playbook-reuse.html

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