Isso não é mais necessário porque o with_dict
iterador 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 var
seja adicionado por funções diferentes.
Por padrão, o ansible usa a replace
estratégia ao combinar definições de variáveis. No entanto, se a variável ansible hash_behaviour
for definida para merge
o 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_plugins
ansible.cfg
Por fim, atualize sua tarefa para parecer
name: my loop
action: shell echo ${item[1].name}
with_items: "{{var|hash_to_tuples}}"