Я использую Ansible для чтения в файле YAML, содержащем список словарей.Затем мне нужно перебрать этот список и вызвать другую роль в зависимости от данных в каждом объекте списка.У меня есть решение, которое работает, но оно кажется мне таким грязным, что я хотел выяснить, есть ли лучший способ.
Я определил структуру файла YAML, чтобы обеспечить ввод в мою книгу воспроизведения, и я прочитал этот файл в переменную с помощью модуля include_vars
.Затем я использую with_items
для обхода массива один раз для каждой роли, которую мне нужно поддерживать (в настоящее время 6, но она может увеличиться), и использую предложение when
только для include_role
, когда данные в объекте верныдля этой роли.
Код
Образец входного файла:
---
objects:
- type: type1
name: obj_type1
- type: type2
name: obj_type2
- type: type3
name: obj_type3
Образец Playbook:
---
- hosts: cf-host
gather_facts: False
vars:
objects_file: ''
tasks:
- name: Read objects_file
include_vars:
file: "{{ objects_file }}"
- name: Handle type1
include_role:
name: type1_role
vars:
- type1_role_name: "{{ item.name }}"
with_items: "{{ objects }}"
when: item.type == "type1"
- name: Handle type2
include_role:
name: type2_role
vars:
- type2_role_name: "{{ item.name }}"
with_items: "{{ objects }}"
when: item.type == "type2"
- name: Handle type3
include_role:
name: type3_role
vars:
- type3_role_name: "{{ item.name }}"
with_items: "{{ objects }}"
when: item.type == "type3"
Образец роли:
---
- name: Print name
debug:
msg: "Type 1 - Name is {{ type1_role_name }}"
Другие роли такие же, но для msg
установлено значение "Тип X - имя равно {{typeX_role_name}}".
Это приводит к пропущенной задачедля каждого элемента в списке, когда он не соответствует типу, соответствующему роли.Это также означает, что я должен циклически проходить по одному и тому же списку несколько раз (столько, сколько типов, которые мне нужно поддерживать).Как уже упоминалось, мне уже нужно поддерживать 6 различных типов, и это число может возрасти.
Такое решение выглядит так, как будто оно очень плохо масштабируется и будет иметь ужасную производительность, так как список и поддерживаемые типы становятся все больше и больше.Есть ли лучший способ сделать то, что мне нужно сделать?
Лучшее решение
Используя этот ответ: https://stackoverflow.com/a/53859851/9744341 в качестве основы, я смог прийтис этим как лучшее решение, которое я доволен.Вот, если у кого-то еще есть такие же потребности:
Образец Playbook:
---
- hosts: cf-host
gather_facts: False
vars:
objects_file: ''
role_name_lookup:
type1:
role_name: type1_role
tasks_from: type1_tasks
type2:
role_name: type2_role
tasks_from: type2_tasks
type3:
role_name: type3_role
tasks_from: main
tasks:
- name: Read objects_file
include_vars:
file: "{{ objects_file }}"
- name: Call roles to create infra
include_role:
name: "{{ role_name_lookup[item.type].role_name }}"
tasks_from: "{{ role_name_lookup[item.type].tasks_from }}"
vars:
inputs: "{{ item }}"
with_items: "{{ objects }}"
Образец роли:
---
- name: Print name
debug:
msg: "Type 1 - Name is {{ inputs.name }}"
Другие роли такие же, новместо msg
установите Type X - Name is {{ inputs.name }}
.