为什么变量在 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 个变量:
在库存中group_vars/*(优先级 6)*
jump_host: 'https://henms-haproxy.sharedtcs.net/'
in inventory 文件或脚本组 vars (prio 2)*
jump_host: henms-haproxy.sharedtcs.net
第一个覆盖第二个,因为优先级更高。
*
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_hostname
和 inventory_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:
设置
+---------+ +-----------+ +----------+
| 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 个变量:
在库存中group_vars/*(优先级 6)
*
jump_host: 'https://henms-haproxy.sharedtcs.net/'
in inventory 文件或脚本组 vars (prio 2)
*
jump_host: henms-haproxy.sharedtcs.net
第一个覆盖第二个,因为优先级更高。
*
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_hostname
和 inventory_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: