为什么变量在 Ansible 清单配置中被覆盖

Why is variable overwritten in Ansible inventory configuration

设置

+---------+         +-----------+         +----------+
| Ansible |         | jump_host |         |  target  |
+---------+         +-----------+         +----------+
                  hproxy.shared.net    webserver.shared.net

具有以下 Ansible 清单:

hosts:
    target:
        ansible_host: webserver.shared.net
vars:
    jump_host: hproxy.shared.net
    ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q {{jump_host}}"'

我正在 Ansible 主机上玩这个简单的任务:

- hosts: target
  name: Execute remote cmd
  command:
    cmd: ls -al
  register: output

问题

在 Ansible 控制台输出中,我收到此错误:

ssh: Could not resolve hostname https://hproxy.shared.net/: Name or service not known

详细错误:

<webserver.shared.net> SSH: EXEC sshpass -d11 ssh -C -o ControlMaster=auto -o ControlPersist=60s-o ConnectTimeout=10 -o 'ProxyCommand=ssh -W %h:%p https://hproxy.shared.net/' webserver.shared.net '/bin/sh -c '"'"'echo ~user && sleep 0'"'"'' ! <webserver.shared.net> (255, b'', b'OpenSSH_7.6p1 Ubuntu-4ubuntu0.3, OpenSSL 1.0.2n 7 Dec 2017\r\ndebug1: /etc/ssh/ssh_config line 19: Applying options for *\r\nssh: Could not resolve hostname https://hproxy.shared.net/: Name or service not known\r\nssh_exchange_identification: Connection closed by remote host\r\n')

但是当我以这种方式配置库存时,运行 完美:

[...]
vars:
    ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q hproxy.shared.net"'

(hproxy.shared.net 而不是 {{jump_host}})

很明显,问题出在主机名前面添加 https://。

问题

有没有办法阻止 Ansible 在主机名前面添加这个 https:// 前缀,当引用它们作为 Jinja 变量时?

解决方案

我有 2 个变量:

第一个覆盖第二个,因为优先级更高。

* Ansible 变量优先级:https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable

向 Zeitounator 致敬

请注意,正如您问题中所粘贴的那样,您的清单应该会触发错误,因为它在几个方面不遵守 yaml 清单格式约定:host 错字(=> hosts),主机定义是字符串而不是字典...此外,您使用 jump_host 作为变量标识符,而它只是您清单中的主机昵称。您确定 var 没有在别处定义吗?

这里有几个例子可以让你走上正轨。尽管允许“快捷方式”避开顶层的 all 组,但我坚持使用下面的 standard

你真的需要将你的跳转主机定义为潜在的 ansible 目标(即你真的要部署在该主机本身上)吗?如果没有,您可以将库存修改为:

---
all:
  vars:
    jump_host_address: hproxy.shared.net
    ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q {{ jump_host_address }}"'
  hosts:
    target:
      ansible_host: webserver.shared.net

如果您想将跳转主机保留在您的库存中,您很可能不会使用代理命令连接到它

---
all:
  hosts:
    jump_host:
      ansible_host: hproxy.shared.net
  children:
    targets_behind_jump:
      vars:
        ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q {{ hostvars.jump_host.ansible_host }}"'
      hosts:
        target:
          ansible_host: webserver.shared.net

最后,您还应该问问自己,您是否真的需要为房东起个昵称。在 IMO 中直接在清单中管理完整的 fqdn 名称要容易得多(并且可以访问像 inventory_hostnameinventory_hostname_short 这样的变量)。下面是两个相同的示例,使用全名,但未明确声明跳转主机。

---
all:
  vars:
    jump_host_address: hproxy.shared.net
    ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q {{ jump_host_address }}"'
  hosts:
    webserver.shared.net:
---
all:
  vars:
    jump_host_name: hproxy.shared.net
  hosts:
    hproxy.shared.net:
  children:
    targets_behind_jump:
      vars:
        ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q {{ hostvars[jump_host_name].inventory_hostname }}"'
      hosts:
        webserver.shared.net: