I have a playbook that goes like this:
- name: Install php extensions
ansible.builtin.apt:
pkg:
- php{{ php_version }}{{ item.pkg_extension }}
loop:
- { pkg_extension: -mysql }
- { pkg_extension: -bz2 }
- { pkg_extension: -curl }
- { pkg_extension: -gd }
- { pkg_extension: -imap }
- { pkg_extension: -mbstring }
- { pkg_extension: -xml }
- { pkg_extension: -zip }
when: php_key_setup is succeeded and nginx_install is succeeded and php_base_install is succeeded
register: php_install
Sometimes for reasons unknown to me, this fails for one of the packages in the loop. I want to pass these packages as a list or a dictionary to the apt module instead, like in
- name: Optimal yum
ansible.builtin.yum:
name: "{{ list_of_packages }}"
state: present
How can I create this list from this loop, concatenating everything without adding an extra step to create this list and reuse it afterwards?
Given the variables
php_version: 8.3
php_pkg_extensions:
- mysql
- bz2
- curl
- gd
- imap
- mbstring
- xml
- zip
Declare the list
packages: "{{ ['php' ~ php_version]|
product(php_pkg_extensions)|
map('join', '-') }}"
gives what you want
packages:
- php8.3-mysql
- php8.3-bz2
- php8.3-curl
- php8.3-gd
- php8.3-imap
- php8.3-mbstring
- php8.3-xml
- php8.3-zip
Example of a complete playbook for testing
- hosts: localhost
vars:
php_version: 8.3
php_pkg_extensions:
- mysql
- bz2
- curl
- gd
- imap
- mbstring
- xml
- zip
packages: "{{ ['php' ~ php_version]|
product(php_pkg_extensions)|
map('join', '-') }}"
tasks:
- debug:
var: packages
- name: Install php extensions
ansible.builtin.apt:
pkg: "{{ packages }}"
when: install_php_extensions|d(false)|bool