Ansible:如何将多值数据列表用作库存并传递给目标主机

时间:2017-09-01 12:53:30

标签: ansible ansible-inventory ansible-facts

我的主机库存源来自一个输出成对值的内部工具,例如,这里有六个观察点,我目前有160个观察值:

   servername1  processname1
   servername1  processname2
   servername1  processname3
   servername2  processname1
   servername3  processname1
   servername4  processname1

所以第1列是我的目标主机列表(我的库存)。 Column2是唯一的processname值,专门分配给servername的值。通常会出现相同的服务器。某些服务器只有一个进程名,其他服务器可能有2到N.这意味着我的目标主机可能会重复一个唯一的进程名列表。我想使用这个输出对列表中的动态库存,我需要将每个观察值的两个值关联起来并分配给变量。我不是绝对需要使用动态库存,我只需要一个解决方案。我还需要通过命令:或shell:modules传递给目标主机和{{processname#}}中的值。 (这是独一无二的,没有与此需求相关的模块)

如果需要,我可以过滤此数据并以JSON格式或YAML输出,为每个主机创建单独的YML文件。虽然我更愿意动态处理这些;预处理列表是可以接受的。

因为ansible-playbook需要一些已知的主机库存清单,所以当我开始播放时,我无法理解如何从动态输出创建此列表。

到目前为止我做了什么:我已经尝试过读取并尝试在/etc/ansible/hosts/host_vars/servername#.yml文件中设置这些对。这非常难看,因为我必须将数据输出预处理成YML格式。但是它并没有给我一个主持人列表来参考我的剧本。因此,虽然似乎hostvar是合乎逻辑的选择,但我无法理解它。

我需要什么:

- The suggested format of the data?  JSON? YAML? Other? (if I cannot read it in dynamically.
- Is putting this in host_vars correct?
- Last night I saw another answer using set_fact, would that help?

感谢您的任何见解。我现在已经使用Ansible 3.5周了!我使用静态和动态库存做得非常好,但是由于库存清单不明显,这给我带来了麻烦,给出匹配对的格式。

注意:许多人建议使用host_vars,但在我看来,要保留给主机名,以及相关的端口和代理值。我错了。

=============================================== ====================

更新:感谢您提供正确方向的帮助。 我已将库存脚本更新为以JSON格式输出主机列表。 第一个新选项是以JSON格式输出主机。 例: { “my_host转变”:[ “servername1”, “servername2”]}

将其称为动态库存脚本,效果很好!

ansible all -m ping servername1 | SUCCESS => {     “改变了”:错误,     “乒乓” } servername2 | SUCCESS => {     “改变了”:错误,     “乒乓” }

下一步:库存脚本的第二个新选项是添加一个新的开关来输入主机名。这部分仍然让我感到困惑。这是输出: showInv --host = servername1

{ “servername1”:[ “processname1”, “processname2”, “processname3”]}

我遗漏的最后一部分是我如何使用特定的“--host = {{my_host}}从我的剧本中调用库存脚本。

似乎我需要找到现有主机名的变量,并将其作为切换选项“--host =”

传递回库存脚本

3 个答案:

答案 0 :(得分:3)

你说你对动态库存很满意。做你自己的。

这是the docs

你需要制作一个可以做两件事的脚本:

  • 使用--list执行时,处理您的文件并将此JSON打印到stdout:

    { "myhosts": ["servername1", "servername2", "servername3"] }
    
  • 使用--host servername1执行时,将此JSON打印到stdout:

    { "myprocesses": ["processname1", "processname2"] }
    

因此,使用--list,您应该提供uniq主机列表。在我的示例中,它们属于myhosts组。

使用--host <hostname>,您应该为该主机提供主机变量的列表dict(<hostname>)。在我的示例中,有一个列表变量myprocesses,其中包含该主机的所有进程。

然后拨打ansible-playbook -i my_inv_script myplaybook.yml

示例剧本:

---
- hosts: myhosts
  tasks:
    - debug:
        msg: "Process name is {{ item }}"
      with_items: "{{ myprocesses }}"

此剧本将覆盖动态广告资源中的所有主机,并打印每个主机的所有流程。

答案 1 :(得分:2)

您需要开发一个动态库存脚本,它将第一列作为主机名,第二列作为该主机的变量。

请在下面找到我用php编写的动态库存链接 https://github.com/walden-it/ansible-ij/blob/master/inventory.php

看一下函数get_vars()和get_hosts(),看看数组是如何填充的。

如果您需要它,这是此脚本正在查看的数据库的转储: https://github.com/walden-it/ansible-ij/blob/master/ansible.sql

然后,您只需在 ansible 运行中使用-i广告资源进行指定,或将其作为inventory_file添加到ansible.cfg

答案 2 :(得分:1)

关闭它。在康斯坦丁的建议的帮助下,我现在有了一个有效的游戏。什么不是立即显而易见的是,Ansible正在做一些&#34;魔术&#34;在幕后。我不得不修改我的库存脚本,生成我的动态库存以接受&#34; - list&#34;切换选项,&#34; - 主机主机名&#34;选项。

完成此操作后,我可以使用-i listInv运行playbook,Ansible在内部将此脚本称为listInv --list,这将生成我的动态库存清单。然后循环,直到with_items,并在内部调用脚本listInv --host {{items}}并输出匹配的进程名。

此外,我的脚本生成的JSON输出必须使&#34; group&#34; (第一)字段,&#34; myprocess&#34;。最初,我把它作为&#34; my_process&#34;,这就失败了。删除下划线,修复了那个错误。

现在全部工作。这是学习的一个很好的例子,但它仍然是神奇的。

剧本如下:

- hosts: all
  gather_facts: no
  connection: local

  tasks:
    - debug:
        msg: "Process name is {{ item }}"
      with_items:  "{{ myprocess }}"