преобразовать значения хэша yaml в ключи хэша json в Ansible

Я пытаюсь заставить 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 и помещает их в список.

Я думаю, что мог бы сделать это с помощью Zip и Hash в Ruby но я не знаю, как заставить это работать в Ansible или, точнее, в Jmespath.


person Steve Button    schedule 12.04.2019    source источник


Ответы (2)


Я сгенерировал приведенный ниже список. Я добавлю новую строку в сгенерированный список (думал сначала поделиться этим)

---
- 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,"
}
person error404    schedule 12.04.2019

Jmespath не позволяет использовать динамические имена в хэшах с множественным выбором. Я нашел расширение jmespath, позволяющее делать это с помощью ссылок на ключи, но оно не является частью простой реализации jmespath и не является невозможным.

Чтобы сделать это в простом анзибле, вам нужно будет создать новую переменную и заполнить ее циклом. Могут быть и другие способы использования других фильтров, но это решение, которое я придумал:

- 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
person Zeitounator    schedule 13.04.2019