如何在RouterOS的Ansible剧本或组变量中拼接ansible_user变量?
解决RouterOS Ansible用户自动添加后缀的问题
问题原因
你之前的写法报错是因为在Play的vars字段中重新定义ansible_user时,直接引用了{{ ansible_user }},导致模板渲染陷入递归循环——渲染该变量时需要不断调用自身,最终触发异常。
可行解决方案
方法一:通过group_vars全局配置(推荐)
针对routeros组创建专属变量文件,一次性配置所有RouterOS设备的连接参数和用户后缀,无需在每个Playbook中重复编写:
- 在Ansible项目目录下创建
group_vars/routeros.yml文件 - 写入以下内容:
ansible_connection: ansible.netcommon.network_cli ansible_network_os: community.network.routeros # 直接从inventory或环境变量获取原始用户,拼接后缀 ansible_user: "{{ hostvars[inventory_hostname].ansible_user | default(lookup('env', 'ANSIBLE_USER')) }}+cet512w"
hostvars[inventory_hostname].ansible_user:获取inventory中为该主机定义的原始用户值,避免递归引用default(lookup('env', 'ANSIBLE_USER')):如果inventory未定义用户,自动读取环境变量中的ANSIBLE_USER值
方法二:在Playbook中用set_fact延迟赋值
利用set_fact在Play执行阶段赋值,避开Play初始化时的模板递归问题:
- name: RouterOS - 示例剧本 hosts: routeros vars: - ansible_connection: ansible.netcommon.network_cli - ansible_network_os: community.network.routeros tasks: - name: 拼接用户后缀 set_fact: ansible_user: "{{ ansible_user }}+cet512w" # 后续执行RouterOS相关任务 - name: 获取系统标识信息 community.routeros.command: commands: /system identity print
方法三:Inventory中直接配置组变量
如果使用YAML格式的Inventory,可以在组级别直接定义拼接逻辑:
all: children: routeros: vars: ansible_connection: ansible.netcommon.network_cli ansible_network_os: community.network.routeros # 用主机级别的ansible_user拼接后缀(主机变量优先级高于组变量,不会递归) ansible_user: "{{ hostvars[inventory_hostname].ansible_user | default('admin') }}+cet512w" hosts: router1: ansible_host: 192.168.1.1 ansible_user: my_router_user router2: ansible_host: 192.168.1.2 ansible_user: another_router_user
内容的提问来源于stack exchange,提问作者Christoph
相关产品推荐
相关产品推荐

