Ansible: (неожиданные) элементы hostvars всегда перезаписываются значениями для последнего хоста в группе во время цикла задач - PullRequest
0 голосов
/ 23 октября 2018

Я пытаюсь написать Ansible playbook, который выполняет несколько задач по настройке маршрутизаторов Cisco IOS.Некоторые из этих задач должны циклически перебирать переменные списка, которые определены на уровне файла переменных хоста.Например, для одного или нескольких интерфейсов настройте x на этом интерфейсе.Или, учитывая один или несколько fvrfs, настройте серверы имен для каждого fvrf.Количество интерфейсов и fvrfs являются динамическими.Есть несколько задач, которые имеют значения динамического списка, подобные этому, в роли playbook.

Проблема, с которой я сталкиваюсь, состоит в том, что переменные хоста с уникальными значениями для каждого маршрутизатора всегда устанавливаются в значения, определенные для последнегороутер в группе.Это происходит для переменных, которые являются строкой, и переменных, которые представляют собой список строк.Другими словами, hostvars маршрутизаторов, предшествующих последнему маршрутизатору в группе инвентаризации, всегда перезаписываются hostvars, определенными для последнего маршрутизатора.

Ansible Runtime:

$ ansible --version
ansible 2.7.0
  config file = /opt/ansible/ansible.cfg
  configured module search path = [u'/home/<redacted>/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/<redacted>/mypython/lib/python2.7/site-packages/ansible
  executable location = /home/<redacted>/mypython/bin/ansible
  python version = 2.7.15 (default, Oct 22 2018, 15:22:25) [GCC 4.4.7 20120313 (Red Hat 4.4.7-18)]
(A) (mypython) <redacted>@<redacted_hostname> /opt/ansible
$ ansible-playbook --version
ansible-playbook 2.7.0
  config file = /opt/ansible/ansible.cfg
  configured module search path = [u'/home/<redacted>/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/<redacted>/mypython/lib/python2.7/site-packages/ansible
  executable location = /home/<redacted>/mypython/bin/ansible-playbook
  python version = 2.7.15 (default, Oct 22 2018, 15:22:25) [GCC 4.4.7 20120313 (Red Hat 4.4.7-18)]

Структура каталогов:

+-- ansible.cfg
+-- inventory
|   +-- lab-g2
|   |   +-- group_vars
|   |   |   +-- lab-g2-crs-2900
|   |   |       +-- host_vars
|   |   |       |   +-- 10.74.0.71.yml
|   |   |       |   +-- 10.74.0.73.yml
|   |   |       +-- vars
|   |   +-- inventory
+-- library
+-- playbooks
|   +-- roles -> /opt/ansible/roles
|   +-- set-nameservers.yml
+-- README.md
+-- roles
|    +-- set-nameservers
    |   +-- tasks
    |       +-- main.yml

playbook.yml:

---

- name: CONFIGURE NAMESERVERS ON ROUTER
  hosts: all
  gather_facts: no
  connection: network_cli

  roles:
    - set-nameservers

Файл инвентаризации:

[lab-g2-crs-2900]
10.74.0.71
10.74.0.73

[all:children]
lab-g2-crs-2900

Файл групповых переменных:

---

ansible_connection: network_cli
ansible_network_os: ios

Переменная хостафайлы:

10.74.0.71.yml:

fvrf: ["WAN1", "WAN2"]
umbrella_out: ["GigabitEthernet0/0"]

10.74.0.73.yml:

fvrf: ["WAN3", "WAN4"]
umbrella_out: ["GigabitEthernet0/1"]

role / set-nameservers / tasks / main.yml

---
- name: CONFIGURE NAMESERVERS
  ios_config:
    lines:
      - "ip name-server vrf {{ item }} 208.67.220.220 208.67.222.222"
  with_items: "{{ fvrf }}"

- name: DEBUG
  debug:
    msg: "fvrf name is {{ item }}"
  with_items: "{{ fvrf }}"

- name: CONFIGURE UMBRELLA OUTBOUND INTERFACE
  ios_config:
    lines:
      - "description Outbound umbrella interface"
    parents: interface {{ item }}
  with_items: "{{ umbrella_out }}"

- name: DEBUG
  debug:
    msg: "Outbound Umbrella interface is {{ item }}"
  with_items: "{{ umbrella_out }}"

ОЖИДАЕМЫЙ РЕЗУЛЬТАТ

PLAY [CONFIGURE NAMESERVERS ON ROUTER] ***************************************************************************************************************************************

TASK [set-nameservers : CONFIGURE NAMESERVERS] *******************************************************************************************************************************
changed: [10.74.0.73] => (item=WAN3)
changed: [10.74.0.71] => (item=WAN1)
changed: [10.74.0.73] => (item=WAN4)
changed: [10.74.0.71] => (item=WAN2)

TASK [set-nameservers : DEBUG] ***********************************************************************************************************************************************
ok: [10.74.0.71] => (item=WAN3) => {
    "msg": "fvrf name is WAN1"
}
ok: [10.74.0.71] => (item=WAN4) => {
    "msg": "fvrf name is WAN2"
}
ok: [10.74.0.73] => (item=WAN3) => {
    "msg": "fvrf name is WAN3"
}
ok: [10.74.0.73] => (item=WAN4) => {
    "msg": "fvrf name is WAN4"
}

TASK [set-nameservers : CONFIGURE UMBRELLA OUTBOUND INTERFACE] ***************************************************************************************************************
changed: [10.74.0.73] => (item=GigabitEthernet0/0)
changed: [10.74.0.71] => (item=GigabitEthernet0/1)

TASK [set-nameservers : DEBUG] ***********************************************************************************************************************************************
ok: [10.74.0.71] => (item=GigabitEthernet0/1) => {
    "msg": "Outbound Umbrella interface is GigabitEthernet0/0"
}
ok: [10.74.0.73] => (item=GigabitEthernet0/1) => {
    "msg": "Outbound Umbrella interface is GigabitEthernet0/1"
}

PLAY RECAP *******************************************************************************************************************************************************************
10.74.0.71                : ok=4    changed=2    unreachable=0    failed=0
10.74.0.73                : ok=4    changed=2    unreachable=0    failed=0

АКТУАЛЬНЫЙ РЕЗУЛЬТАТ

PLAY [CONFIGURE NAMESERVERS ON ROUTER] ***************************************************************************************************************************************

TASK [set-nameservers : CONFIGURE NAMESERVERS] *******************************************************************************************************************************
changed: [10.74.0.73] => (item=WAN3)
changed: [10.74.0.71] => (item=WAN3)
changed: [10.74.0.73] => (item=WAN4)
changed: [10.74.0.71] => (item=WAN4)

TASK [set-nameservers : DEBUG] ***********************************************************************************************************************************************
ok: [10.74.0.71] => (item=WAN3) => {
    "msg": "fvrf name is WAN3"
}
ok: [10.74.0.71] => (item=WAN4) => {
    "msg": "fvrf name is WAN4"
}
ok: [10.74.0.73] => (item=WAN3) => {
    "msg": "fvrf name is WAN3"
}
ok: [10.74.0.73] => (item=WAN4) => {
    "msg": "fvrf name is WAN4"
}

TASK [set-nameservers : CONFIGURE UMBRELLA OUTBOUND INTERFACE] ***************************************************************************************************************
changed: [10.74.0.73] => (item=GigabitEthernet0/1)
changed: [10.74.0.71] => (item=GigabitEthernet0/1)

TASK [set-nameservers : DEBUG] ***********************************************************************************************************************************************
ok: [10.74.0.71] => (item=GigabitEthernet0/1) => {
    "msg": "Outbound Umbrella interface is GigabitEthernet0/1"
}
ok: [10.74.0.73] => (item=GigabitEthernet0/1) => {
    "msg": "Outbound Umbrella interface is GigabitEthernet0/1"
}

PLAY RECAP *******************************************************************************************************************************************************************
10.74.0.71                : ok=4    changed=2    unreachable=0    failed=0
10.74.0.73                : ok=4    changed=2    unreachable=0    failed=0

Как видно из выходного результатапеременные из файла хоста для 10.74.0.73 используются для обоих хостов, хотя 10.74.0.71 имеет свои собственные уникальные значения переменных, определенные в отдельном файле.В отдельной книге воспроизведения с той же структурой и 16 маршрутизаторами она показывала то же поведение ... используя hostvars последнего маршрутизатора в группе для всех 16 маршрутизаторов (yikes!)

Я искалв течение нескольких часов просматривал веб-страницы Ansible и много обсуждений, касающихся циклов, переменных и приоритета переменных.Я не понял, в чем проблема.Я думаю, что наиболее вероятный виновник в том, что я неправильно понимаю, как работает операция with_items, но я не знаю, как изменить задачи, чтобы обеспечить желаемый результат, когда у каждого хоста есть уникальные списки переменных.Может ли это быть ошибкой в ​​поведении?

Любая помощь в этом вопросе приветствуется!

1 Ответ

0 голосов
/ 23 октября 2018

Спасибо за публикацию каталога, это был ключ.Проблемы возникают не с with_items, а с вложенным host_vars в group_vars.

Если вы вытяните host_vars из каталога group_vars, он начнет себя вестиснова здраво.Я не копался в правилах назначения, чтобы выяснить точно , в какой момент он заменяется, но tl; dr состоит в том, что верхний сегмент не специфичен для хоста, хотянижнее ведро равно , таким образом:

hostvars["10.74.0.71"] = # the correct thing 
vars["lab-g2-crs-2900"] = {}
for h in ["10.74.0.71", ...etc...]:
   vars["lab-g2-crs-2900"].update(hostvars[h])
# and now the value in the group_vars "masks off" the host-specific one
# because they appear to be applied in reverse-depth-first order

Вы можете подтвердить это самостоятельно, не запуская всю пьесу, просто используя ansible-inventory --list и глядя на hostvars в _meta

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...