我怎样才能在不同的角色中保持一个可靠的变量?
How can I persist an ansible variable across ansible roles?
我在一个play里注册了一个变量
---
- 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}
如何在同一个游戏中访问在单独角色中注册的变量?
Edit for clarity of how things piece together:
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
如何将它作为参数传递给角色。我假设这样的(寄存器)变量没有隐式传递(就像 hotvars 一样)。
- { role: my_role, my_lb: "{{my_lb}}" }
尝试将您的变量声明移动到 pre_task
块中。此处设置的变量应在角色内和角色后可用。
https://docs.ansible.com/playbooks_roles.html#roles
例如
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 }
注意:这是参考 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']}}"
(注意缺少引号,因为它是一个变量,而不是字符串文字。)
有点尴尬,不过这些组合已经满足了我的所有需求。
Update: To access the variable using the hostvars syntax use the appropriate host GROUP variable rather than the host that executed the set_fact:
hostvars[inventory_hostname]['variable']
扩大已接受的问题。
1.-您可以在注册变量的地方定义另一个角色,然后在那里设置它,然后从多个角色引用该变量。只要角色在同一个剧中。
在这里记录:
http://docs.ansible.com/ansible/playbooks_variables.html#variable-examples
Generally speaking, variables set in one role are available to others. This means if you have a roles/common/vars/main.yml you can set variables in there and make use of them in other roles and elsewhere in your playbook
编辑:澄清,根据我的经验,这适用于在 Ansible 2.x 中注册和设置变量。
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 方法应该有效:
我在一个play里注册了一个变量
---
- 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}
如何在同一个游戏中访问在单独角色中注册的变量?
Edit for clarity of how things piece together:
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
如何将它作为参数传递给角色。我假设这样的(寄存器)变量没有隐式传递(就像 hotvars 一样)。
- { role: my_role, my_lb: "{{my_lb}}" }
尝试将您的变量声明移动到 pre_task
块中。此处设置的变量应在角色内和角色后可用。
https://docs.ansible.com/playbooks_roles.html#roles
例如
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 }
注意:这是参考 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']}}"
(注意缺少引号,因为它是一个变量,而不是字符串文字。)
有点尴尬,不过这些组合已经满足了我的所有需求。
Update: To access the variable using the hostvars syntax use the appropriate host GROUP variable rather than the host that executed the set_fact:
hostvars[inventory_hostname]['variable']
扩大已接受的问题。
1.-您可以在注册变量的地方定义另一个角色,然后在那里设置它,然后从多个角色引用该变量。只要角色在同一个剧中。 在这里记录: http://docs.ansible.com/ansible/playbooks_variables.html#variable-examples
Generally speaking, variables set in one role are available to others. This means if you have a roles/common/vars/main.yml you can set variables in there and make use of them in other roles and elsewhere in your playbook
编辑:澄清,根据我的经验,这适用于在 Ansible 2.x 中注册和设置变量。
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 方法应该有效: