В Ansible playbook, как лучше перебрать список объектов и вызвать другую роль в зависимости от данных этого объекта? - PullRequest
0 голосов
/ 20 декабря 2018

Я использую 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 }}.

1 Ответ

0 голосов
/ 20 декабря 2018

Подойдет ли этот код вашей цели?

- name: Include roles
  include_role:
    name: "{{ item.type }}_role"
  with_items: "{{ objects }}"


- name: Print name
  debug:
    msg: "{{ item.type }} - Name is {{ role_name }}"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...