преобразовать значения хэша yaml в ключи хэша json в Ansible - PullRequest
0 голосов
/ 12 апреля 2019

Я пытаюсь заставить 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 .

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

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

---
- 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,"
}
0 голосов
/ 13 апреля 2019

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

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

- 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
...