преобразование словарных ключей в playbook

#ansible #ansible-playbook

#ansible

Вопрос:

У меня есть существующий словарь переменных playbook, определенный как:

 vars:
  resource_tags: {
    Name: "some name"
    Service: "some service"
  }
  

Это используется при различных вызовах задач в этой форме. Но в другой задаче мне нужно это в другом формате, и вместо того, чтобы жестко кодировать, мне было интересно, можно ли это встроить в задачу.

Мне нужно, чтобы это выглядело как:

   {
    "tag:Name": "some name"
    "tag:Service": "some service"
  }
  

Я попытался повторить использование with_dict и установить факт с помощью combine:

   - set_fact:
        ec2_remote_facts_filter: "{{ ec2_remote_facts_filter | default({}) | combine( { 'tag:'item.name: item.val } ) }}"
    with_dict: "{{ ec2_count_resource_tags }}"
  

И, очевидно, это не работает.

Возможно ли это вообще?

Ответ №1:

Если вы не возражаете против небольшого взлома:

 - debug: msg="{{ resource_tags | to_json(indent=0) | regex_replace('n"','n"tag:') }}"
  

Это преобразует ваш dict в строку в формате JSON с indent=0 , что означает, что каждый ключ будет начинаться с новой строки; затем вставьте tag: после первой двойной кавычки в каждой строке.
Поскольку результат является допустимым JSON, механизм шаблонов Ansible преобразует его обратно в dict в качестве последнего шага замены переменных, предоставляя вам:

 ok: [localhost] => {
    "msg": {
        "tag:Name": "some name",
        "tag:Service": "some service"
    }
}
  

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

Комментарии:

1. Это работает отлично. Я предпочитаю этот подход, потому что он не требует установки каких-либо пользовательских модулей на сервере ansible, поэтому код будет отлично работать в моей тестовой виртуальной машине ansible, а также при запуске под Ansible Tower.

Ответ №2:

Возможно, вам нужен пользовательский плагин поиска в вашем случае.

1) Отредактируйте файл ansible.cfg и раскомментируйте ключ ‘lookup_plugins’ со значением ‘./plugins/lookup’

2) Создайте файл плагина с именем ‘ec2remote.py ‘ в ‘./plugins/lookup’

3) Используйте его в своем playbook:

 - debug:
    msg: "{{ item }}"
  with_ec2remote: "{{ ec2_count_resource_tags }}"
  

4) Реализует ваш ec2remote.py (здесь много примеров)

 class LookupModule(LookupBase):
  def run(self, terms, **kwargs):
    result = {}
    for k,v in terms.items():
       result["tag:" k] = v
    return result
  

Обычно я предпочитаю разрабатывать плагины, которые легко использовать и тестировать и, таким образом, сохранять понятный playbook.