Как сохранить переменную ansible в ролях 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}

как я могу получить доступ к переменным, зарегистрированным в отдельной роли, в той же игре?

Edit для ясности того, как вещи кусок вместе:

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 ответов


NB: это было написано со ссылкой на Ansible 1.X. Я подозреваю, что разбор переменных и область видимости значительно изменились с Ansible 2.0, поэтому имейте это в виду. Я попытаюсь обновить ответ, если у меня будет время (или, возможно, кто-то другой ответит за v2.0!)

есть два варианта. Проще всего определить переменные в вашем учебнике верхнего уровня, а затем распространить их на различные роли. Вы можете либо установить их как простые vars, либо использовать 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']}}"

как описано в этот бит ансибля docs.

обратите внимание, что если вы всегда хотите искать hostvars текущей машины, на которой вы выполняете команды (не зная, что это на самом деле называется в файле Ansible hosts), вы можете использовать переменную inventory_hostname вот так:

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

(обратите внимание на отсутствие кавычек, так как это переменная, а не строковый литерал.)

немного неудобно, но эти комбинации отвечают всем моим потребностям до сих пор.


попробуйте переместить объявления переменных в 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 }

расширить принятый вопрос.

1.- Вы можете определить другую роль, где вы регистрируете переменную, а затем установить ее там, а затем ссылаться на эту переменную из нескольких ролей. Пока роли в одной пьесе. Док здесь: http://docs.ansible.com/ansible/playbooks_variables.html#variable-examples

вообще говоря, переменные, установленные в одной роли доступны для других. Это означает, что у вас есть роли / common/vars / main.YML вы можете установите переменные там и используйте их в других ролях и в других местах в вашем playbook

Edit: уточнение, это относится к зарегистрированным и установленным переменным в 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 должен работать:

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


как abt передает его в качестве параметра роли. Я предполагаю, что такие (регистровые) переменные не передаются неявно (как hotvars).

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