如何在运行时动态确定的主机上运行角色

问题描述 投票:0回答:1

我希望将应用程序配置从一台主机迁移到另一台主机。在任一主机上运行的任务有很大不同,它们保证自己的角色。理想情况下,我正在寻找通过网络调用动态确定的目标主机,而不是提供给剧本。

不幸的是,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')
ansible ansible-2.x
1个回答
0
投票

问:“...寻找通过网络调用动态确定的目标主机...

对于库存

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
© www.soinside.com 2019 - 2024. All rights reserved.