【问题标题】:How specify a list value as variable in ansible inventory file?如何在ansible库存文件中将列表值指定为变量?
【发布时间】:2013-09-05 11:54:37
【问题描述】:

我需要类似(ansible 库存文件):

[example]
127.0.0.1 timezone="Europe/Amsterdam" locales="en_US","nl_NL"

但是,ansible 不会将“语言环境”识别为列表。

【问题讨论】:

    标签: list variables ansible inventory


    【解决方案1】:

    你可以像这样传递一个列表或对象:

    [example]
    127.0.0.1 timezone="Europe/Amsterdam" locales='["en_US", "nl_NL"]'
    

    【讨论】:

    • @ryanyuyu 这不仅与问题中的代码不同,而且还是 OP 正在寻找的确切解决方案。你测试过吗?莱勒做到了,我也做到了:而且它有效。这应该是被接受的答案,而不是被否决。
    • 是的,也可以确认这有效。例如,这适用于“with_items”语句。你甚至可以像这样创建类似字典的对象。我使用它在清单文件中定义 nginx 身份验证用户和密码: nginx_auth='[ {"user": "user1", "pass": "pass1"}, {"user": "user2", "pass": "pass2"}]'
    • 这是最简洁的ini文件解决方案吗?如果您有 20 多个项目和 5 个主机来配置它怎么办?很高兴知道,但这暂时有效。
    • @WillHarris 你能把多个项目放在一个键中吗?例如:{"user":["user1","user2"]}?
    • @JohnnyQ 取决于您希望如何处理该值。在我的示例中,我将使用with_items: nginx_auth,然后以{{item.user}}{{item.pass}} 的身份访问。在您的示例中,我看不到在使用 with_items 的上下文中迭代您的值列表的任何自然方式。也许您可以使用 Jinja2 过滤器在模板中进行额外的“列表”处理。
    【解决方案2】:

    对于复杂变量,最好在 host_vars 文件中而不是在清单文件中定义它们,因为 host_vars 文件支持 YAML 语法。

    尝试创建一个包含以下内容的host_vars/127.0.0.1 文件:

    timezone: Europe/Amsterdam
    locales:
        - en_US
        - nl_NL
    

    【讨论】:

    • 谢谢,这是我目前的工作方式 :) 您的回答是否意味着您不能在清单文件(和 --extra-vars)中指定列表变量?
    • @rmuller 我不知道是否可以在 ini 文件或命令行中指定列表变量。如果您在 ansible 邮件列表中提问,您可能会得到更快的回复。
    • @rmuller 我还建议加入#ansible IRC 频道,那里的人通常会很快提供帮助:-)
    • 我认为库存中不可能。我尝试使用下面的破折号前缀列表 xyz=,但收到错误“错误:分配给组的变量必须采用 key=value 形式”。
    • 我也想过使用这个,但这是一种乏味的方法。特别是如果您有很多网站要配置。
    【解决方案3】:

    Ryler 的回答在这种特定情况下很好,但我在使用模板模块的其他变体时遇到了问题。

    [example]
    127.0.0.1 timezone="Europe/Amsterdam" locales='["en_US", "nl_NL"]'
    

    是他的原始示例并且工作正常。

    以下变体适用于模板。基本上,如果它是一个字符串,您必须记住使用内部双引号,否则整个结构将被解析为单个字符串。如果它只是数字或“真”或“假”(不是“是”),那么你很好。在这个变体中,如果模板有外部引号,我无法让它与模板一起使用。

    除了模板模块之外,我还没有彻底检查它们会破坏哪些内部用例。

    我正在使用 Ansible 2.2.1。

    [example:vars]
    # these work
    myvar1=["foo", "bar"]
    myvar2=[1,2]
    myvar3=[True,False]
    
    # These fail, they get interpreted as a single string.
    myvar4=[yes, no]
    myvar5=[foo,bar]
    myvar6='["foo", "bar"]'
    

    【讨论】:

    • 这个额外的信息帮助我解决了一个烦人的任意变量解析问题。谢谢!
    • 一点额外信息:我认为差异是由于不同的解析路线而产生的。在 [group:vars] 中,所有内容都直接作为 INI_PARSER->YAML_PARSER 传递,包括双引号。因此 YAML 解析器将其解释为字符串。在主机名之后,它通过与模块的“等于样式”参数一起使用的解析器类似的解析器:INI_PARSER->ANSIBLE_ARG_PARSER->YAML_PARSER。在后一种情况下,ANSIBLE_ARG_PARSER 解释双引号字符串并将内容(不带引号)传递给 YAML 解析器。
    【解决方案4】:

    你可以试试拆分

    #inventory file
    [example]
    127.0.0.1 timezone="Europe/Amsterdam" locales="en_US","nl_NL"
    
    #role file
    ---
    - debug: msg="{{ item }}"
      with_items: locales.split(',')
    

    【讨论】:

      【解决方案5】:

      我相信这种情况是您定义变量的地方。

      如果它在a下

      [主机:变量] var=["a", "b"]

      否则:

      [主持人] host1 var='["a", "b"]'

      【讨论】:

        【解决方案6】:

        带有变量的 INI 文件如下所示

        $ cat ./vars/vars.yml

        lvol_names=['2g-1','2g-2','2g-3']
        

        变量代表列表类型

         lvol_names:
               - 2g-1
               - 2g-2
               - 2g-3
        

        可以通过查找从剧本中读取变量:

        $ cat ./play.yml

        - name: play1
          hosts: kub2_data_nodes
          become: yes
        
        
          vars:
         
             - lvol_names: "{{ lookup('ini', 'lvol_names type=properties file=./vars/vars.yml') }}"
             
        

        【讨论】:

          【解决方案7】:

          您可以自定义过滤器,将字符串拆分为列表

          Github ansible example 展示如何创建自定义过滤器。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-03-19
            • 2019-04-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多