AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 685673
Accepted
Craig Ringer
Craig Ringer
Asked: 2015-04-27 06:17:35 +0800 CST2015-04-27 06:17:35 +0800 CST 2015-04-27 06:17:35 +0800 CST

在 Ansible 中附加到列表或向字典添加键

  • 772

(与Ansible 角色中的回调或钩子以及可重用的一系列任务有关):

有没有比(ab)使用 jina2 模板表达式更好的方法来追加到列表或在 Ansible 中向字典添加键?

我知道您可以执行以下操作:

- name: this is a hack
  shell: echo "{% originalvar.append('x') %}New value of originalvar is {{originalvar}}"

但是真的没有任何元任务或助手可以做到这一点吗?

它感觉很脆弱,似乎没有文档记录,并且依赖于许多关于变量在 Ansible 中如何工作的假设。

我的用例是多个角色(数据库服务器扩展),每个角色都需要为基本角色(数据库服务器)提供一些配置。这不像在 db server 配置文件中添加一行那么简单;每个更改都适用于同一行,例如扩展名bdr和pg_stat_statements必须都出现在目标行上:

shared_preload_libaries = 'bdr, pg_stat_statements'

执行此操作的 Ansible 方法是否只是使用正则表达式多次处理配置文件(每个扩展名一次),提取当前值,解析它,然后重写它?如果是这样,您如何在多次运行中使其具有幂等性?

如果配置比这更难解析并且不像附加另一个逗号分隔值那么简单怎么办?想想 XML 配置文件。

ansible
  • 6 6 个回答
  • 128794 Views

6 个回答

  • Voted
  1. Max Kovgan
    2016-12-10T01:28:23+08:002016-12-10T01:28:23+08:00

    从 Ansible v2.x 开始,您可以执行以下操作:

    # use case I: appending to LIST variable:
    - name: my appender
      set_fact:
        my_list_var: '{{my_list_myvar + new_items_list}}'
    
    # use case II: appending to LIST variable one by one:
    - name: my appender
      set_fact:
        my_list_var: '{{my_list_var + [item]}}'
      with_items: '{{my_new_items|list}}'
    
    # use case III: appending more keys DICT variable in a "batch":
    - name: my appender
      set_fact:
        my_dict_var: '{{my_dict_var|combine(my_new_keys_in_a_dict)}}'
    
    # use case IV: appending keys DICT variable one by one from tuples
    - name: setup list of tuples (for 2.4.x and up
      set_fact:
        lot: >
          [('key1', 'value1',), ('key2', 'value2',), ..., ('keyN', 'valueN',)],
    - name: my appender
      set_fact:
        my_dict_var: '{{my_dict_var|combine({item[0]: item[1]})}}'
      with_items: '{{lot}}'
    
    # use case V: appending keys DICT variable one by one from list of dicts (thanks to @ssc)
    - name: add new key / value pairs to dict
      set_fact:
        my_dict_var: "{{ my_dict_var | combine({item.key: item.value}) }}"
      with_items:
      - { key: 'key01', value: 'value 01' }
      - { key: 'key02', value: 'value 03' }
      - { key: 'key03', value: 'value 04' }
    

    以上所有内容都记录在: https ://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-hashes-dictionaries

    • 48
  2. Best Answer
    GnP
    2015-06-27T08:51:06+08:002015-06-27T08:51:06+08:00

    您可以使用 合并变量中的两个列表+。假设您有一个group_vars包含以下内容的文件:

    ---
    # group_vars/all
    pgsql_extensions:
      - ext1
      - ext2
      - ext3
    

    它用于模板中,pgsql.conf.j2例如:

    # {{ ansible_managed }}
    pgsql_extensions={% for item in pgsql_extensions %}{{ item }}, {% endfor %}
    

    然后,您可以将扩展附加到测试数据库服务器,如下所示:

    ---
    # group_vars/testing_db
    append_exts:
      - ext4
      - ext5
    pgsql_extensions: "{{ pgsql_extensions + append_exts }}"
    

    当角色在任何测试服务器中运行时,将添加额外的扩展。

    我不确定这也适用于字典,并且还要小​​心空格并在行尾留下一个悬空的逗号。

    • 19
  3. Arthur Tsang
    2016-03-16T09:05:31+08:002016-03-16T09:05:31+08:00

    你需要把循环分成2

    ---
    - 主机:本地主机
      任务:
        - include_vars:堆栈
        - set_facts: 角色={{stacks.Roles | 分裂(' ')}}
        - 包括:addhost.yml
          with_items:“{{角色}}”
    

    和 addhost.yml

    - set_facts: groupname={{item}}
    - set_facts: ips={{stacks[item]|split(' ')}}
    - local_action: add_host hostname={{item}} groupname={{groupname}}
      with_items: {{ips}}
    
    • 3
  4. VeselaHouba
    2019-10-22T03:24:00+08:002019-10-22T03:24:00+08:00

    这里几乎所有的答案都需要更改任务,但我需要在 vars 定义中动态合并字典,而不是在运行期间。

    例如,我想在其中定义一些共享变量all group_vars,然后我想在其他一些group或host_vars. 在为角色工作时非常有用。

    如果您尝试使用combineorunion过滤器覆盖 var 文件中的原始变量,您将在模板过程中以无限循环结束,因此我创建了此解决方法(这不是解决方案)。

    您可以根据某些名称模式定义多个变量,然后自动将它们加载到角色中。

    group_vars/all.yml

    dictionary_of_bla:
      - name: blabla
        value1 : blabla
        value2 : blabla
    

    group_vars/group1.yml

    dictionary_of_bla_group1:
      - name: blabla2
        value1 : blabla2
        value2 : blabla2
    

    角色代码片段

    tasks:
      - name: Run for all dictionary_of_bla.* variations
        include_tasks: do_some_stuff.yml
        with_items: "{{ lookup('varnames','dictionary_of_bla.*').split(',') }}"
        loop_control:
          loop_var: _dictionary_of_bla
    

    do_some_stuff.yml

    - name: do magic
      magic:
        trick_name: item.name
        trick_value1: item.value1
        trick_value2: item.value2
      with_items: "{{ vars[_dictionary_of_bla] }}"
    

    这只是一个片段,但您应该了解它是如何工作的。注意:lookup('varnames','') 从 ansible 2.8 开始可用

    我想也可以dictionary_of_bla.*在运行时使用相同的查找将所有变量合并到一个字典中。

    这种方法的优点是您不需要设置确切的变量名称列表,而只有模式和用户可以动态设置它。

    • 3
  5. nuts
    2018-08-09T02:51:14+08:002018-08-09T02:51:14+08:00

    不确定他们什么时候添加的,但至少对于字典/哈希(不是列表/数组),您可以设置变量hash_behaviour,如下所示:hash_behaviour = merge在您的ansible.cfg.

    我花了好几个小时才偶然发现这个设置:S

    • 2
  6. Antonis Christofides
    2015-04-28T23:01:49+08:002015-04-28T23:01:49+08:00

    Ansible是一个自动化系统,并且,关于配置文件管理,它与apt. 越来越多的软件提供从conf.d目录读取配置片段的功能的原因是使此类自动化系统能够具有不同的包/角色,从而将配置添加到软件中。我相信这不是Ansible做你想做的事的哲学,而是使用conf.d技巧。如果正在配置的软件不提供此功能,您可能会遇到麻烦。

    既然你提到了 XML 配置文件,我借此机会做一些抱怨。Unix 传统使用纯文本配置文件是有原因的。二进制配置文件不适合系统自动化,因此任何类型的二进制格式都会给您带来麻烦,并且可能需要您创建一个程序来处理配置。(如果有人认为 XML 是纯文本格式,他们应该去好好研究一下。)

    现在,关于你的具体PostgreSQL问题。PostgreSQL确实支持这个conf.d把戏。首先,我会检查是否shared_preload_libraries可以多次指定。我在文档中没有找到任何提示,但我仍然会尝试。如果不能多次指定,我会向他们解释我的问题PostgreSQL,以防他们有想法;这是一个PostgreSQL问题,而不是一个Ansible问题。如果没有解决方案并且我真的无法将不同的角色合并为一个,我将实现一个系统来编译托管主机上的配置。在这种情况下,我可能会创建一个/usr/local/sbin/update_postgresql_config可以编译/etc/postgresql/postgresql.conf.jinja为/etc/postgresql/9.x/main/postgresql.conf. 该脚本将从 中读取共享的预加载库/etc/postgresql/shared_preload_libraries.txt,每行一个库,并将它们提供给 jinja。

    自动化系统这样做并不少见。一个例子是 Debianexim4软件包。

    • -5

相关问题

  • Ansible 剧本,使用选项 --disabled-login 创建用户

  • ansible playbook,操作系统不同的用户

  • ansible:为什么文件模块会跳过?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve