iterar um hash em uma tarefa ansible

Isso não é mais necessário porque o with_dictiterador está disponível no núcleo ansible desde então version 1.5.

Eu estava preso no problema de iterar um hash em uma tarefa.

Vars:

var:
item1
:
name
: one
value: 1
item2
:
name
: two
value: 2

Taks:

name: my loop
action
: shell echo ${item.name}
with_items
: $var

O exemplo acima irá gerar um erro

with_items expects a list

Agora, a solução óbvia para isso pode ser reescrever o vars como

var: 
- name: one
value: 1
- name: two
value: 2

No entanto, há um caso de uso principal que encontrei que não pode ser satisfeito por uma lista de hashes. É quando eu quero que o mesmo varseja adicionado por funções diferentes.

Por padrão, o ansible usa a replaceestratégia ao combinar definições de variáveis. No entanto, se a variável ansible hash_behaviourfor definida para mergeo estado final da variável, o estado é criado pela fusão recursiva de todos os hashes.

Voltando ao tópico em questão, a iteração sobre o hash pode ser obtida criando um filtro jinja2 personalizado.

Primeiro crie uma estrutura semelhante a

custom
└── filter_plugins
├── __init__.py
└── hash.py

em seu repositório ansible.

Adicione o seguinte snippet a hash.py

def hash_to_tuples(h):
return h.items()

def hash_keys(h):
return h.keys()

def hash_values(h):
return h.values()

class FilterModule(object):
''' utility filters for operating on hashes '''

def filters(self):
return {
'hash_to_tuples' : hash_to_tuples
,'hash_keys' : hash_keys
,'hash_values' : hash_values
}

Em seguida, adicione ao seu arquivo.filter_plugins=./custom/filter_pluginsansible.cfg

Por fim, atualize sua tarefa para parecer

name: my loop
action
: shell echo ${item[1].name}
with_items
: "{{var|hash_to_tuples}}"