我如何使用set_fact和with_together?

时间:2017-12-05 19:42:34

标签: ansible ansible-2.x ansible-facts

我正在尝试转换来自远程计算机上的属性文件的bash环境变量。我正在将键和值注册到两个寄存器变量,然后尝试使用with_togetherset_fact

来遍历它们

以下是我如何获取变量键/值

- name: Source Env Properties
  shell: . <source utility> && ( set -a posix ; set| sed 's,=.*,,' )
  register: variable_keys

- shell: . <source utility> && ( set -a posix ; set| sed 's,^.*=,,' )
  register: variable_values

之后,我尝试set_fact使用两个注册值。

- name: set variables
  set_fact:
     "{{item.0}}:{{item.1}}"
  with_together:
    - "{{ variable_keys.stdout_lines }}"
    - "{{ variable_values.stdout_lines }}"

任务的输出似乎应该有效,但在尝试使用这些变量时,它表示它们没有被定义。

谁能告诉我为什么这不起作用?

1 个答案:

答案 0 :(得分:1)

因此,正如我在评论中提到的,您的第一个问题是set_fact块中的语法不正确。如果你有这个:

"{{item.0}}:{{item.1}}"

然后你有单个字符串,而不是key: value对。你需要修改它看起来像

- name: set variables
  set_fact:
    "{{item.0}}": "{{item.1}}"
  with_together:
    - "{{ variable_keys.stdout_lines }}"
    - "{{ variable_values.stdout_lines }}"

但这只是问题的一半。您的sed表达式最终可能会产生语法无效的输出,因为它们将包含bash函数定义。也就是说,如果我在本地环境中运行第一个命令,则输出包括来自shell函数的所有残余,用于bash完成,git提示等,如下所示:

scl () 
{ 
    local CMD
    if [ "$CMD" 
        eval "module $@";
    else
        /usr/bin/scl "$@";
    fi
}

这只会破坏安塞:

failed: [localhost] (item=[u"'", u"'"]) => {"changed": false, "failed": true, "item": ["'", "'"], "msg": "The variable name ''' is not valid. Variables must start with a letter or underscore character, and contain only letters, numbers and underscores."}

您需要确保过滤掉该内容。我用过这个:

- name: Source Env Properties
  shell: . ./myvars.sh && ( set -a posix; set| sed -n '/^[A-Z]/ s,=.*,,p' )
  register: variable_keys

- shell: . ./myvars.sh && ( set -a posix; set| sed -n '/^[A-Z]/ s,^.*=,,p' )
  register: variable_values

- name: set variables
  set_fact:
    "{{item.0}}": "{{item.1}}"
  with_together:
    - "{{ variable_keys.stdout_lines }}"
    - "{{ variable_values.stdout_lines }}"

如果我有,请myvars.sh

FOO=bar

如果在我的剧本中,我有了上述内容:

- debug:
    var: FOO

我将看作输出:

ok: [localhost] => {
    "FOO": "bar"
}

顺便说一句,我认为sed所有这些问题都很脆弱,可能会导致其他问题。我可能会做这样的事情:

- name: Source Env Properties
  shell: |
    set -a
    . ./myvars.sh
    jq -n env
  register: vars_raw

- set_fact:
    shellvars: "{{ vars_raw.stdout|from_json }}"

- debug:
    var: shellvars.FOO

这使用jq将所有可用的环境变量导出为JSON,然后将结果分配给shellvars变量。 set -a确保myvars.sh中设置的任何变量都会导出到环境中。如果您没有jq方便,可以使用python

- name: Source Env Properties
  shell: |
    set -a
    . ./myvars.sh
    python -c 'import json; import os; print(json.dumps(dict(os.environ)))'
  register: vars_raw

- set_fact:
    shellvars: "{{ vars_raw.stdout|from_json }}"

- debug:
    var: shellvars.FOO