it-swarm.com.ru

Передайте переменные Ansible из одной роли (запущенной на одном хосте) в другую роль, запущенную на другом хосте в той же книге воспроизведения

У меня есть книга воспроизведения, которая выполняет разные роли на разных хостах . Можно ли передать переменную из одной роли, выполняющейся на одном хосте, в другую роль на другом хосте, запущенном в рамках одной и той же серии воспроизведения? Или любой обходной путь?

playbook
   Host1
     role1
       here I get some variables: var1 var2 ...etc
   Host2
     role2
       here I need to use var1 var2 ... etc from the above Host/role

Задача в role1, которая устанавливает переменную db, выглядит следующим образом:

- Shell: cd /ACE/conf && grep ^db.url local1.properties | awk -F/ '{print $4}' | awk -F? '{print $1}'
  register: db

ОБНОВЛЕНИЕ: На первом хосте значения являются динамическими, это как файл конфигурации, который всегда обновляется. После того, как я сохраню значения в переменных на Host1 вместе с role1, я перехожу на Host2, запускаю role2 и выполняю действия с этими значениями из переменных, хранящихся в Host1. 

Я пробовал с hostvars:

{{ hostvars.LBL.db.stdout }}
{{ hostvars['LBL']['db'] }}
{{ hostvars['LBL']['db']['stdout'] }}

и я получаю ошибку:

in get_variables raise Exception("Host not found: %s" % hostname) Exception: Host not found: LBL

LBL существует в хостах, так как на нем я запускаю первую роль

Я установил переменную на одном хосте и хочу, чтобы эта переменная была доступна для другого хоста. Все это в одной книге. Это можно сделать?

hostvars не работает, используя это так:

---   
- name: test hostvars Host1
  hosts: LBL
  tasks:
    - command: "ls /bin"
        register: ls_out

- name: test hostvars Host2
  hosts: LM
  tasks:
    - debug:
        var: "{{ hostvars['LBL']['ls_out']['stdout'] }}"

ошибка:

fatal: [10.104.148.138] => Host not found: LBL

/ и т.д./анзибль/хостов

[[email protected] ansible]# cat /etc/ansible/hosts
[LBL]
10.104.148.136
[LM]
10.104.148.138
7
ady8531

Проблема в вашем инвентаре.

Это сообщение: 

fatal: [10.104.148.138] => Host not found: LBL

потому что LBL это группа, а не хост. В группе LBL есть один хост: 10.104.148.136

Выполните одно из следующих действий:

1. Измените свой инвентарь (/etc/ansible/hosts) на:

LBL ansible_ssh_Host=10.104.148.136
LM ansible_ssh_Host=10.104.148.138

2. или если вы действительно знаете, что делаете, и LBL - это группа, и вы хотите сохранить ее таким образом, то получите доступ к переменной с помощью:

{{ hostvars['10.104.148.136']['db']['stdout'] }}

Опять же, LBL - это группа, а не хост. Больше информации .

6
Kashyap

Эта тема сложна, и есть два разных ответа в зависимости от того, что вы хотите.

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

Пример:

---
- hosts: Host1
- roles:
    - role1
    - role2

Цель: вы хотите получить доступ к некоторой переменной из role1 внутри role2.

Используйте модуль set_fact.

Внутри роль1:

name: save precious value
set_fact: 
  pantsu: shiroi

Внутри role2:

name: Nozoki...
debug: msg="Color is {{pantsu}}"

Доступ к статической переменной для одного хоста (или группы) другому

Пример:

[group_foo]
Host1
Host2
[group_bar]
Host3
Host4

group_vars/group_foo

important_value=bla-bla-ba

Цель: вы хотите использовать его в playbook для group2.

Это гораздо сложнее. 

Внутри group_vars/group_bar

other_var: '{{hostvars[groups["group_foo"][0]].important_value}}'

Вы можете использовать другие индексы, кроме «0».

11
George Shuklin

Вот мое решение. Моя задача состояла в том, чтобы синхронизировать данные между двумя серверами, и я хотел передать имена серверов следующим образом: ansible-playbook sync.yaml -e "source = Host1 destination = Host2"

Вот основная пьеса:

---

- name: get_sync_facts
  hosts: "{{ source }}"
  roles:
    - set_sync_facts

- name: sync
  hosts: "{{ destination }}" 
  roles:
    - get_sync_facts
    - sync

Вот роль set_sync_facts:

---

- set_fact: src_media_dir='/some/dir/'
- set_fact: src_user='myuser'
- set_fact: src_Host='1.1.1.1'
- set_fact: src_port=12345
- set_fact: src_db_user='dbuser'
- set_fact: src_db_password='something'
- set_fact: src_db_name='some_db'

(Я действительно получил некоторые из них из задач, а другие из Host vars, но вы поняли)

А вот роль get_sync_facts:

---

- set_fact: src_media_dir={{ hostvars[source]['src_media_dir'] }}
- set_fact: src_user={{ hostvars[source]['src_user'] }}
- set_fact: src_Host={{ hostvars[source]['src_Host'] }}
- set_fact: src_port={{ hostvars[source]['src_port'] }}
- set_fact: src_db_user={{ hostvars[source]['src_db_user'] }}
- set_fact: src_db_password={{ hostvars[source]['src_db_password'] }}
- set_fact: src_db_name={{ hostvars[source]['src_db_name'] }}

Вы могли бы обойтись без этого и просто ссылаться на hostvars непосредственно в своих пьесах, но это, казалось, было проще поддерживать, поскольку оно напрямую соответствовало роли set_sync_facts. 

2
Andy Baker

это довольно старая тема, но, может быть, она кому-нибудь пригодится. Я использовал sed, чтобы получить имя хоста на основе "target", указанного в дополнительных параметрах.

Для использования этой «целевой» группы необходимо указать только 1 имя хоста.

Хозяева моего инвентаря:

[ansible_local]
localhost

[machine1]
machine1.domain.tld

upgrade_packages.yml

---
- hosts: '{{ target }}'
  Sudo: yes
  tasks:
  - name: check for Debian system
    Shell: /bin/false
    when: ansible_pkg_mgr != "apt"

  - name: full-upgrade all packages
    apt: update_cache=yes upgrade=full
    register: upgrade_result

- hosts: ansible_local
  tasks:
  - name: find out Host from target
    Shell: /bin/sed -n -e '/^\[{{ target }}\]$/,/^\[.*\]$/ { /^\[/d; /^$/d; p; }' {{ inventory_file }}
    register: target_inventory

  - name: Display all facts from target machine (change when to true if needed)
    debug: var=hostvars[target_inventory.stdout]
    when: false

  - name: Display upgrade result on ansible_local node
    debug: var=hostvars[target_inventory.stdout].upgrade_result.msg

Вызвать с помощью: ansible-playbook ./upgrade-packages.yml -e "target=machine1" -v

1
Quoing

У меня была похожая установка, где есть три хоста h1, h2, h3, и на каждом из них я хотел определить факт { "important_fact": "foo" } (и bar, и baz соответственно)

Чтобы получить список, содержащий все различные важные_факты на всех хостах, вы можете сделать это следующим образом:

- set_fact:
    important_facts_list: "{{ hostvars | json('*.important_fact') }}"
  run_once: yes
  delegate_to: h1

important_facts_list будет содержать [ 'foo', 'bar', 'baz' ], и теперь вы можете перебирать их, используя with_items.

0
Johannes Meixner