首页 > 解决方案 > ansible meta:refresh_inventory 在任务执行中不包括以前不存在的主机

问题描述

前段时间,有人建议使用动态清单根据模板中的位置和其他变量生成不同的主机文件,但我遇到了一个很大的问题:

从模板创建清单后,我需要刷新它(我使用 meta: refresh_inventory 执行此操作)以便 Ansible 在新添加的主机上执行任务,但是,如果主机最初不在 hosts 文件中,则 ansible 不会执行任务在上面。另一方面,如果在更改主机文件后,新形成的文件中没有主机,那么 Ansible 会像应有的那样忽略主机,因此 refresh_inventory 完成了一半的工作。有没有办法解决这个问题?

例如,我有 1 个任务从模板生成主机文件,然后刷新库存,然后在所有主机上执行一个简单的任务,例如显示消息:

 tasks:
  - name: Creating inventory template
    local_action:
         module: template
         src: hosts.j2
         dest: "/opt/ansible/inventories/{{location}}/hosts"
         mode: 0777
         force: yes
         backup: yes
    ignore_errors: yes
    run_once: true

  - name: "Refreshing hosts file for {{location}} location"
    meta: refresh_inventory

  - name: Force refresh of host errors
    meta: clear_host_errors

  - name: Show message
    debug: msg="This works for this host"

如果初始 hosts 文件有主机 A、B、C、D,而新创建的清单有 B、C、D,则一切正常:

ok: [B] => {
    "msg": "This works for this host"
}
ok: [C] => {
    "msg": "This works for this host"
}
ok: [D] => {
    "msg": "This works for this host"
}

但是,如果新形成的主机文件有主机 B、C、D、E(E 不存在于初始主机文件中),那么结果又是:

ok: [B] => {
    "msg": "This works for this host"
}
ok: [C] => {
    "msg": "This works for this host"
}
ok: [D] => {
    "msg": "This works for this host"
}

缺少 E 的任务。现在,如果我重播剧本,只添加另一个主机,比如 F,那么结果如下所示:

ok: [B] => {
    "msg": "This works for this host"
}
ok: [C] => {
    "msg": "This works for this host"
}
ok: [D] => {
    "msg": "This works for this host"
}
ok: [E] => {
    "msg": "This works for this host"
}

但是没有 F,它在刷新之前已经添加到库存文件中。

那么,有什么想法吗?

标签: networkingautomationansiblerefreshinventory

解决方案


从基础引用

对于剧本中的每个剧本,您可以选择基础设施中的哪些机器作为目标...主机行是一个或多个组或主机模式的列表...

例如,可以在第 1 次游戏中创建库存并在第 2 次游戏中使用它。下面的剧本

- hosts: localhost
  tasks:
    - template:
        src: hosts.j2
        dest: "{{ playbook_dir }}/hosts"
    - meta: refresh_inventory

- hosts: test
  tasks:
    - debug:
        var: inventory_hostname

使用模板(适合您的需要)

$ cat hosts.j2
[test]
test_01
test_02
test_03

[test:vars]
ansible_connection=ssh
ansible_user=admin
ansible_become=yes
ansible_become_user=root
ansible_become_method=sudo
ansible_python_interpreter=/usr/local/bin/python3.6
ansible_perl_interpreter=/usr/local/bin/perl

PLAY [localhost] ****************************************************************************

TASK [Gathering Facts] **********************************************************************
ok: [localhost]

TASK [template] *****************************************************************************
changed: [localhost]

PLAY [test] *********************************************************************************

TASK [Gathering Facts] **********************************************************************
ok: [test_02]
ok: [test_01]
ok: [test_03]

TASK [debug] ********************************************************************************
ok: [test_01] => {
    "inventory_hostname": "test_01"
}
ok: [test_02] => {
    "inventory_hostname": "test_02"
}
ok: [test_03] => {
    "inventory_hostname": "test_03"
}

PLAY RECAP **********************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0   
test_01                    : ok=2    changed=0    unreachable=0    failed=0   
test_02                    : ok=2    changed=0    unreachable=0    failed=0   
test_03                    : ok=2    changed=0    unreachable=0    failed=0

推荐阅读