简体   繁体   English

使用 jinja2 创建 ansible 列表变量

[英]Create ansible list variable with jinja2

The following code is in the defaults/main.yml file for a role:以下代码位于角色的 defaults/main.yml 文件中:

  file_env: "{% if cf_env is equalto 'cf10_dev' %}\
  dev\
  {% elif cf_env is equalto 'cf10_stg' %}\
  stg\
  {% elif (cf_env is equalto 'cf10_prd') or (cf_env is equalto 'cf10_prd_ext') %}\
  prd\
  {% elif cf_env is equalto 'cf11' %}\
  [dev, prd]
  {% endif %}"

The first 3 conditional statements work fine, where the file_env var is set to a single value, but when trying to set the file_env var to a list (the last elif statement), it doesn't work:前 3 个条件语句工作正常,其中file_env var 设置为单个值,但是当尝试将file_env var 设置为列表(最后一个 elif 语句)时,它不起作用:

failed: [server-new.xxx.com] (item=[dev, prd] ) => {"ansible_loop_var": "item", "changed": false, "item": "[dev, prd] ", "msg": "Destination /opt/coldfusion11/[dev, prd] 01/bin/jvm.config does not exist !", "rc": 257}

Here is the task that generates the above error:这是产生上述错误的任务:

- name: Update jvm.config for coldfusion11 server
  lineinfile:
    path: /opt/coldfusion11/{{ item }}01/bin/jvm.config
    regexp: '^java.home'
    line: 'java.home=/usr/lib/jvm/jre-openjdk'
  loop:
    - "{{ file_env }}"
  notify:
    - handler_create_script_list
    - handler_restart_coldfusion10
  when:
    - cf_env == "cf11"

How can I set the file_env var to a list?如何将file_env var 设置为列表?

I believe your issue is that it's interpreting the variable as a string, literally '[dev, prd] ' (with a space at the end, judging by the error message).我相信你的问题是它将变量解释为一个字符串,字面意思是'[dev, prd] ' (最后有一个空格,根据错误消息判断)。

I think you want to try a different format as suggested in https://serverfault.com/a/913936/512181我认为您想尝试https://serverfault.com/a/913936/512181中建议的不同格式

  1. If your are going to loop over your var, you should always return a list (with single element when needed) to avoid possible tricky errors.如果您要遍历您的 var,则应始终返回一个列表(需要时带有单个元素)以避免可能的棘手错误。 You simply need to modify your loop expression to the following:您只需将loop表达式修改为以下内容:

     loop: "{{ file_env }}"
  2. Your template expressions are not using white space control which will end up with new lines in the output when they should not appear.您的模板表达式没有使用空格控件,当它们不应该出现时,它们最终会在 output 中出现新行。

  3. Your variable definition is hardly readable (and makes me think you have a deeper project architecture issue but that's an other story).你的变量定义很难读(这让我觉得你有更深层次的项目架构问题,但那是另一回事了)。 Taking into account point 1 above, I suggest you refactor to the following more readable, sustainable and working form using a key/value mapping in a dict and getting the corresponding value in your final var考虑到上面的第 1 点,我建议您使用 dict 中的键/值映射并在最终 var 中获取相应的值,重构为以下更具可读性、可持续性和工作性的形式

    files_by_env cf10_dev: - dev cf10_stg: - stg cf10_prd: - prd cf10_prd_ext: - prd cf11: - dev - prd file_env: "{{ files_by_env[cf_env] }}"

    Alternatively, you can reverse the definition in the dict (ie list environments for every file) which is slightly less verbose but leads to a more complicated expression to get the result或者,您可以反转 dict 中的定义(即每个文件的列表环境),这稍微不那么冗长,但会导致更复杂的表达式来获得结果

    env_by_file: dev: - cf10_dev - cf11 stg: - cf10_stg prd: - cf10_prd - cf10_prd_ext - cf11 file_env: "{{ env_by_file | dict2items | selectattr('value', 'contains', cf_env) | map(attribute='key') | list }}"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM