在注册变量command_result
下,从数据库获取的记录可能是多行的。
以下内容可帮助我遍历command_result
变量中数据库的每个记录。
- debug:
msg: "This is a database line: {{ item }}"
with_items: "{{ command_result.stdout_lines }}"
我现在需要的是为每次循环迭代以及相应的{{ item }}
触发如下所示的新游戏。
- hosts: "{{ item.stdout.split('\t')[0] }}"
tasks:
- name: Check if reboot is required
shell: /home/ansible/scripts/check.sh "{{ item.stdout.split('\t')[1] }}"
register: output
- debug: var=output.stdout_lines
- add_host: name={{ item }}
groups=dest_nodes
ansible_user={{ USER }}
with_items: "{{ dest_ip.split(',') }}"
项目值将在每个循环中更改,并将被馈送到上方的播放中。
因此,总结:如果数据库在{{ command_result.stdout_lines }}
中返回三个记录,则应分别在{{ item }}
中用每个记录的详细信息调用三次shell模块播放。
例如:
数据库可以返回任意数量的行,并考虑返回三行类型:<listofhosts>\t<somearguments>
:
host5,host8\targ1
host6,host2\targ3
host9,host3,host4\targ4
我需要的是,循环with_items: {{ command_result.stdout_lines }}
将运行3次,并且每次运行都将为该次运行及其各自的参数构建主机列表的动态主机组。
所以:
host5,host8
,并且外壳程序应为arg1
host6,host2
,shell将获得arg3
希望这使我的要求得到理解。
我正在使用最新版本的Ansible。
答案 0 :(得分:1)
通过模块add_host
,您应该能够通过创建动态主机组来运行此类任务。
此外,为了满足每行必须有多个主机的要求,我们首先借助模块set_fact
重新创建一个清理列表。
然后,对于新创建的列表,我们可以使用循环with_subelements
,以创建正确的元组(check_arg, host)
。
这里是一个示例,其中我在剧本的dynamic_hosts
变量中伪造了您的数据库输出:
---
- hosts: 127.0.0.1
gather_facts: false
connection: local
vars:
dynamic_hosts:
- "host5,host8\targ1"
- "host6,host2\targ3"
- "host9,host3,host4\targ4"
tasks:
- debug:
msg: "{{ dynamic_hosts }}"
- name: Make a clean list out of the hosts and arguments
set_fact:
hosts: "{{ hosts | default([]) + [ {'hosts': item.split('\t')[0].split(','), 'check_arg': item.split('\t')[1]} ] }}"
with_items: "{{ dynamic_hosts }}"
- debug:
msg: "{{ hosts }}"
- name: Adding hosts to a dynamic group based on the faked database output stored in hosts
add_host:
name: "{{ item.1 }}"
check_arg: "{{ item.0.check_arg }}"
ansible_host: 127.0.0.1
ansible_connection: local
groups: nodes_to_run_on
with_subelements:
- "{{ hosts }}"
- hosts
- hosts: nodes_to_run_on
gather_facts: false
tasks:
- debug:
msg: "Run the shell with the argument `{{ check_arg }}` here"
如您所见,我将在剧本的第一部分中借助nodes_to_run_on
创建一个名为add_host
的主机组。稍后,我将使用该主机组在该组中的所有主机上运行一组新任务。
这将是此剧本的输出:
PLAY [127.0.0.1] **********************************************************************************************************************************
TASK [debug] **************************************************************************************************************************************
ok: [127.0.0.1] => {
"msg": [
"host5,host8\targ1",
"host6,host2\targ3",
"host9,host3,host4\targ4"
]
}
TASK [Make a clean list out of the hosts and arguments] ******************************************************************************************
ok: [127.0.0.1] => (item=host5,host8 arg1)
ok: [127.0.0.1] => (item=host6,host2 arg3)
ok: [127.0.0.1] => (item=host9,host3,host4 arg4)
TASK [debug] **************************************************************************************************************************************
ok: [127.0.0.1] => {
"msg": [
{
"check_arg": "arg1",
"hosts": [
"host5",
"host8"
]
},
{
"check_arg": "arg3",
"hosts": [
"host6",
"host2"
]
},
{
"check_arg": "arg4",
"hosts": [
"host9",
"host3",
"host4"
]
}
]
}
TASK [Adding hosts to a dynamic group based on the faked database output stored in hosts] *********************************************************
changed: [127.0.0.1] => (item=[{'check_arg': 'arg1'}, 'host5'])
changed: [127.0.0.1] => (item=[{'check_arg': 'arg1'}, 'host8'])
changed: [127.0.0.1] => (item=[{'check_arg': 'arg3'}, 'host6'])
changed: [127.0.0.1] => (item=[{'check_arg': 'arg3'}, 'host2'])
changed: [127.0.0.1] => (item=[{'check_arg': 'arg4'}, 'host9'])
changed: [127.0.0.1] => (item=[{'check_arg': 'arg4'}, 'host3'])
changed: [127.0.0.1] => (item=[{'check_arg': 'arg4'}, 'host4'])
PLAY [nodes_to_run_on] ****************************************************************************************************************************
TASK [debug] **************************************************************************************************************************************
ok: [host5] => {
"msg": "Run the shell with the argument `arg1` here"
}
ok: [host8] => {
"msg": "Run the shell with the argument `arg1` here"
}
ok: [host6] => {
"msg": "Run the shell with the argument `arg3` here"
}
ok: [host2] => {
"msg": "Run the shell with the argument `arg3` here"
}
ok: [host9] => {
"msg": "Run the shell with the argument `arg4` here"
}
ok: [host3] => {
"msg": "Run the shell with the argument `arg4` here"
}
ok: [host4] => {
"msg": "Run the shell with the argument `arg4` here"
}
PLAY RECAP ****************************************************************************************************************************************
127.0.0.1 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host2 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host3 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host4 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host5 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host6 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host8 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host9 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
请注意:,这并不是我们在此处创建的主机的真正DRY列表,但是它使解决方案幼稚,并且更加实现了KISS的原则。 / p>
我们最终在此处生成的清单如下所示:
## kiss.yml ## lots of repetition
nodes_to_run_on:
hosts:
host5:
check_arg: arg1
ansible_host: 127.0.0.1
ansible_connection: local
host8:
check_arg: arg1
ansible_host: 127.0.0.1
ansible_connection: local
host6:
check_arg: arg3
ansible_host: 127.0.0.1
ansible_connection: local
host2:
check_arg: arg3
ansible_host: 127.0.0.1
ansible_connection: local
host9:
check_arg: arg4
ansible_host: 127.0.0.1
ansible_connection: local
host3:
check_arg: arg4
ansible_host: 127.0.0.1
ansible_connection: local
host4:
check_arg: arg4
ansible_host: 127.0.0.1
ansible_connection: local
什么时候肯定可以变干到
## dry.yaml ## no repetition with the help of group variables
nodes_to_run_on:
vars:
ansible_host: 127.0.0.1
ansible_connection: local
children:
with_arg1:
hosts:
host5:
host8:
vars:
check_arg: arg1
with_arg3:
hosts:
host6:
host2:
vars:
check_arg: arg3
with_arg4:
hosts:
host9:
host3:
host4:
vars:
check_arg: arg4
考虑一下这出戏中的那两个:
---
- hosts: nodes_to_run_on
gather_facts: false
tasks:
- debug:
msg: "Run the shell with the argument `{{ check_arg }}` here"
使用kiss.yml
$ ansible-playbook example.yml --inventory=kiss.yml
PLAY [nodes_to_run_on] ****************************************************************************************************************************
TASK [debug] **************************************************************************************************************************************
ok: [host5] => {
"msg": "Run the shell with the argument `arg1` here"
}
ok: [host8] => {
"msg": "Run the shell with the argument `arg1` here"
}
ok: [host6] => {
"msg": "Run the shell with the argument `arg3` here"
}
ok: [host2] => {
"msg": "Run the shell with the argument `arg3` here"
}
ok: [host9] => {
"msg": "Run the shell with the argument `arg4` here"
}
ok: [host3] => {
"msg": "Run the shell with the argument `arg4` here"
}
ok: [host4] => {
"msg": "Run the shell with the argument `arg4` here"
}
PLAY RECAP ****************************************************************************************************************************************
host2 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host3 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host4 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host5 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host6 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host8 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host9 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
使用dry.yml
$ ansible-playbook example.yml --inventory=dry.yml
PLAY [nodes_to_run_on] ****************************************************************************************************************************
TASK [debug] **************************************************************************************************************************************
ok: [host5] => {
"msg": "Run the shell with the argument `arg1` here"
}
ok: [host8] => {
"msg": "Run the shell with the argument `arg1` here"
}
ok: [host6] => {
"msg": "Run the shell with the argument `arg3` here"
}
ok: [host2] => {
"msg": "Run the shell with the argument `arg3` here"
}
ok: [host9] => {
"msg": "Run the shell with the argument `arg4` here"
}
ok: [host3] => {
"msg": "Run the shell with the argument `arg4` here"
}
ok: [host4] => {
"msg": "Run the shell with the argument `arg4` here"
}
PLAY RECAP ****************************************************************************************************************************************
host2 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host3 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host4 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host5 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host6 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host8 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host9 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
因此,您可以看到,dry.yml
库存为30行时,我们使用24行的库存kiss.yml
实现了同样的效果。
但是,无论来源是哪种方式,都来自将生成主机列表的数据库,最终创建DRY发明家的努力并不会真正付出代价。