Ansible动态选择主机组
我的清单文件如下所示Ansible动态选择主机组,ansible,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-gro
[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: ?????????
在第二个任务中,我希望类似于if result==yes在host-group-1上执行任务,if result==no在host-group-2上执行任务
请在此帮助我。下面的示例演示如何在剧本中使用Jinja。大多数人只使用Jinja表达式
{{…}}
。但是如果您需要执行更复杂的任务,也可以使用Jinja语句{%…%}
。但是语句没有返回值。因此,如果要将值返回到set\u 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
运行剧本,它将使用第一组。已跳过调试操作,因为我尚未指定清单文件
$ 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代码中的任何错误,必须使用
忽略该错误ignore\u errors:true
- 每个shell脚本都被视为更改,因为Ansible不了解shell代码的作用。因为它可能会改变某些东西,Ansible总是把它当作一种改变。如果您只是在本地主机上收集信息,这一点都没有变化。因此,有必要告诉Ansible,当:false时,
changed\u代码不会改变任何内容
hostvars
。Ansible实际上没有任何作用域,这使得嵌套循环具有挑战性(但这是另一个主题)。所有任务的结果都存储在这个全局monster哈希变量中,主机名作为密钥。无论您在localhost
上运行什么,都存储在hostvars.localhost
中。每个主机都可以完全访问其他主机的数据。这使得可以在localhost中收集信息,以便稍后在其他主机上的任务中使用
顺便说一句,我不知道你为什么会得到这么多的反对票。我认为这不是一个简单的问题。下面的示例演示了如何在剧本中使用Jinja。大多数人只使用Jinja表达式
{{…}}
。但是如果您需要执行更复杂的任务,也可以使用Jinja语句{%…%}
。但是语句没有返回值。因此,如果要将值返回到set\u 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
运行剧本,它将使用第一组。已跳过调试操作,因为我尚未指定清单文件
$ 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代码中的任何错误,必须使用
忽略该错误ignore\u errors:true
- 每个shell脚本都被视为更改,因为Ansible不了解shell代码的作用。因为它可能会改变某些东西,Ansible总是把它当作一种改变。如果您只是在本地主机上收集信息,这一点都没有变化。因此,有必要告诉Ansible,当:false时,
changed\u代码不会改变任何内容
hostvars
。Ansible实际上没有任何作用域,这使得嵌套循环具有挑战性(但这是另一个主题)。所有任务的结果都存储在这个全局monster哈希变量中,主机名作为密钥。无论您在localhost
上运行什么,都存储在hostvars.localhost
中。每个主机都可以完全访问其他主机的数据。这使得可以在localhost中收集信息,以便稍后在其他主机上的任务中使用
顺便说一句,我不知道你为什么会得到这么多的反对票。我认为这不是一个无关紧要的问题。你能澄清一下你的例子吗?不能将主机(或主机组)应用于任务,只能应用于播放。也就是说,
host
不是任务上的有效键(就此而言,task
)。如果你能更具体地描述你要做的事情,那也会有帮助,因为可能有一个解决方案不是你所描述的。@larsks要求很简单,我想根据脚本返回的参数来选择主机组。这并不“简单”,你的例子也不清楚。如果您可以使用有效的anisble语法显示您希望的行为,那么提供答案就更容易了。您是否只是尝试了-hosts:{{hostvars['127.0.0.1'].result.stdout='yes'| trialum('host-group-1','host-group-2')}}?(我同意你的例子真的很糟糕,但是没有有效的ansible代码)你能澄清一下你的例子吗?不能将主机(或主机组)应用于任务,只能应用于播放。也就是说,host
不是任务上的有效键(就此而言,task
)。如果你能更具体地描述你要做的事情,那也会有帮助,因为可能有一个解决方案不是你所描述的。@larsks要求很简单,我想根据脚本返回的参数来选择主机组。这并不“简单”,你的例子也不清楚。如果您可以使用有效的anisble语法显示您想要的行为,那么提供答案就更容易了。您是否只是尝试了-hosts