Ansible动态选择主机组

时间:2017-09-08 12:22:22

标签: ansible

我的库存文件如下所示。

[host-group-1]
 x.x.x.1
 x.x.x.2

[host-group-2]
 x.x.x.3
 x.x.x.4

现在我想根据脚本返回的参数选择并执行这些组的任务。 该剧本如下所示。

---
- host: 127.0.0.1
  tasks:
  - name: something 
    local_action: /home/script.py
    register: result

 - host: host-group-1:host-group-2
   task: ?????????

这里的第二个任务我想要的东西,如果result == yes执行host-group-1上的任务,如果result == no执行任务host-group-2

请在这里帮助我。

1 个答案:

答案 0 :(得分:1)

以下示例显示如何在剧本中使用Jinja。大多数人只使用Jinja表达式{{ ... }}。但是,如果您需要执行更复杂的任务,也可以使用Jinja语句{% ... %}。但声明没有回报价值。因此,如果要将值返回到set_fact任务,则必须以表达式结束。

---
- name: Get group
  hosts: localhost
  connection: local
  tasks:
    - shell: |-
        echo {{ say }}
      register: group
      ignore_errors: true
      changed_when: false
    - set_fact:
        group: >-
          {% if group.stdout == "yes"     -%}
          {%   set group = "host-group-1" -%}
          {% elif group.stdout == "no"    -%}
          {%   set group = "host-group-2" -%}
          {% else                         -%}
          {%   set group = ""             -%}
          {% endif                        -%}
          {{ group }}

- hosts: "{{ hostvars.localhost.group }}"
  tasks:
    - debug: var=group

如果您使用yes运行Playbook,则会使用第一组。跳过调试操作,因为我没有指定库存文件。

$ ansible-playbook if.yml --extra-vars say=yes

PLAY [Get group] *****************************************************************************

TASK [command] *******************************************************************************
ok: [localhost]

TASK [set_fact] ******************************************************************************
ok: [localhost]

PLAY [host-group-1] **************************************************************************
skipping: no hosts matched

PLAY RECAP ***********************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

如果您使用no运行它,则使用第二组。

$ ansible-playbook if.yml --extra-vars say=no

PLAY [Get group] *****************************************************************************

TASK [command] *******************************************************************************
ok: [localhost]

TASK [set_fact] ******************************************************************************
ok: [localhost]

PLAY [host-group-2] **************************************************************************
skipping: no hosts matched

PLAY RECAP ***********************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

有关shell脚本的一些提示:

  • 每当shell脚本的返回值不为零时,Ansible会将此视为错误。这打破了你的Ansible运行。如果您要处理Ansible代码中的任何错误,则必须使用ignore_errors: true忽略错误。

  • 每个shell脚本都被视为更改,因为Ansible不了解shell代码的作用。而且因为它可能会改变某些东西,Ansible总是将其视为一种变化。如果您只是在本地主机上收集信息,则根本不会有任何变化。所以有必要告诉Ansible代码不会改变changed_when: false的任何内容。

提示Ansible如何存储信息:

Ansible的内部数据结构是一个混乱的全局变量,称为hostvars。 Ansible几乎没有任何范围,这使得嵌套循环具有挑战性(但这是另一个主题)。任务的所有结果都存储在这个单一的全局怪物哈希变量中,主机名称作为键。您在localhost上运行的任何内容都存储在hostvars.localhost中。每个主机都可以完全访问其他主机的数据。这使得可以在localhost中收集信息,以便稍后在其他主机上工作的任务中使用它。

顺便说一句。我不知道,为什么你有这么多的选票。我认为这不是一个微不足道的问题。