Jean-Louis FEREY Jean-Louis FEREY - 2 months ago 55
Ini Question

How to write an Ansible task using with_dict in a loop (with_items)

I want to update INI configuration files.

Today, I store my informations in a var file (in group_vars) this way :

# Identity configuration information
admin_token: "{{identity_admin_token}}"
verbose: True
connection: "mysql://{{ identity_db_user }:{{ identity_db_password }}@{{ db_lb_name }}/{{ identity_db }}"
provider: keystone.token.providers.uuid.Provider
driver: keystone.token.persistence.backends.sql.Token

In my Ansible task, I use these informations this way:

- name: configuration / modify keystone.conf ini file DEFAULT section
section: DEFAULT
dest: /etc/keystone/keystone.conf
option: "{{item.key}}"
value: "{{item.value}}"
with_dict: identity_servers_conf['DEFAULT']

Is there a way to iterate through my dict file with each "section" parameters, i.e DEFAULT, database, token. In fact, I try to find a way to do a with_dict nested in a with_items loop.


I find very interesting this way of organizing variables for .ini files.

I wanted to use it myself, so I worked on a plugin that allows to generate all the keys of an .ini file in one pass with the inifile module.

It works fine and I use to manage my OpenStack configuration files.

I am not a specialist in development, but I think this plugin can be useful for everyone, so if someone wants to take over to maintain and integrate it into ansible, he is welcome.

The plugin transforms the hierarchy data in a list (section, key, value) for use directly with the inifile module with_inidata as below:

vars file :

    verbose: "{{ image_log_verbose }}"
    rabbit_host: "{{ amqp_host }}"
    rabbit_port: "{{ amqp_port }}"
    rabbit_userid: "{{ amqp_userid }}"
    rabbit_password: "{{ amqp_password }}"
    rabbit_ha_queues: "{{ amqp_ha_queues }}"
    connection: "mysql://{{ image_db_user }}:{{ image_db_password }}@{{ db_host }}/{{ image_db }}"
    auth_uri: "http://{{ identity_admin_host }}:{{ identity_api_port }}/v2.0"
    identity_uri: "http://{{ identity_admin_host }}:{{ identity_admin_port }}"
    admin_tenant_name: "{{ image_ks_tenant }}"
    admin_user: "{{ image_ks_user }}"
    admin_password: "{{ image_ks_password }}"
    flavor: keystone
    default_store: file
    filesystem_store_datadir: /var/lib/glance/images/

plugin code :

# (c) 2014, Pierre-Yves KERVIEL <>
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with Ansible.  If not, see <>.

# inidata is used to manage ini

import ansible.utils as utils
import ansible.errors as errors

class LookupModule(object):

    def __init__(self, basedir=None, **kwargs):
        self.basedir = basedir

    def run(self, terms, inject=None, **kwargs):
        terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject)

        if not isinstance(terms, dict):
            raise errors.AnsibleError("inidata lookup expects a dictionnary , got '%s'" %terms)

        ret = []
        for item0 in terms:
            if not isinstance(terms[item0], dict):
                raise errors.AnsibleError("inidata lookup expects a dictionary, got '%s'" %terms[item0])
            for item1 in terms[item0]:
                ret.append((item0, item1, terms[item0][item1]))

        return ret

Task code :

- name: configuration.modify_glance-api_conf_file / modify glance-api.conf ini file
    section: "{{ item.0 }}"
    dest: /etc/glance/glance-api.conf
    option: "{{ item.1 }}"
    value: "{{ item.2 }}"
    backup: yes
  with_inidata: glanceapi_conf

To use it, simply copy the plugin code with the name "dataini" in the directory defined in /etc/ansible.cfg.

This should be /usr/share/ansible_plugins/lookup_plugins for the Ubuntu distribution and write your tasks as in my example.

I hope that this plugin will allow you to simplify your ini files management.