Ansible变量:我可以在其内部引用变量吗?

时间:2018-07-10 12:07:54

标签: ansible yaml

我正在为一部有趣的剧本写角色。在角色中,我有一个defaults文件夹,其中包含一个main.yml,用于定义该角色使用的变量的默认值。我可以在同一对象内交叉引用吗?

例如,我尝试了以下方法:

scripts_config: 
  host_entry:
    dir: "/foo" 
    file: "{{dir}}/config"
    foo: "{{host_entry.dir}}/foo"
    bar: "{{scripts_config.host_entry.dir}}/bar"

它们都不起作用。我一次尝试了filefoobar中的每一个:

  • file给出了任务包含一个带有未定义变量的选项。 错误是:“ dir”未定义
  • foo给出了任务包含一个带有未定义变量的选项。错误是:“ host_entry”未定义
  • bar给出了模板化时发生未处理的异常

有可能吗?

我的用例是我想要一个带有目录和几个文件的对象,这些目录和文件与默认设置中的相对。但是,如果您覆盖默认值,则可以为一个或多个文件指定完整路径,因此我不希望任务假定它是相对的。

2 个答案:

答案 0 :(得分:1)

不必自行引用变量来设置默认值。只需使用default filter

---
- hosts: localhost
  vars:
    file: "{{ dir | default ('/foo') }}/config" 
  tasks:
    - debug: var=file

您可以覆盖默认值:

$ ansible-playbook default.yml -e dir=/changed
PLAY [localhost] ***************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "file": "/changed/config"
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

或使用默认值:

$ ansible-playbook default.yml 
PLAY [localhost] ***************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "file": "/foo/config"
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

您也可以使用set_fact。您可以更改所有文件的基本目录,也可以更改每个文件的完整路径:

---
- hosts: localhost
  tasks:
    - set_fact: base="/foo"
      when: base is undefined
    - set_fact: file1={{base}}/file1
      when: file1 is undefined
    - set_fact: file2={{base}}/file2
      when: file2 is undefined
    - debug: var=file1
    - debug: var=file2

答案 1 :(得分:0)

当我想要这种东西时我通常会做什么:

View

正在将以下内容添加到角色/parent_dir/ ├── dirA/ ├── dirB/ ├── dirC/ └── dirD/

defaults

然后到parent_dir: /parent_dir/

vars

这样,您的“其他”目录/文件...将相对于other_dir_a: "{{ parent_dir }}/dirA" other_dir_b: "{{ parent_dir }}/dirB" other_dir_c: "{{ parent_dir }}/dirC" other_dir_d: "{{ parent_dir }}/dirD"

这与您想做的事情类似吗?

根据下面的评论进行更新

所有这些变量比角色变量更“重要”:

https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html

  • 阻止变量(仅适用于阻止任务)
  • 任务变量(仅用于任务)
  • include_vars
  • set_facts /已注册的变量
  • 角色(和include_role)参数
  • 包括参数
  • 额外的变量(总是优先)

您可以使用其中任何一个来替换。例如,使用额外的变量。

{{ parent_dir }}

如果要将它们全部用作默认值,则也可以将所有变量都放在ansible-playbook -i inventory playbook.yml -e other_dir_a=/new/path/for/a -e other_dir_b=/new/path/for/b下。它们处于最低优先级,因此可以用其他任何变量代替。