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

嵌套Ansible角色中server变量作用域丢失问题求助

Ansible角色变量传递问题:server变量在create-service角色中丢失

背景

原有openldap_vpn角色用于运行wireguard-go Docker容器,现需改造为部署可执行DNS查询并启动podman的systemd服务,容器内包含负责隧道转发的依赖服务。角色调用链路为:openldap_vpn → podman_wireguard_forwarder → podman_user_service → create-service。create-service角色解析模板时依赖server变量,但该变量传递至create-service时丢失——不过在podman_user_service中通过debug模块验证时,server变量仍可正常访问。

相关配置代码

1. openldap_vpn角色vars目录下的server字典

server:
  public_key: MFrZG5hi29Yp0U/p2RauSUUH8EAiE2wBcqX3p8jkG28=
  inside_ip: whatever
  host: whatever
  port: whatever

2. openldap_vpn引入podman_wireguard_forwarder的配置

---
- include_role: name=podman_wireguard_forwarder
  vars:
    name: openldap_vpn
    # needs private key
    listen_port: "{{ server.port }}"
    peers:
    - allowed_ips:
      - "{{ server.inside_ip }}/32"
      endpoint: ENDPOINT_IP
      public_key: "{{ server.public_key }}"
    forward_port: 3389
    forward_dst:
      host: "{{ server.inside_ip }}"
      port: 3389
    config_prepare_command: "ip=\"$(getent hosts '{{ server.host }}' | awk '{ print $1 }')\" ; sed -E \"s/ENDPOINT_IP/$ip/\""

3. podman_wireguard_forwarder的关键任务

- name: install wireguard config template
  become: yes
  become_user: "{{ user }}"
  template:
    src: wireguard_config
    dest: "{{ wg_config }}.template"

- include_role: name=podman_user_service
  vars:
    service_name: "{{ service_name_vpn }}"
    params: |-
      --network "{{ podman_network }}" \
      --cap-add=NET_ADMIN \
      -v /dev/net/tun:/dev/net/tun \
      -v "{{ wg_config }}:/etc/wireguard/wg0.conf"
    image: docker.io/masipcat/wireguard-go:latest
    start_pre: "/bin/sh -c '{{ config_prepare_command }}' < '{{ wg_config}}.template' > '{{ wg_config }}'"

4. podman_user_service的关键任务

- debug:
    msg: "still works: {{ server }}"

- name: "update podman image {{ image }}"
  become: yes
  become_user: "{{ user }}"
  shell: podman image pull "{{ image }}"
  when: not image | regex_search('^localhost/')

- include_role: name=create-service

5. create-service中执行失败的任务

- name: "copy {{ service_name }} service file"
    become: yes
    become_user: "{{ user if scope == 'user' else omit }}"
    template:
      src: service
      dest: "\
          {{ '/home/' + user + '/.config/systemd/user' if scope == 'user' else '/etc/systemd/system' }}\
          /{{ service_name }}.service"

报错信息

ansible.errors.AnsibleUndefinedVariable: [{'allowed_ips': ['{{ server.inside_ip }}/32'], 'endpoint': 'ENDPOINT_IP', 'public_key': '{{ server.public_key }}'}]: 'server' is undefined. 'server' is undefined.

解决方法

  1. 显式传递变量:在podman_user_service引入create-service时,手动将server变量传递过去,因为Ansible默认不会自动将父角色的变量传递给嵌套调用的子角色。修改podman_user_service中的角色引入代码:
- include_role: name=create-service
  vars:
    server: "{{ server }}"
  1. 提前渲染模板依赖值:检查create-service使用的service模板文件,若模板中直接引用了server变量的字段,可在调用create-service前,将这些字段提前渲染为独立变量并传递,避免模板依赖上层角色的变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:53:13