【问题标题】:Ansible nested loops through inventories通过库存的 Ansible 嵌套循环
【发布时间】:2018-11-02 22:37:35
【问题描述】:

我正在查看 Ansible https://docs.ansible.com/ansible/2.7/user_guide/playbooks_loops.html 的 Loops 页面,但找不到我要查找的内容...

我想测试“源”主机是否可以到达/连接到一组端口上的一组目标主机。例如,每组目标主机可以是一个清单组,每个清单组都有自己要测试的端口列表。

这个想法是只指定两个变量作为剧本的输入:一个主机组列表和一个或多个源主机的列表。

循环应该怎么做?清单可以是 YAML 或 INI 文件:每个组一个或多个。 TCP 连接的测试很简单……所以重点只放在输入变量和循环构造上。

感谢和问候。

史蒂夫

【问题讨论】:

    标签: ansible ansible-inventory


    【解决方案1】:

    给定以下hosts库存文件

    server1
    server2
    server3
    
    [dev]
    d1
    d2
    d3
    
    [dev:vars]
    ports=8080,8443
    
    [int]
    i1
    i2
    i3
    
    [int:vars]
    ports=80,443
    

    和下面的剧本play.yml

    ---
    - hosts: all
      gather_facts: False
      vars:
        group: 'dev'
    
      tasks:
      - name: Just loop through a group and group_vars
        debug:
          msg: 'group is {{group}} target is {{item.0}} port is {{item.1}}'
        loop: >
          {{ groups[group] |
             product(hostvars[groups[group][0]]["ports"]) |
             list }}
    

    您可以按照您的描述循环浏览您的库存

    ansible-playbook -i hosts play.yml -l server* -e group=int
    

    产生以下结果:

    PLAY [all] *********************************************************************
    
    TASK [Just loop through a group and group_vars] ********************************
    ok: [server1] => (item=[u'i1', 80]) => {
        "msg": "group is int target is i1 port is 80"
    }
    ok: [server1] => (item=[u'i1', 443]) => {
        "msg": "group is int target is i1 port is 443"
    }
    ok: [server2] => (item=[u'i1', 80]) => {
        "msg": "group is int target is i1 port is 80"
    }
    ok: [server2] => (item=[u'i1', 443]) => {
        "msg": "group is int target is i1 port is 443"
    }
    ok: [server1] => (item=[u'i2', 80]) => {
        "msg": "group is int target is i2 port is 80"
    }
    ok: [server3] => (item=[u'i1', 80]) => {
        "msg": "group is int target is i1 port is 80"
    }
    ok: [server1] => (item=[u'i2', 443]) => {
        "msg": "group is int target is i2 port is 443"
    }
    ok: [server3] => (item=[u'i1', 443]) => {
        "msg": "group is int target is i1 port is 443"
    }
    ok: [server2] => (item=[u'i2', 80]) => {
        "msg": "group is int target is i2 port is 80"
    }
    ok: [server1] => (item=[u'i3', 80]) => {
        "msg": "group is int target is i3 port is 80"
    }
    ok: [server3] => (item=[u'i2', 80]) => {
        "msg": "group is int target is i2 port is 80"
    }
    ok: [server2] => (item=[u'i2', 443]) => {
        "msg": "group is int target is i2 port is 443"
    }
    ok: [server1] => (item=[u'i3', 443]) => {
        "msg": "group is int target is i3 port is 443"
    }
    ok: [server3] => (item=[u'i2', 443]) => {
        "msg": "group is int target is i2 port is 443"
    }
    ok: [server2] => (item=[u'i3', 80]) => {
        "msg": "group is int target is i3 port is 80"
    }
    ok: [server3] => (item=[u'i3', 80]) => {
        "msg": "group is int target is i3 port is 80"
    }
    ok: [server2] => (item=[u'i3', 443]) => {
        "msg": "group is int target is i3 port is 443"
    }
    ok: [server3] => (item=[u'i3', 443]) => {
        "msg": "group is int target is i3 port is 443"
    }
    
    PLAY RECAP *********************************************************************
    server1                    : ok=1    changed=0    unreachable=0    failed=0
    server2                    : ok=1    changed=0    unreachable=0    failed=0
    server3                    : ok=1    changed=0    unreachable=0    failed=0

    例如,您只需将调试替换为wait_for module

    【讨论】:

    • 这正是我想要的,谢谢。我知道我必须使用“子元素”模式,但关键部分是hostvars[groups[group][0]]["ports"]。通过一些调整,我将能够将服务器列表与该库存分开,例如,通过使用 add_host 模块并将服务器列表作为输入参数。
    • 接受答案会很好;-)
    • 如果 var "group" 是一个列表怎么办?
    • 最好是在新问题中提出这个问题,因为这与标准循环有关。
    • 谢谢,我做到了here
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多