ansible:如何将两个远程主机相互关联,并在它们之间共享主机变量
ansible: how to associate two remote hosts with eachother, and share hostvars between them
背景资料:
我需要在一组主机 (web1) 上动态设置一个变量,然后在另一组主机上检查相同的变量。一旦它们匹配,我就可以执行进一步的操作。
代码
我的主机文件如下所示:
[web1]
web1.ttv.mydomain.com
[web1:vars]
primary_count=0
[web2]
web2.ttv.mydomain.com
[web2:vars]
secondary_count=0
[web]
web1
web2
这是剧本:
- hosts: web1
tasks:
- name: query primary servers
shell: psql -U widget widget -c 'SELECT COUNT(*) FROM test' -t
register: result
- set_fact: primary_count={{result.stdout}}
- hosts: web
tasks:
- name: retrieve variable from previous play
shell: echo hello
- debug: var=primary_count
此剧本产生以下结果:
TASK [setup] *******************************************************************
ok: [web1.ttv.mydomain.com]
TASK [query primary servers] ****************************************************
changed: [web1.ttv.mydomain.com]
TASK [debug] *******************************************************************
ok: [web1.ttv.mydomain.com] => {
"primary_count": 0
}
TASK [set_fact] ****************************************************************
ok: [web1.ttv.mydomain.com]
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [web1.ttv.mydomain.com]
ok: [web2.ttv.mydomain.com]
TASK [retrieve variable from previous play] ************************************
changed: [web1.ttv.mydomain.com]
changed: [web2.ttv.mydomain.com]
TASK [debug] *******************************************************************
ok: [web2.ttv.mydomain.com] => {
"primary_count": "VARIABLE IS NOT DEFINED!"
}
ok: [web1.ttv.mydomain.com] => {
"primary_count": " 2"
}
问题
现在我需要一种方法来在第二个游戏中执行以下操作:
- 运行 web2.ttv.mydomain.com
上的相同 select 语句
- 将值保存到secondary_count变量
- 检查 secondary_count 是否与 web1.mydomain.com 上的 "primary_count" 的值匹配。 (请注意现在,因为我在播放 2 中循环遍历的不仅仅是 web1 服务器,所以我收到有关 "primary_count" 未在 web2 服务器上定义的错误。)
- 当值匹配时,然后在辅助设备上重新启动各种服务
问题:
如何使用匹配的 web2 主机名计算 web1 主机上的 "primary_count" 变量?将来我的主机文件将如下所示:
[web1]
web1.ttv.mydomain.com
web1.ttx.mydomain.com
[web2]
web2.ttv.mydomain.com
web2.ttx.mydomain.com
[web]
web1
web2
所以我需要编写某种 eval 语句来执行此操作:
(伪代码)
while looping through ***ALL*** web servers
if primary_count on web1.ttv.mydomain.com matches secondary_count on web2.ttx.mydomain.com then
restart service x on web2.ttx.mydomain.com
else
wait a few seconds and repeat
end
end loop
我认为解决方案在于我的主机/库存文件。不知何故,我需要这个剧本在所有 web1 服务器和所有 web2 服务器上 运行...但我还需要一种方法将 web1.ttv 与 web2.ttv 和 web1.ttx 仅关联web2.ttx 等等。
我只是在学习 ansible,所以如果这种方法完全错误,请告诉我!
谢谢。
编辑 1
在对 group_vars 进行一些研究时,看起来 group_vars 并没有真正帮助我,因为我仍然遇到同样的问题。在遍历所有 Web 服务器(播放 2)时,我在播放 1 中在 web1 服务器上设置的变量在 web2 服务器上不可见。
编辑 2:
- hosts: web1
tasks:
- name: query primary servers
shell: psql -U widget widget -c 'SELECT COUNT(*) FROM widget' -t
register: result
- local_action: shell echo {{ result.stdout }} > varacrossplay.txt
在 local_action 行失败并出现此错误:
致命:[web1.ttv.mydomain.com -> localhost]:失败! => {"changed": true, "cmd": "echo 2 > varacrossplay.txt", "delta": "0:00:00.001641", "end":
": "echo 2 > varacrossplay.txt", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": 真}, "mod
1: 无法创建 varacrossplay.txt: 权限被拒绝", "stdout": "", "stdout_lines": [], "warnings": []}
尝试使用此示例剧本:
[jenkins@batman ansible]$ cat testplaybook.yml
- hosts: web1
tasks:
- name: query primary servers
shell: echo "TEST"
register: result
- local_action: shell echo {{ result.stdout }} > varacrossplay.txt
- hosts: web
tasks:
- local_action: shell cat varacrossplay.txt
register: result
- set_fact: other_fact="{{ result.stdout }}"
- debug: var=other_fact
我的服务器一切正常 xD
[jenkins@batman ansible]$ ansible-playbook -i inventory testplaybook.yml
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [10.0.0.100]
TASK [query primary servers] ***************************************************
changed: [10.0.0.100]
TASK [command] *****************************************************************
changed: [10.0.0.100 -> localhost]
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [10.0.0.2]
ok: [10.0.0.1]
TASK [command] *****************************************************************
changed: [10.0.0.1 -> localhost]
changed: [10.0.0.2 -> localhost]
TASK [set_fact] ****************************************************************
ok: [10.0.0.1]
ok: [10.0.0.2]
TASK [debug] *******************************************************************
ok: [10.0.0.2] => {
"other_fact": "TEST"
}
ok: [10.0.0.1] => {
"other_fact": "TEST"
}
PLAY RECAP *********************************************************************
10.0.0.100 : ok=3 changed=2 unreachable=0 failed=0
10.0.0.1 : ok=4 changed=1 unreachable=0 failed=0
10.0.0.2 : ok=4 changed=1 unreachable=0 failed=0
背景资料:
我需要在一组主机 (web1) 上动态设置一个变量,然后在另一组主机上检查相同的变量。一旦它们匹配,我就可以执行进一步的操作。
代码
我的主机文件如下所示:
[web1]
web1.ttv.mydomain.com
[web1:vars]
primary_count=0
[web2]
web2.ttv.mydomain.com
[web2:vars]
secondary_count=0
[web]
web1
web2
这是剧本:
- hosts: web1
tasks:
- name: query primary servers
shell: psql -U widget widget -c 'SELECT COUNT(*) FROM test' -t
register: result
- set_fact: primary_count={{result.stdout}}
- hosts: web
tasks:
- name: retrieve variable from previous play
shell: echo hello
- debug: var=primary_count
此剧本产生以下结果:
TASK [setup] *******************************************************************
ok: [web1.ttv.mydomain.com]
TASK [query primary servers] ****************************************************
changed: [web1.ttv.mydomain.com]
TASK [debug] *******************************************************************
ok: [web1.ttv.mydomain.com] => {
"primary_count": 0
}
TASK [set_fact] ****************************************************************
ok: [web1.ttv.mydomain.com]
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [web1.ttv.mydomain.com]
ok: [web2.ttv.mydomain.com]
TASK [retrieve variable from previous play] ************************************
changed: [web1.ttv.mydomain.com]
changed: [web2.ttv.mydomain.com]
TASK [debug] *******************************************************************
ok: [web2.ttv.mydomain.com] => {
"primary_count": "VARIABLE IS NOT DEFINED!"
}
ok: [web1.ttv.mydomain.com] => {
"primary_count": " 2"
}
问题
现在我需要一种方法来在第二个游戏中执行以下操作:
- 运行 web2.ttv.mydomain.com 上的相同 select 语句
- 将值保存到secondary_count变量
- 检查 secondary_count 是否与 web1.mydomain.com 上的 "primary_count" 的值匹配。 (请注意现在,因为我在播放 2 中循环遍历的不仅仅是 web1 服务器,所以我收到有关 "primary_count" 未在 web2 服务器上定义的错误。)
- 当值匹配时,然后在辅助设备上重新启动各种服务
问题:
如何使用匹配的 web2 主机名计算 web1 主机上的 "primary_count" 变量?将来我的主机文件将如下所示:
[web1]
web1.ttv.mydomain.com
web1.ttx.mydomain.com
[web2]
web2.ttv.mydomain.com
web2.ttx.mydomain.com
[web]
web1
web2
所以我需要编写某种 eval 语句来执行此操作: (伪代码)
while looping through ***ALL*** web servers
if primary_count on web1.ttv.mydomain.com matches secondary_count on web2.ttx.mydomain.com then
restart service x on web2.ttx.mydomain.com
else
wait a few seconds and repeat
end
end loop
我认为解决方案在于我的主机/库存文件。不知何故,我需要这个剧本在所有 web1 服务器和所有 web2 服务器上 运行...但我还需要一种方法将 web1.ttv 与 web2.ttv 和 web1.ttx 仅关联web2.ttx 等等。
我只是在学习 ansible,所以如果这种方法完全错误,请告诉我!
谢谢。
编辑 1
在对 group_vars 进行一些研究时,看起来 group_vars 并没有真正帮助我,因为我仍然遇到同样的问题。在遍历所有 Web 服务器(播放 2)时,我在播放 1 中在 web1 服务器上设置的变量在 web2 服务器上不可见。
编辑 2:
- hosts: web1
tasks:
- name: query primary servers
shell: psql -U widget widget -c 'SELECT COUNT(*) FROM widget' -t
register: result
- local_action: shell echo {{ result.stdout }} > varacrossplay.txt
在 local_action 行失败并出现此错误:
致命:[web1.ttv.mydomain.com -> localhost]:失败! => {"changed": true, "cmd": "echo 2 > varacrossplay.txt", "delta": "0:00:00.001641", "end": ": "echo 2 > varacrossplay.txt", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": 真}, "mod 1: 无法创建 varacrossplay.txt: 权限被拒绝", "stdout": "", "stdout_lines": [], "warnings": []}
尝试使用此示例剧本:
[jenkins@batman ansible]$ cat testplaybook.yml
- hosts: web1
tasks:
- name: query primary servers
shell: echo "TEST"
register: result
- local_action: shell echo {{ result.stdout }} > varacrossplay.txt
- hosts: web
tasks:
- local_action: shell cat varacrossplay.txt
register: result
- set_fact: other_fact="{{ result.stdout }}"
- debug: var=other_fact
我的服务器一切正常 xD
[jenkins@batman ansible]$ ansible-playbook -i inventory testplaybook.yml
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [10.0.0.100]
TASK [query primary servers] ***************************************************
changed: [10.0.0.100]
TASK [command] *****************************************************************
changed: [10.0.0.100 -> localhost]
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [10.0.0.2]
ok: [10.0.0.1]
TASK [command] *****************************************************************
changed: [10.0.0.1 -> localhost]
changed: [10.0.0.2 -> localhost]
TASK [set_fact] ****************************************************************
ok: [10.0.0.1]
ok: [10.0.0.2]
TASK [debug] *******************************************************************
ok: [10.0.0.2] => {
"other_fact": "TEST"
}
ok: [10.0.0.1] => {
"other_fact": "TEST"
}
PLAY RECAP *********************************************************************
10.0.0.100 : ok=3 changed=2 unreachable=0 failed=0
10.0.0.1 : ok=4 changed=1 unreachable=0 failed=0
10.0.0.2 : ok=4 changed=1 unreachable=0 failed=0