【问题标题】:How to write an Ansible task using with_dict in a loop (with_items)如何在循环中使用 with_dict (with_items) 编写 Ansible 任务
【发布时间】:2015-01-23 15:27:57
【问题描述】:

我想更新 INI 配置文件。

今天,我以这种方式将我的信息存储在一个 var 文件(在 group_vars 中):

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

在我的 Ansible 任务中,我以这种方式使用这些信息:

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

有没有办法使用每个“部分”参数(即 DEFAULT、数据库、令牌)遍历我的 dict 文件。事实上,我试图找到一种方法来执行嵌套在 with_items 循环中的 with_dict。

【问题讨论】:

  • 嗯,看来您需要在 jinja 中进行迭代,而不是在 Ansible 中。
  • 在这种情况下,我宁愿使用 ini 文件模板(参见 template module)。即使您计划做的事情是可能的,它看起来也会很混乱。 ini module 主要是模板模块的快捷方式,所以你应该只将它用于非常简单的任务
  • 感谢您的评论 tedder42 和 ProfHase85。实际上,我之前使用过模板文件,但我更喜欢让安装程序安装的配置文件,并使用 ini_file 更改其中的一些值。当您使用模板文件时,当配置文件因软件的新版本而发生更改时,您可能会遇到问题,并且您继续在远程主机上放置先前版本的配置文件。

标签: python configuration-files ini ansible


【解决方案1】:

我发现这种为 .ini 文件组织变量的方式非常有趣。

我想自己使用它,所以我开发了一个插件,它允许使用 inifile 模块一次性生成 .ini 文件的所有键。

它工作正常,我用来管理我的 OpenStack 配置文件。

我不是开发专家,但我觉得这个插件对每个人都有用,所以如果有人想接手维护并集成到ansible中,欢迎他。

插件将层次结构数据转换为列表(节、键、值),以便直接与 inifile 模块 with_inidata 一起使用,如下所示:

vars 文件:

...
glanceapi_conf:
  DEFAULT:
    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 }}"
  database:
    connection: "mysql://{{ image_db_user }}:{{ image_db_password }}@{{ db_host }}/{{ image_db }}"
  keystone_authtoken:
    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 }}"
  paste_deploy:
    flavor: keystone
  glance_store:
    default_store: file
    filesystem_store_datadir: /var/lib/glance/images/
...

插件代码:

# (c) 2014, Pierre-Yves KERVIEL <pierreyves.kerviel@orange.com>
#
# 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
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# 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 <http://www.gnu.org/licenses/>.

# 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

任务代码:

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

要使用它,只需将名为“dataini”的插件代码复制到 /etc/ansible.cfg 中定义的目录中即可。

这应该是 Ubuntu 发行版的 /usr/share/ansible_plugins/lookup_plugins 并按照我的示例编写您的任务。

我希望这个插件能让你简化你的ini文件管理。

【讨论】:

  • 谢谢 Pierre-Yves,这正是我想要的。我会尽快尝试你的代码。我会及时通知你。
  • 再次感谢皮埃尔-伊夫。我试过你的代码,效果很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-06
  • 2019-12-27
  • 2016-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多