我希望将应用程序配置从一台主机迁移到另一台主机。在任一主机上运行的任务有很大不同,它们保证自己的角色。理想情况下,我正在寻找通过网络调用动态确定的目标主机,而不是提供给剧本。
不幸的是,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')
问:“...寻找通过网络调用动态确定的目标主机...”
对于库存
example.ini
[roles:children]
control
managed
[control]
controlnode.example.com
[managed]
remotenode.example.com
managednode.example.com
一个最小的示例手册
example.yml
---
- hosts: control
become: false
gather_facts: false
tasks:
- name: Get target host
uri:
url: "{{ URL }}"
return_content: true
register: response
vars:
URL: http://www.example.com
- name: Determined dynamically from a web call
add_host:
hostname: "{{ response.content | regex_search('www(.*?)org') }}"
group: managed
- hosts: managed
become: false
gather_facts: false
tasks:
- name: Target hosts
debug:
msg: "{{ inventory_hostname }}"
通过
调用ansible-playbook --inventory example.ini example.yml
将产生
的输出PLAY [control] **********************************
TASK [Get target host] **************************
ok: [controlnode.example.com]
TASK [Determined dynamically from a web call] ***
changed: [controlnode.example.com]
PLAY [managed] **********************************
TASK [Target hosts] *****************************
ok: [remotenode.example.com] =>
msg: remotenode.example.com
ok: [managednode.example.com] =>
msg: managednode.example.com
ok: [www.iana.org] =>
msg: www.iana.org