【问题标题】:Set fact with dynamic key name in ansible在ansible中使用动态键名设置事实
【发布时间】:2016-07-01 10:56:51
【问题描述】:

我正在尝试缩小几块类似的代码,如下所示:

- ... multiple things is going here
  register: list_register
- name: Generating list
  set_fact: my_list="{{ list_register.results | map(attribute='ansible_facts.list_item') | list }}"

# the same code repeats...

其实它们之间唯一的区别就是我这里使用了不同的列表名,而不是my_list

其实我想这样做:

set_fact:
  "{{ some var }}" : "{{ some value }}"

我遇到了this post,但在这里没有找到任何答案。

是否可以这样做或有任何解决方法?

【问题讨论】:

    标签: variables dynamic ansible


    【解决方案1】:

    看看这个示例剧本:

    ---
    - hosts: localhost
      vars:
        iter:
          - key: abc
            val: xyz
          - key: efg
            val: uvw
      tasks:
        - set_fact: {"{{ item.key }}":"{{ item.val }}"}
          with_items: "{{iter}}"
        - debug: msg="key={{item.key}}, hostvar={{hostvars['localhost'][item.key]}}"
          with_items: "{{iter}}"
    

    【讨论】:

    • 其实简化后的答案是set_fact: {"{{ key }}":"{{ val }}"}
    • 感谢您的想法,我通过使用字典列表 [{key: var1, val: val1}, {key: var2, val: val2}] 而不是单个字典 {var1: val1, var2: val2} 来解决问题。
    【解决方案2】:

    以上对我不起作用。最终起作用的是

    - set_fact:
        example_dict: "{'{{ some var }}':'{{ some other var }}'}"
    

    这到底是显而易见的。您构造一个字符串(外部双引号),然后将其解释为哈希。在散列中,键和值必须是单引号(变量替换周围的内部单引号)。最后,您只需像在任何其他字符串中一样放置变量替换。

    斯蒂芬

    【讨论】:

    • 这里,example_dict 最终是一个字符串,而不是字典。
    • 我也必须这样定义,用双引号括起来,ansible 2.3.2.0。它最终不是一个字符串,用debug: 打印它表明它具有正确的字典结构。
    • 非常感谢!这也适用于环境变量键名是基于运行时已知的名称的动态的情况。因此,可以在docs.ansible.com/ansible/latest/user_guide/… 的文档中描述的模块级别使用environment:,并使用- "{'dynamic environment variable key name inkl. {{ vars }}':'{{ dynamic environment variable value}}'}" (here´s a full example) 创建变量。
    【解决方案3】:

    截至 2018 年,使用 ansible v2.7.1,您在帖子中建议的语法运行良好。

    至少在我的情况下,我有这个角色“a”:

    - name: Set fact
      set_fact: 
         "{{ variable_name }}": "{{ variable_value }}"
    

    还有那个角色“b”:

    - debug:
      msg: "variable_name = {{ variable_name }}"
    

    然后执行:

    TASK [role a : Set fact] *******************************************************
    ok: [host_name] => {
      "ansible_facts": {
        "variable_name": "actual value"
      }, 
      "changed": false
    }
    
    ...
    
    TASK [role b : debug] **********************************************************
    ok: [host_name] => {}
    
    MSG:
    
    variable_name = actual value
    

    【讨论】:

    • 使用 ansible 2.9.0 这不起作用:- set_fact: _register_role_run: "{{ register_role_run_conf.name }}": "{{ register_role_run_conf.state }}" - debug: var: register_role_run_conf - debug: var: _register_role_run 输出 TASK [register_role_run : debug] ok: [apigw-adco] => { "register_role_run_conf": { "name": "host_config", "state": true } } TASK [register_role_run : debug] ok: [apigw-adco] => { "_register_role_run": { "{{ register_role_run_conf.name }}": true } }
    【解决方案4】:
    - set_fact: '{{ some_var }}={{ some_value }}'
    

    它通过连接some_var 的值(事实名称)、分隔符=some_value 的值(事实值)来创建一个inline module parameter expression 字符串。

    【讨论】:

    • 很好,这确实有效,因为在 YAML 中,'=' 符号始终是一个字符串,并且由 ansible 解析。
    【解决方案5】:
    - set_fact:
        var1={"{{variable_name}}":"{{ some value }}"}
    

    这将使用您的动态变量键和值创建一个变量“var1”。


    示例:我用它在 AWS Autoscaling 组中创建动态标签,为这样的实例创建 kubernetes 标签:

    - name: Dynamic clustertag
      set_fact:
        clustertag={"kubernetes.io/cluster/{{ clustername }}":"owned"}
    
    - name: Create the auto scale group
      ec2_asg:
        .
        .
        .
        tags:
          - "{{ clustertag }}"
    

    【讨论】:

    • 不起作用。 set_fact: var1=... 甚至不解析。
    【解决方案6】:

    注意 2.9 中的变化——行为发生了变化,导致所有答案无效。 https://github.com/ansible/ansible/issues/64169

    【讨论】:

    • 那么正确的行为是什么?
    • 我在这里没有答案——除了用 JSON 创建一个字符串并导入它。我想创建一个包含单个条目的字典,该字典基于具有多个应用程序配置的字典——并且应用程序的名称存储在一个变量中。我求助于遍历原始字典并仅用一个定义调用包含。但这是代码中的一种解决方法,而不是原始问题的替代方法。 OTOH,我猜这些情况中的大多数都可以转换为这种方法。
    • 这是一个错误,正如错误状态 已关闭 所示,它已被修复。
    猜你喜欢
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    相关资源
    最近更新 更多