ansible делегат_то переменная не определена

#ansible #ansible-2.x

#ansible #ansible-2.x

Вопрос:

У меня проблема, когда я пытаюсь делегировать факты группе хостов. У меня есть главный узел, генерирующий значение, и я хочу убедиться, что моя группа «workers» имеет доступ к этому значению (вместо того, чтобы ориентироваться на master через hostname).

ansible 2.7.9 vagrant 2.2.4

VagrantFile

 ansible_groups = {
    "local" => [],
    "swarm" => [],
    "swarm-master-first" => [],
    "swarm-master" => [],
    "swarm-worker" => []
  }

  (1..num_masters).each do |i|
    ansible_groups["local"].push("swarm_master#{i}")
    ansible_groups["swarm"].push("swarm_master#{i}")
    if i == 1
      ansible_groups["swarm-master-first"].push("swarm_master#{i}")
    end
    ansible_groups["swarm-master"].push("swarm_master#{i}")
  end
  (1..num_workers).each do |i|
    ansible_groups["local"].push("swarm_worker#{i}")
    ansible_groups["swarm"].push("swarm_worker#{i}")
    ansible_groups["swarm-worker"].push("swarm_worker#{i}")
  end

  (1..num_masters).each do |i|
    config.vm.define "swarm_master#{i}" do |swarm_master|
      swarm_master.vm.network "private_network", ip: "192.168.50.1#{i}"
      swarm_master.vm.hostname = "swarmmaster#{i}"
      swarm_master.vm.provider :virtualbox do |vb|
          vb.name = "swarm-master#{i}"
      end
      swarm_master.vm.provision "ansible" do |ansible|
        ansible.playbook = "site.yml"
        ansible.become = true
        ansible.become_user = "root"
        ansible.groups = ansible_groups
      end
    end
  end

  (1..num_workers).each do |i|
    config.vm.define "swarm_worker#{i}" do |node|
      node.vm.network "private_network", ip: "192.168.50.2#{i}"
      node.vm.hostname = "swarmworker#{i}"
      node.vm.provider :virtualbox do |vb|
          vb.name = "swarm-worker#{i}"
      end
      node.vm.provision "ansible" do |ansible|
        ansible.playbook = "site.yml"
        ansible.become = true
        ansible.become_user = "root"
        ansible.groups = ansible_groups
      end
    end
  end
end

  

в результате инвентаризации:

 # Generated by Vagrant

swarm_master1 ansible_host=127.0.0.1 ansible_port=2222 ansible_user='vagrant' ansible_ssh_private_key_file='/Users/dmcminn/.vagrant.d/insecure_private_key'
swarm_worker1 ansible_host=127.0.0.1 ansible_port=2200 ansible_user='vagrant' ansible_ssh_private_key_file='/Users/dmcminn/.vagrant.d/insecure_private_key'

[local]
swarm_master1
swarm_worker1

[swarm]
swarm_master1
swarm_worker1

[swarm-master-first]
swarm_master1

[swarm-master]
swarm_master1

[swarm-worker]
swarm_worker1
  

playbook.yml

 - hosts: swarm-master-first
  tasks:
    - set_fact:
        swarm_token: "TEST"
      delegate_to: "{{ item }}"
      delegate_facts: True
      with_items: "{{ groups['swarm-worker'] }}"
    #- debug: var=swarm_token

- hosts: swarm-worker
  gather_facts: yes
  tasks:
    - debug: var=swarm_token
  

вывод

 PLAY [swarm-master-first] ******************************************************

TASK [set_fact] ****************************************************************
ok: [swarm_master1 -> 127.0.0.1] => (item=swarm_worker1)

...

PLAY [swarm-worker] ************************************************************

TASK [Gathering Facts] *********************************************************
ok: [swarm_worker1]

TASK [debug] *******************************************************************
ok: [swarm_worker1] => {
    "swarm_token": "VARIABLE IS NOT DEFINED!"
}
  

Что я здесь делаю не так?
Спасибо

Ответ №1:

Область действия переменной — это руководство к действию. Область действия переменной «swarm_token» — это 1-я пьеса. 2-я книга воспроизведения ничего не знает о «swarm_token».

Комментарии:

1. Хорошо, я, должно быть, неправильно понял использование этого тогда. Есть какие-нибудь предложения по выполнению того, что мне здесь нужно? т.е. одна группа генерирует некоторый вывод, я хочу, чтобы другая группа хостов использовала вывод в роли diff.

2. Одним из вариантов было бы сохранить общие переменные в файле (созданном, например, шаблонным модулем), а затем «include_vars», где это необходимо.

3. Я думаю, что моя проблема здесь заключается в том, что, как вы упомянули, vagrant выполняет ansible playbook отдельно в двух разных запусках. У вас есть какие-нибудь идеи, как сказать vagrant, чтобы он подождал, пока заработают все машины, а затем выполнил playbook один раз?

4. «ждать, пока все машины будут загружены» непрактично. Ansible — это скорее инструмент, определяющий состояние системы, чем процедурный язык. IIUIC вариантом было бы определить состояния «мастеров», а затем перейти к «рабочим». Лучшие практики могут помочь с некоторыми советами.