You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible:结合条件语句使用copy模块无法正确写入目标主机名

问题分析与解决方案

核心问题排查

  1. set_fact条件无效:原Playbook中when: certData.json > 0是错误判断——certData.json是字典类型,无法直接与数字比较,导致该任务始终跳过,activeCertData变量从未被定义,后续循环判断时会出现变量不存在的异常。
  2. 未处理变量缺失场景:循环中直接访问hostvars[host]['activeCertData'],若变量未定义会触发错误,无法正确识别符合条件的主机。

调整后的Playbook代码

---
- hosts: all
  gather_facts: false
  
  tasks:
    - name: Print certData.json
      debug:
        msg: "{{ certData.json }}"

    - name: Set activeCertData with JMESPATH
      set_fact:
        activeCertData: "{{ certData.json | json_query('items[?status != `revoked`].{ currentCertID: id, currentCertSN: serialHex, status: status, cn: cn}') }}"
      # 修正条件:判断证书数据中存在有效条目
      when: certData.json.items | length > 0

    - name: Generate new devices list file
      copy:
        dest: newDevices.txt
        content: |-
          {% for host in ansible_play_hosts %}
          {# 处理activeCertData未定义的情况,默认返回空列表 #}
          {% if hostvars[host].get('activeCertData', []) | length == 0 %}
          {{ host }}
          {% endif %}
          {% endfor %}
      delegate_to: localhost
      run_once: true

关键调整说明

  • 修正变量赋值触发条件:改用certData.json.items | length > 0判断证书数据中是否存在条目,确保activeCertData变量能被正确赋值。
  • 安全访问变量:使用hostvars[host].get('activeCertData', [])替代直接索引,当变量未定义时自动返回空列表,既避免报错又保证判断逻辑准确。
  • 逻辑验证:以示例中的A01主机为例,其证书status为Active-Pending Install(不属于revoked),因此activeCertData长度为1,不会被写入文件;若主机无有效证书(items为空或所有条目status为revoked),则会被正确写入文件。

如果需要追加符合条件的主机而非覆盖文件,可将copy模块替换为lineinfile模块:

- name: Append new devices to file
  lineinfile:
    path: newDevices.txt
    line: "{{ inventory_hostname }}"
    create: true
  delegate_to: localhost
  when: hostvars[inventory_hostname].get('activeCertData', []) | length == 0

此方式会让每个符合条件的主机单独执行任务,将自身主机名追加到文件中。


内容的提问来源于stack exchange,提问作者stminion001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:15:49