[英]Extract nested dict value with conditions from JSON using JINJA2 in Ansible
I'm trying to extract the CDN domain name for a specific Alias from Ansible's cloudfront_facts
, with the following (summarized) output: 我正在尝试从Ansible的cloudfront_facts
提取特定别名的CDN域名,并提供以下(摘要)输出:
{
"cdn_facts": {
"ansible_facts": {
"cloudfront": {
"summary": {
"distributions": [
{
"Aliases": [
"media.example.com"
],
"DomainName": "a1b2c3d4e5f6g.cloudfront.net"
},
{
"Aliases": [
"example.com"
],
"DomainName": "g7f6e5d4c3b2a.cloudfront.net"
}
]
}
}
}
}
In other words, for the Alias example.com
I'd like to set a fact with the value of g7f6e5d4c3b2a.cloudfront.net
. 换句话说,对于Alias example.com
我想设置一个值为g7f6e5d4c3b2a.cloudfront.net
的事实。
I've tried the following to try and print out the value, but it's simply producing an empty list. 我已经尝试了以下方法来尝试打印出该值,但它只是产生一个空列表。
- debug:
msg: "{{ cdn_facts.ansible_facts.cloudfront.summary.distributions | selectattr('Aliases[0]', 'equalto', 'example.com') | map(attribute='DomainName') | list }}"
I'm at a loss on how to even debug this, as cdn_facts.ansible_facts.cloudfront.summary.distributions
produces an array of dicts, but selectattr
and map
are not producing anything. 我对如何调试它cdn_facts.ansible_facts.cloudfront.summary.distributions
,因为cdn_facts.ansible_facts.cloudfront.summary.distributions
会生成一系列selectattr
,但是selectattr
和map
不会生成任何内容。
Nothing in your data has an attribute named Aliases[0]
, so that's why your selectattr
filter is failing. 数据中没有任何属性名为selectattr
Aliases[0]
,因此这就是selectattr
过滤器失败的原因。
For extracting data from deeply nested dictionaries, the json_query
filter is often a better choice than trying to chain native Jinja filters. 为了从深度嵌套的字典中提取数据,与尝试链接本机Jinja过滤器相比, json_query
过滤器通常是更好的选择。 For example, given the alias example.com
, the following expression will extract the corresponding DomainName
attribute: 例如,给定别名example.com
,以下表达式将提取相应的DomainName
属性:
cdn_facts.ansible_facts.cloudfront.summary.distributions[?Aliases[0] == `example.com`]|[0].DomainName
We can use that in a playbook like this: 我们可以在像这样的剧本中使用它:
---
- hosts: localhost
gather_facts: false
tasks:
- include_vars:
file: data.json
name: data
- debug:
msg: >-
{{ item }} ->
{{
(data|json_query('cdn_facts.ansible_facts.cloudfront.summary.distributions[?Aliases[0] == `{}`]|[0].DomainName'.format(item)))
}}
loop:
- media.example.com
- example.com
Which will output: 将输出:
TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => (item=media.example.com) => {
"msg": "media.example.com -> a1b2c3d4e5f6g.cloudfront.net"
}
ok: [localhost] => (item=example.com) => {
"msg": "example.com -> g7f6e5d4c3b2a.cloudfront.net"
}
The json_query
modules uses the jmespath search syntax. json_query
模块使用jmespath搜索语法。 You can experiment with jmespath expressions by pasting your data into the text box at https://jmespath.org and then entering search expressions in the field above it. 您可以通过将数据粘贴到https://jmespath.org上的文本框中,然后在其上方的字段中输入搜索表达式来试验jmespath表达式。 Alternately, you can grab the jpterm command line tool. 或者,您可以获取jpterm命令行工具。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.