Ansible 动态选择主机组 [英] Ansible select host group dynamically

查看:31
本文介绍了Ansible 动态选择主机组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的库存文件如下所示.

My inventory file looks like below.

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

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

现在我想根据脚本返回的参数在这些组上选择和执行任务.剧本如下.

Now I want to select and perform tasks on these groups based on the parameter return by a script. The playbook looks below.

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

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

在第二个任务中,我想要类似 if result== yes 在 host-group-1 上执行任务,如果 result==no 在 host-group-2 上执行任务

Here on the 2nd task I want something like if result== yes perform the task on host-group-1 and if result==no perform the task host-group-2

请在这里帮助我.

推荐答案

以下示例展示了如何在 playbook 中使用 Jinja.大多数人只使用 Jinja 表达式 {{ ... }}.但是如果你需要做更复杂的任务,也可以使用Jinja语句{% ... %}.但是语句没有返回值.因此,如果您想向 set_fact 任务返回一个值,则必须以表达式结尾.

The following example shows how to use Jinja in a playbook. Most people use only Jinja expressions {{ ... }}. But if you need to do more complicate tasks, it is also possible to use Jinja statements {% ... %}. But a statement has no return value. So you have to end with an expression, if you want to return a value to the set_fact task.

---
- 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 运行剧本,它将使用第一组.调试操作被跳过,因为我没有指定清单文件.

If you run the playbook with yes it used the first group. The debug action is skipped, because I have not specified an inventory file.

$ 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 运行它,它会使用第二组.

And if you run it with no it uses the second group.

$ 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 脚本的一些提示:

Some hints about shell scripts:

  • 只要 shell 脚本的返回值不为零,Ansible 就会将其视为错误.这会破坏您的 Ansible 运行.如果您想处理 Ansible 代码中的任何错误,您必须使用 ignore_errors: true 忽略错误.

每一个shell脚本都被当成变化对待,因为Ansible不明白,shell代码是做什么的.并且因为它可能会改变某些东西,所以 Ansible 总是将其视为一种改变.如果您只是收集有关本地主机的信息,则完全没有变化.所以有必要用changed_when: false告诉Ansible代码没有改变任何东西.

Each shell script is treated as change, because Ansible has no understand, what the shell code does. And because it might change something, Ansible treats it always as a change. If you just collect information on your local host, this is no change at all. So it is necessary to tell Ansible that the code does not change anything with changed_when: false.

提示 Ansible 如何存储信息:

A hint how Ansible stores information:

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

Ansible's internal data structure is one big messy global variable, which is called hostvars. Ansible has virtually no kind of scope, which makes nested loops challenging (but this is another topic). All results of tasks are stored in this single global monster hash variable with the name of the host as a key. Whatever you run on localhost is stored in hostvars.localhost. Every host has full access to the data of each other host. This makes it possible to collect information in localhost to use it later in the task working on other hosts.

顺便说一句.我不知道,为什么你得到这么多反对票.我认为这不是一个微不足道的问题.

btw. I have no idea, why you got so many down votes. I think this is not a trivial question.

这篇关于Ansible 动态选择主机组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆