如何在ansible角色中保留ansible变量?

时间:2015-03-27 16:15:44

标签: ansible

我在剧中注册了一个变量。

---
- hosts: 127.0.0.1
  gather_facts: no
  connection: local
  sudo: no
  vars_files:
    - vars.yml
  tasks:
    - name: build load balancer
      os_load_balancer: net=mc_net ext_net=vlan3320 name=load_balancer protocol=HTTPS port=80
      register: my_lb

我可以访问该变量,直到我在角色中发出请求。

例如,在同一次运行中的单独角色中,我想访问该注册变量:

- debug: var=my_lb

我得到以下输出:

{'msg': "AnsibleUndefinedVariable: One or more undefined variables: 'my_lb' is undefined", 'failed': True}

如何在同一个游戏中访问在单独角色中注册的变量?

  

编辑以清楚地了解事物的组合:

Top Play
-includes: 
  - Sub play 1
    - registers variable foo
  - Sub play 2
    -includes:
      - sub play A
        - role 1 
        - role 2
        - role 3 
          - references variable foo in template
      - Sub play B
  - Sub play 3

4 个答案:

答案 0 :(得分:5)

注意:这是指Ansible 1.X.我怀疑变量解析和范围已经与Ansible 2.0发生了很大的变化,所以请记住这一点。如果我有时间(或者其他人会回答v2.0,我会尝试更新答案)。

这里有两种选择。最简单的方法是在顶级剧本中定义变量,然后将它们传播到各种角色。您可以将它们设置为简单变量,也可以使用pre_tasks动态查找/计算值,例如

vars:
    foo_static: "value_bar"

pre_tasks:
    - set_fact:
        foo_ncpu: "{{ ansible_processor_vcpus }}"

  roles:
    - {role: role1, role1_var1: "{{foo_static}}", role1_var2: "{{foo_ncpu}}" }
    - {role: role2, role2_var1: "{{foo_static}}", role2_var2: "{{foo_ncpu}}" }

第二个选项要求您将任务添加到从中提取变量所需的任何角色(尽管因为所有ansible角色都是开源的,这应该很容易)。诀窍是使用set_fact将变量导出为'host_fact',例如

- name: Export role1_varfoo to a 'host-fact' type variable
  set_fact:
    role1_varfoo: "{{ role1_varfoo }}"

然后可以稍后访问:

  vars:
    role2_varfoo: "{{ hostvars['myhost']['role1_varfoo']}}"

this bit of the ansible docs中所述。

请注意,如果您始终要查找当前计算机的主机变量,而您正在运行命令(不知道它在ansible hosts文件中实际调用了什么),您可以使用变量inventory_hostname,如下所示:

  vars:
    role2_varfoo: "{{ hostvars[inventory_hostname]['role1_varfoo']}}"

(注意缺少引号,因为它是变量,而不是字符串文字。)

稍微尴尬,但到目前为止,这些组合已经满足了我的所有需求。

答案 1 :(得分:3)

尝试将变量声明移动到pre_task块中。此处设置的变量应在角色内和角色之后可用。

https://docs.ansible.com/playbooks_roles.html#roles

e.g。

pre_tasks:
    - name: build load balancer
      os_load_balancer: net=mc_net ext_net=vlan3320 name=load_balancer protocol=HTTPS port=80
      register: my_lb

roles:
  - { role: some_role }

答案 2 :(得分:3)

  

更新:要使用hostvars语法访问变量,请使用相应的主机GROUP变量,而不是执行set_fact的主机:

hostvars[inventory_hostname]['variable']

扩大已接受的问题。

1. - 您可以在注册变量的位置定义另一个角色,然后在那里设置它,然后从多个角色中引用该变量。因为角色在同一个游戏中。 在这里记录: http://docs.ansible.com/ansible/playbooks_variables.html#variable-examples

  

一般来说,在一个角色中设置的变量可供其他人使用。这意味着如果您有角色/ common / vars / main.yml,您可以在其中设置变量并在其他角色和游戏手册中的其他位置使用它们

编辑:澄清,根据我的经验,这适用于Ansible 2.x中的REGISTERED和set变量。

2.-就使用hostvars而言,我自己尝试过并因此错误而失败:

fatal: [localhost]: FAILED! => {"failed": true, "msg": "'dict object' has no attribute 'ec2_instance_id'"} 

我是我的情况我正在做以下事情。

- hosts: localhost
  gather_facts: yes
  roles:
  - { role: role_1 }
post_tasks:
- name: Check instance variables within localhost
  debug: var={{ hostvars['localhost']['ec2_instance_id'] }}

在角色1上我有:

- name: register instance_id
  set_fact: ec2_instance_id="{{ item.id }}"
  with_items: "{{ ec2_instance.instances }}"

虽然根据这个旧线程,hostvar方法应该可以工作:

https://github.com/ansible/ansible/issues/1934

答案 3 :(得分:0)

如何将它作为参数传递给角色。我假设这样的(寄存器)变量没有隐式传递(就像hotvars那样)。

- { role: my_role, my_lb: "{{my_lb}}" }