本文介绍了ansible:从同一个剧本中的其他剧本访问寄存器变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从第二本剧本中的第一个剧本"中访问名为"count"的变量.我在这里找到了有关同一问题的其他文章,我以为我在遵循正确的步骤,但是下面的代码仍然失败.

I'm trying to access the variable called "count" from the first "play" in my playbook in the second playbook. I found some other posts here about the same issue and I thought I was following the right steps, but the code below is still failing.

代码

- hosts: group1
  tasks:
  - name: count registrations on primary node
    shell: psql -U widgets widgets -c 'SELECT COUNT(*) FROM location' -t
    register: count
  - debug: var=count.stdout

- hosts: group2
  tasks:
#the line below works...
#  - debug: msg={{ hostvars['myserver1.mydomain.com']['count']['stdout'] }}
# but this one fails
  - debug: msg={{ hostvars['group1']['count']['stdout'] }}

这将产生以下输出:

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [myserver1.mydomain.com]

TASK [count registrations on node] **************************************
changed: [myserver1.mydomain.com]

TASK [debug] *******************************************************************
ok: [myserver1.mydomain.com] => {
    "count.stdout": "     2"
}

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [myserver2.mydomain.com]

TASK [debug] *******************************************************************
fatal: [myserver1.mydomain.com]: FAILED! => {"failed": true, "msg": "'ansible.vars.hostvars.HostVars object' has no attribute 'can_sip1'"}

NO MORE HOSTS LEFT *************************************************************
 [ERROR]: Could not create retry file 'playbooks/test.retry'. The error was: [Errno 13] Permission denied: 'playbooks/test.retry'


PLAY RECAP *********************************************************************

myserver1.mydomain.com:ok = 3更改= 1不可达= 0失败= 0
myserver2.mydomain.com:确定= 1更改== 0不可达= 0失败= 1

myserver1.mydomain.com : ok=3 changed=1 unreachable=0 failed=0
myserver2.mydomain.com : ok=1 changed=0 unreachable=0 failed=1

我所指的另一篇文章位于:如何设置注册一个变量是否可以在剧情之间持续存在?

The other post that I referring to is found here: How do I set register a variable to persist between plays in ansible?

这可能很简单,但是我看不出错误所在.谢谢.

It's probably something simple, but I can't see where the bug lies.Thanks.

编辑1

我也试图像这样使用set_fact:

I've also tried to use set_fact like this:

- hosts: group1
  tasks:                                  
  - name: count registrations on primary node        
    shell: psql -U widget widget -c 'SELECT COUNT(*) FROM location' -t
    register: result                      
  - debug: var=result.stdout              
  - set_fact: the_count=result.stdout
  - debug: var={{the_count}}              

- hosts: group2                        
  tasks:                                  
  - name: retrieve variable from previous play
    shell: echo hello                     
  - debug: var={{hostvars}}

我得到的结果是:

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [myserver1.mydomain.com]

TASK [count reg on primary] ****************************************************
changed: [myserver1.mydomain.com]

TASK [debug] *******************************************************************
ok: [myserver1.mydomain.com] => {
    "result.stdout": "     2"
}

TASK [set_fact] ****************************************************************
ok: [myserver1.mydomain.com]

TASK [debug] *******************************************************************
ok: [myserver1.mydomain.com] => {
    "result.stdout": "     2"
}

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [myserver2.mydomain.com]

TASK [retrieve variable from previous play] ************************************
changed: [myserver2.mydomain.com]

TASK [debug] *******************************************************************
ok: [myserver2.mydomain.com] => {
    "<ansible.vars.hostvars.HostVars object at 0x7f3b6602b290>": "VARIABLE IS NOT DEFINED!"
}

PLAY RECAP *********************************************************************
myserver1.mydomain.com        : ok=5    changed=1    unreachable=0    failed=0   
myserver2.mydomain.com       : ok=3    changed=1    unreachable=0    failed=0   

所以看来hostvars中没有对象...

So It looks like there are no objects in the hostvars...

编辑3

这是今早的剧本的样子.

This is what the playbook looks like this morning.

- hosts: group1
  tasks:
  - name: count reg on primary
    shell: psql -U widgets widgets -c 'SELECT COUNT(*) FROM location' -t
    register: result
  - debug: var=result.stdout
  - set_fact: the_count={{result.stdout}} 
  - debug: var={{the_count}}

- hosts: group2
  tasks:
  - name: retrieve variable from previous play
    shell: echo hello
  - debug: var={{hostvars}}    

从第一场比赛开始的"debug:var = {{the_count}}"行会打印出正确的计数值,但它也表示未定义变量...像这样:

The "debug: var={{the_count}}" line from the first play prints out the correct value for the count but it also says the VARIABLE IS NOT DEFINED... like so:

任务[set_fact] *********************************************** *********************任务路径:/etc/ansible/playbooks/test.yml:8好的:[myserver1.mydomain.com] => {"ansible_facts":{"the_count":"2"},"changed":false,"invocation":{"module_args":{"the_count":"2"} ,"module_name":"set_fact"}}

TASK [set_fact] ****************************************************************task path: /etc/ansible/playbooks/test.yml:8ok: [myserver1.mydomain.com] => {"ansible_facts": {"the_count": " 2"}, "changed": false, "invocation": {"module_args": {"the_count": " 2"}, "module_name": "set_fact"}}

任务[调试] *********************************************** ************************任务路径:/etc/ansible/playbooks/test.yml:10好的:[myserver1.mydomain.com] => { "2":变量未定义!"}

TASK [debug] *******************************************************************task path: /etc/ansible/playbooks/test.yml:10ok: [myserver1.mydomain.com] => { " 2": "VARIABLE IS NOT DEFINED!"}

然后,当我打第二场戏时,我仍然收到消息

And then once I hit the second play, I still get the message

TASK [debug] *******************************************************************
task path: /etc/ansible/playbooks/test.yml:16
ok: [myserver2.mydomain.com] => {
    "<ansible.vars.hostvars.HostVars object at 0x7fb077fdc310>": "VARIABLE IS NOT DEFINED!"
}

在您的示例中,建议您使用调试:var = {{{hostlers}}".如果您能为我澄清一下.看起来像是一个错字.

In your example, you are suggestion that I use "debug: var={{hostlers}}". If you can clarify that for me please. It looks like it's a typo.

如果仔细看一下Edit 3,您将看到我已经实现了"debug:var = {{{hostvars}}",正如您在回答中所建议的那样.但这给了我同样的错误,那就是未定义变量.我不仅在尝试将变量从一个剧本传递到另一个剧本,而是从一组主机传递到另一组主机.请注意,播放1如何使用组1,播放2如何仅适用于组2.

If you take a look at Edit 3 carefully, you will see that I have implemented "debug:var={{hostvars}}" as you suggest in your answer. But it gives me the same error that the variable is not defined.I'm not just trying to pass variables from one play to another.. but from one set of hosts to another. Notice how play 1 uses group1 and play two applies only to group2.

推荐答案

  1. 寄存器变量(如事实)是每个主机的.这些值可能会因机器而异.因此,您只能使用清单中定义的主机/IP作为键,而不能使用组名.我认为您已经知道了这一点,正如您在代码片段1中标记的那样.

  1. Register variables, like facts, are per host. The values can differ depending on the machine. So you can only use host/ip defined in the inventory as key, not the group name. I think you have already knowed this, as you marked this in code snippet 1.

在代码段2中,set_fact行(- set_fact: the_count=result.stdout)实际上将键the_count设置为文本值result.stdout,因为result.stdout被视为纯文本,而不是变量.如果要将其视为变量,则最好使用{{ result.stdout }}.您可以通过使用-v选项运行剧本来验证这一点.

In the code snippet 2, the set_fact line (- set_fact: the_count=result.stdout) actually set the key the_count to the text value result.stdout, since result.stdout is treated as plain text, not a variable. If you want to treat it as a variable, you'd better use {{ result.stdout }}. You can verify this via running the playbook with -v option.

任务:

  • set_fact:the_content1 = content.stdout
  • set_fact:the_content2 = {{content.stdout}}

输出:

TASK [set_fact] ****************************************************************
ok: [192.168.1.58] => {"ansible_facts": {"the_content1": "content.stdout"}, "changed": false}

TASK [set_fact] ****************************************************************
ok: [192.168.1.58] => {"ansible_facts": {"the_content2": "hello world"}, "changed": false}

  • debug模块具有两个可能的参数:varmsg. var参数需要一个变量名.

  • The debug module has two possible parameter: var and msg. The var parameter expect a variable name.

    • 调试:var = {{hostvars}}

    在此行中,首先,Ansible提取hostvars的值,因为它用两个括号括起来.其次,它尝试查找名称为hostvars值的变量,因为var参数直接需要一个变量名.这就是为什么您看到以下奇怪的输出的原因.这意味着Ansible找不到名称为<ansible.vars.hostvars.HostVars object at 0x7f3b6602b290>的变量.

    In this line, first of all, Ansible extracts the value of hostvars, since it is enclosed with two brackets. Secondly, it tries to find a variable whose name is the value of hostvars, since var parameter expects a variable name directly. That is why you see the following strange output. This means Ansible couldn't find a variable whose name is <ansible.vars.hostvars.HostVars object at 0x7f3b6602b290>.

    "<ansible.vars.hostvars.HostVars object at 0x7f3b6602b290>": "VARIABLE IS NOT DEFINED!"
    

    您可以使用以下内容:

    • 调试:var = hostvars
    • 调试:msg = {{hostvars}}

    参考:

    • Register variables don't survive across plays with different hosts
    • set_fact - Set host facts from a task
    • debug - Print statements during execution

    这篇关于ansible:从同一个剧本中的其他剧本访问寄存器变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 10-29 17:13