I want to template php.ini configs for apache2 and cli. I filtered out the default options and added them to a dictionary like this:
php_config_options:
cli:
engine: "On"
short_open_tag: "Off"
precision: 14
[...]
apache2:
engine: "On"
short_open_tag: "Off"
precision: 14
[...]
I have put this under vars/Ubuntu-22.yaml
so that I can configure it ongoing for the releases. My template looks like this:
{% if php_config_options[environment] is defined %}
{% for option, value in php_config_options[environment].items() %}
{{ option }} = {{ value }}
{% endfor %}
{% endif %}
and my task like this:
- name: setup | Template php.ini
ansible.builtin.template:
src: "{{ php_version }}/php.ini.j2"
dest: /etc/php/{{ php_version }}/apache2/php.ini
owner: root
group: root
mode: 0644
vars:
environment: "apache2"
When I try to run it I got the Error dict object has no element []
but I don’t know why. Can anyone help me here?
My idea is to use these default variables, but when I want to change one I will set this in either group_vars or host_vars and he picks this + the other default ones.
2
Answers
You should use community.general.ini_file module, which was designed exactly for your usecase – to tweak existing settings, without maintaining defaults yourself.
I created a minimal reproducible playbook to illustrate how you can map your yaml settings into existing ini file
Let’s say we have a config.ini file inside playbook directory, with following contents:
We can then execute the following playbook.yaml
In this playbook we define 2 variables,
default_php_config_options
with default settings that need to be overriden andphp_config_options
which contain overrides for default options.The output of command
ansible-playbook playbook.yaml
will containand the contents of file config.ini are
Notice that value of key1 in section1 was replaced, and missing options were added, while original section0 values remain unchanged.
Now about this loop, what are we doing – we are combining
default_php_config_options
withphp_config_options
, thus overriding former with values from later if present (see combine filter docs), and then for each key/value pair in each section we are creating list, containingAnd executing init_file module for each generated list. I’m sure that other jinja-gurus can come up with clever function to solve same task, but I like my playbooks to be explicit.
The caveat is that if you’ll delete something from
default_php_config_options
or inphp_config_options
, but in key, that wasn’t present in defaults, it wont change already changed keys or sections back to default values. In that case you should either explicitly specify old value, or create a separate task to remove unneeded keys.Edit: added combine example.
default_php_config_options | combine(php_config_options)
can be used with @Vladimir Botka example as well, but I’ll leave my answer which gives an ability to work with existing ini files.Given the simplified dictionary
Use the filter community.general.to_ini. For example, the template
gives
Example of a complete playbook for testing