我有一个site.yml剧本,当我使用这个配置时:
- hosts: target
tags:
- setup_target
tasks:
- name: See some data
debug: msg={{ hostvars[inventory_hostname][ansible_lsb].codename }}
可靠地向我报告一个错误:
PLAY [target] *****************************************************************
GATHERING FACTS ***************************************************************
ok: [target]
TASK: [See some data] *********************************************************
fatal: [target] => One or more undefined variables: dict object has no element {u'release': u'14.04', u'major_release': u'14', u'codename': u'trusty', u'id': u'Ubuntu', u'description': u'Ubuntu 14.04.1 LTS'}
FATAL: all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
to retry, use: --limit @/home/robe/site.retry
target : ok=1 changed=0 unreachable=1 failed=0
但如果我使用点样式,比如:
---
# The main playbook to deploy
# setup our database
- hosts: target
tags:
- setup_target
tasks:
- name: See some data
debug: msg={{ hostvars[inventory_hostname].ansible_lsb.codename }}
输出正常:
PLAY [target] *****************************************************************
GATHERING FACTS ***************************************************************
ok: [target]
TASK: [See some data] *********************************************************
ok: [target] => {
"msg": "trusty"
}
PLAY RECAP ********************************************************************
target : ok=2 changed=0 unreachable=0 failed=0
那么,有什么不同呢?对我来说,两者是平等的?
那么,有什么不同呢?对我来说,两者是平等的?
这归结为dicts/hashes在Python中的工作方式,以及它们在jinja2和Ansible中的工作情况。
如果您有一个名为data
的dict,并且您想要foo
元素的值,您可以这样访问它:
data["foo"]
如果省略引号,则需要一个名为foo的变量。
data[foo] # does not work (so far)
jinja2还允许您使用点样式:
data.foo
让我们假设"foo"元素的值是数字42。这些都是真的:
data["foo"] = 42
data[foo] # does not work
data.foo = 42
现在,如果您有一个名为foo的变量,该怎么办?在下面的例子中,我们将考虑键"foo"的值仍然是42,而"bar"将是13。
foo = "bar"
data["foo"] = 42
data[bar] = 13
data.foo = 42
要将其转换为原始情况,请记住inventory_hostname
和ansible_lsb
都是变量,而不是字符串。更令人困惑的是,ansible_lsb是一本字典。这意味着你原来的括号样式扩展如下:
hostvars["inventory_hostname"][{u'release': u'14.04', u'major_release': u'14', u'codename': u'trusty', u'id': u'Ubuntu', u'description': u'Ubuntu 14.04.1 LTS'}]["codename"]
哎呀。作为dict的关键的dict进入了递归的同类相食龟。
以下是你的"点状"风格。
hostvars["inventory_hostname"]["ansible_lsb"]["codename"]
这个也可以稍微翻译一下,让它稍微清晰一点:
lsb = hostvars["inventory_hostname"]["ansible_lsb"]
lsb["codename"]
这显然是你想要的。