我正在尝试让 Ansible 将哈希数组转换为键值对列表,键是第一个哈希的值之一,值是与第一个哈希不同的值。
一个例子会有所帮助。
我想转换:-
TASK [k8s_cluster : Cluster create | debug result of private ec2_vpc_subnet_facts] ***
ok: [localhost] => {
"result": {
"subnets": [
{
"availability_zone": "eu-west-1c",
"subnet_id": "subnet-cccccccc",
},
{
"availability_zone": "eu-west-1a",
"subnet_id": "subnet-aaaaaaaa",
},
{
"availability_zone": "eu-west-1b",
"subnet_id": "subnet-bbbbbbbb",
}
]
}
}
到
eu-west-1a: subnet-aaaaaaaa
eu-west-1b: subnet-bbbbbbbb
eu-west-1c: subnet-cccccccc
我已经尝试了result.subnets | map('subnet.availability_zone': 'subnets.subnet_id')
(根本不起作用(和json_query('subnets[*].subnet_id'
它只是挑选出subnet_id值并将它们放入列表中。
我想我可以在Ruby中使用Zip和Hash来做到这一点,但我不知道如何在Ansible中做到这一点,或者更具体地说是在Jmespath中。
我已经生成了下面的列表,我将在生成的列表中添加一个新行(想先分享这个(
---
- name: play
hosts: localhost
tasks:
- name: play
include_vars: vars.yml
- name: debug
debug:
msg: "{% for each in subnets %}{{ each.availability_zone }}:{{ each.subnet_id }}{% raw %},{% endraw %}{% endfor %}"
输出--->
ok: [localhost] => {
"msg": "eu-west-1c:subnet-cccccccc,eu-west-1a:subnet-aaaaaaaa,eu-west-1b:subnet-bbbbbbbb,"
}
Jmespath不允许在多选哈希中使用动态名称。我找到了 jmespath 的扩展,允许通过使用键引用来做这样的事情,但它不是普通 jmespath 实现的一部分,也不是 ansible。
要在普通 ansible 中执行此操作,您必须创建一个新变量并用循环填充它。可能还有其他方法使用其他过滤器,但这是我提出的解决方案:
- name: Create the expected hash
set_fact:
my_hash: >-
{{
my_hash
| default({})
| combine({ item.availability_zone: item.subnet_id })
}}
loop: "{{ subnets }}"
- name: Print result
debug:
var: my_hash