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

为何Ansible Playbook会忽略--check参数?

问题:Ansible --check模式下routeros_command模块仍执行实际修改

问题场景

我在测试针对MikroTik路由器的简单Ansible Playbook,Playbook内容如下:

--- 
- hosts: mikrotiks
  connection: network_cli 
  gather_facts: no 

  vars: 
    ansible_network_os: routeros 
    ansible_user: admin 

  tasks: 
  - name: Add Basic FW Rules 
    routeros_command: 
      commands: 
        - /ip firewall nat add chain=srcnat out-interface=ether1 action=masquerade

执行带--check参数的命令:

ansible-playbook -i hosts mikrotik.yml --check

但发现任务实际已执行,输出结果:

PLAY [mikrotiks] **************************************************************************************************************************************

TASK [Add Basic FW Rules] **************************************************************************************************************************************
changed: [192.168.1.82]

PLAY RECAP **************************************************************************************************************************************
192.168.1.82               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

当前ansible.cfg为全新安装后的默认配置。

原因分析

routeros_command属于原始命令执行类模块,核心作用是直接在设备上运行指定的RouterOS命令,默认不支持Ansible的--check模式。该模块无法预判命令执行后的状态变化,也不具备幂等性检查逻辑,因此即使加上--check参数,它仍然会实际执行命令并返回changed状态。

解决方案

1. 使用幂等专用模块替代

改用RouterOS专属的routeros_firewall_nat模块,这类模块原生支持幂等性和--check模式:会先检查目标规则是否已存在,仅在规则缺失时创建;--check模式下只会模拟操作,不会实际修改设备配置。

- name: Add Basic FW Rules (Idempotent)
  routeros_firewall_nat:
    chain: srcnat
    out_interface: ether1
    action: masquerade
    state: present

2. 手动兼容check模式(针对command模块)

如果必须使用routeros_command,可以先检查规则是否存在,再根据结果决定是否执行添加操作,同时通过check_mode变量控制行为:

- name: Check if NAT rule exists
  routeros_command:
    commands:
      - /ip firewall nat print where chain=srcnat out-interface=ether1 action=masquerade
  register: nat_rule_check
  check_mode: no  # 强制在check模式下执行检查,获取真实状态

- name: Add Basic FW Rules
  routeros_command:
    commands:
      - /ip firewall nat add chain=srcnat out-interface=ether1 action=masquerade
  when: nat_rule_check.stdout | length == 0
  check_mode: yes  # check模式下不执行该任务,仅模拟

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 13:48:19