我希望将应用程序配置从一个主机迁移到另一个主机。在两个主机上运行的任务有很大不同,因此它们有自己的角色。理想情况下,我希望目标主机能够通过网络调用动态确定,而不是提供给剧本。
不幸的是,由于公司政策,delegate_to 已被限制,所以这不是一个选项。相反,我希望将目标主机作为变量提供给主机:但它要么不匹配,要么抱怨变量未定义。
简化的剧本
- hosts: all
tasks:
- name: Get target host
uri:
url: http://url_link.com/get_gateways.cgi?name={{ target_gateway }}
timeout: 5
return_content: true
register: connection_string
- name: store target host as fact
set_fact:
target_host: "{{ connection_string.content }}"
- name: debug connection string
debug:
var: target_host
- debug:
var=hostvars[inventory_hostname]["connection_string"].content
- hosts: target_host # Case 1
- hosts: "{{ hostvars[inventory_hostname]['connection_string'].content }}" #Case 2
tasks:
- import_role:
name: gateway_migration
使用target_host时的输出:
PLAY [all] ************************************************************************************************************************************************************************************************************************************************************************************************************************************************
TASK [Initialising the host specific facts only.] *********************************************************************************************************************************************************************************************************************************************************************************************************
ok: [myhost]
TASK [Get target host] ************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [myhost]
TASK [store target host as fact] **************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [myhost]
TASK [debug] **********************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [myhost] => {
"target_host": [
"target-1"
]
}
TASK [debug] **********************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [sd-a6l1-kupa.nam.nsroot.net] => {
"hostvars[inventory_hostname][\"connection_string\"].content": "target-1"
}
[WARNING]: Could not match supplied host pattern, ignoring: target_host
PLAY [target_host] ****************************************************************************************************************************************************************************************************************************************************************************************************************************************
skipping: no hosts matched
对于情况 2(用 target_host 替换 hostvars 字典时,错误消息几乎相同)。在这两种情况下,它都声称变量未定义:
ERROR! The field 'hosts' has an invalid value, which includes an undefined variable. The error was: 'inventory_hostname' is undefined. 'inventory_hostname' is undefined
实际上,我正在对从 url 返回的字符串运行正则表达式,并且当尝试不使用“jinja 语法”时,删除引号和花括号,我得到以下内容:
[WARNING]: Could not match supplied host pattern, ignoring: hostvars[inventory_hostname]['connection_string'].content | regex_search('(.*?)~(.*?)~(.*?)~(.*?)'
[WARNING]: Could not match supplied host pattern, ignoring: '\\1')