如何在单个Molecule场景中使用不同版本的Ansible collection?
问题根本原因
Ansible 执行 playbook 时会在启动阶段预解析所有静态引用的角色/集合,你把「安装旧版本集合」和「引用集合内角色」放在了同一个 play 里,Ansible 解析到
include_role代码的时候,安装集合的任务还没有执行,自然找不到对应角色。第二次运行时旧集合已经在上次执行过程中安装完成,所以不会报错。
解决方案
方案1:拆分prepare playbook为两个独立play(改造成本最低)
把安装集合和引用角色拆到两个不同的play中,第二个play会在第一个play完全执行完后再启动解析,就能正常读取到刚安装的旧版本集合:
--- # 第一个Play:仅负责安装旧版本集合 - name: Install old collection hosts: localhost gather_facts: false tasks: - name: Install previous collection version command: >- ansible-galaxy collection install -r {{ lookup('env', 'MOLECULE_SCENARIO_DIRECTORY') }}/collections-upgrade.yml -p {{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}/collections changed_when: true # 第二个Play:执行旧版本软件部署 - name: Prepare old software version hosts: all become: true become_method: sudo gather_facts: true tasks: - name: Include installation role from old collection include_role: name: namespace.collection.role
该方案无需修改molecule.yml的原有序列配置。
方案2:调整Molecule序列,用两次独立依赖步骤安装集合(逻辑更清晰)
把所有集合安装逻辑从playbook中剥离,交给Molecule步骤统一管理,避免playbook内的解析时序问题:
- 修改
molecule.yml的执行序列,用自定义command步骤分别安装新旧版本集合:
scenario: converge_sequence: - create # 安装旧版本集合 - command: ansible-galaxy collection install -r ${MOLECULE_SCENARIO_DIRECTORY}/collections-upgrade.yml -p ${MOLECULE_EPHEMERAL_DIRECTORY}/collections - prepare # 直接用已安装的旧集合部署旧版软件 # 强制安装新版本集合覆盖旧版本 - command: ansible-galaxy collection install -r ${MOLECULE_SCENARIO_DIRECTORY}/collections.yml -p ${MOLECULE_EPHEMERAL_DIRECTORY}/collections --force - converge # 用新版本集合执行升级 test_sequence: - lint - destroy - syntax - create - command: ansible-galaxy collection install -r ${MOLECULE_SCENARIO_DIRECTORY}/collections-upgrade.yml -p ${MOLECULE_EPHEMERAL_DIRECTORY}/collections - prepare - command: ansible-galaxy collection install -r ${MOLECULE_SCENARIO_DIRECTORY}/collections.yml -p ${MOLECULE_EPHEMERAL_DIRECTORY}/collections --force - converge - idempotence - verify - destroy
- 删掉
prepare.yml中原有的安装旧版本集合的任务,仅保留部署软件的逻辑即可。
附加验证配置
如果修改后仍然报找不到角色,可检查报错信息中的搜索路径是否包含你配置的临时集合目录,可在molecule.yml中显式追加集合搜索路径:
provisioner: name: ansible env: ANSIBLE_COLLECTIONS_PATH: ${MOLECULE_EPHEMERAL_DIRECTORY}/collections:~/.ansible/collections:/usr/share/ansible/collections
内容的提问来源于stack exchange,提问作者Anatoli
相关产品推荐
相关产品推荐

