Ansible — Цикл над вложенным массивом внутри списка объектов?

#ansible

Вопрос:

Я пытаюсь найти наиболее эффективный способ установки каждой версии PHP и пакетов для каждой версии без дублирования.

В настоящее время у меня есть это:

 - name: Install PHP
  apt:
    name: "{{ packages.php_version }}-{{ packages.packages }}"
  vars:
    packages:
      - { php_version: 5.6, packages: ['common', 'cli', 'opcache', 'mysql', 'mbstring', 'simplexml', 'curl', 'bcmath', 'ldap', 'gd', 'dom', 'zip', 'xml', 'readline', 'json', 'fpm', 'imagick']}
      - { php_version: 7.0, packages: ['common', 'cli', 'opcache', 'mysql', 'mbstring', 'simplexml', 'curl', 'bcmath', 'ldap', 'gd', 'dom', 'zip', 'xml', 'readline', 'json', 'fpm', 'imagick']}
 

Однако я не могу настроить селектор, чтобы он работал над пакетами.

Я хотел бы иметь что-то, где это в основном повторяет каждую версию php и пакеты для каждой, поскольку они могут отличаться.

Спасибо

ОТРЕДАКТИРУЙТЕ, ЧТОБЫ ОТВЕТИТЬ почти на все вопросы для меня! Большое спасибо. Я хотел установить все версии PHP только одну выбранную версию. Поэтому я сделал следующее:

 - name: Install PHP
  apt:
    name: "php{{ item.0.key }}-{{ item.1 }}"
  loop: "{{ packages_dict | dict2items | subelements('value') }}"
 

Не уверен, что это лучший способ? кажется неэффективным на самом деле, но это работает!

Ответ №1:

Наиболее эффективным способом было бы сначала преобразовать список в словарь. Например

   packages_dict: "{{ packages|items2dict(key_name='php_version',
                                         value_name='packages') }}"
 

дает (сокращенно)

   packages_dict:
    '5.6':
    - common
    - cli
    - opcache
    '7.0':
    - common
    - cli
    - opcache
 

Тогда выбор и итерация тривиальны, например

 - hosts: localhost
  vars:
    packages:
      - php_version: '5.6'
        packages: ['common', 'cli', 'opcache']
      - php_version: '7.0'
        packages: ['common', 'cli', 'opcache']
    packages_dict: "{{ packages|items2dict(key_name='php_version',
                                           value_name='packages') }}"
    php_version: "{{ my_php_version|d('5.6') }}"
  tasks:
    - name: Install PHP
      debug:
        msg: "name: {{ php_version }}-{{ item }}"
      loop: "{{ packages_dict[php_version] }}"
 

дает

   msg: 'name: 5.6-common'
  msg: 'name: 5.6-cli'
  msg: 'name: 5.6-opcache'
 

Вопрос: «Я хотел установить ВСЕ версии php.«

Ответ: В этом случае преобразование не требуется. Вы можете повторить пакеты списка с подэлементами, например

     - name: Install PHP
      debug:
        msg: "name: {{ item.0.php_version }}-{{ item.1 }}"
      with_subelements:
        - "{{ packages }}"
        - packages
 

дает

   msg: 'name: 5.6-common'
  msg: 'name: 5.6-cli'
  msg: 'name: 5.6-opcache'
  msg: 'name: 7.0-common'
  msg: 'name: 7.0-cli'
  msg: 'name: 7.0-opcache'
 

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

1. Смотрите правку в исходном посте, уценка в этом комментарии не работала. Большое спасибо, что указали мне правильное направление. Однако я хотел установить ВСЕ версии php, а не только выбранную.