Проблемы с ansible 2.7.9 с использованием host_vars (неопределенная переменная)

#variables #ansible #host

#переменные #ansible #хост

Вопрос:

Ansible 2.7.9 не использует host_vars

Я настроил очень простую настройку с 3 хостами, в основном для целей тестирования. У меня есть хосты :

 - ansible1 (this is where I store the code)
- ansible2
- ansible3
  

Мой инвентарь :

 [ansible@ansible1 ~]$ cat /etc/ansible/hosts
[common]
ansible1
ansible2
ansible3
  

Мой cfg выглядит так :

 [ansible@ansible1 ~]$ cat /etc/ansible/ansible.cfg
[defaults]
roles_path = /etc/ansible/roles
inventory  = /etc/ansible/hosts
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
pipelining = True
control_path = /tmp/ansible-ssh-%%h-%%p-%%r
pipelining = False
[accelerate]
[selinux]
[colors]
  

Я определил основную программу под названием common, которая вызывает common :

 [ansible@ansible1 ~]$ ls /etc/ansible/roles/
common  common.retry  common.yml
[ansible@ansible1 ~]$ cat /etc/ansible/roles/common.yml
--- # Playbook for webservers
- hosts: common
  roles:
    - common
[ansible@ansible1 ~]$
  

Задача/main.yml :

 [ansible@ansible1 ~]$ cat /etc/ansible/roles/common/tasks/main.yml
- name: test ansible1
  lineinfile:
    dest: /tmp/ansible.txt
    create: yes
    line: "{{ myvar }}"
- name: set ansible2
  lineinfile:
    dest: /tmp/ansible2.txt
    create: yes
    line: "hi"
[ansible@ansible1 ~]$

[ansible@ansible1 ~]$ cat /etc/ansible/roles/common/vars/main.yml
copyright_msg: "Copyrighta 2019"
myvar: "value of myvar from common/vars"
  

Затем я разместил некоторую информацию в /etc /ansible/host_vars

 [ansible@ansible1 ~]$ ls /etc/ansible/hosts_vars/
ansible2.yml
[ansible@ansible1 ~]$ cat /etc/ansible/hosts_vars/ansible2.yml
myvar: "myvar from host_vars"
[ansible@ansible1 ~]$
  

Это отлично работает с playbook :

 [ansible@ansible1 ~]$ ansible-playbook /etc/ansible/roles/common.yml --limit ansible2

PLAY [common] ******************************************************************

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

TASK [common : test ansible1] **************************************************
changed: [ansible2]

TASK [common : set ansible2] ***************************************************
changed: [ansible2]

PLAY RECAP *********************************************************************
ansible2                   : ok=3    changed=2    unreachable=0    failed=0
  

Я вижу файл с содержимым myvar :

 [root@ansible2 ~]# cat /tmp/ansible.txt
value of myvar from common/vars
[root@ansible2 ~]#
  

Но тогда я не понимаю, почему он не принимает значение из / etc / ansible /hosts_vars/ansible2.yml, на самом деле, если я прокомментирую строку из /etc / ansible/roles /common /vars /main.yml, там будет указано неопределенная переменная :

 [ansible@ansible1 ansible]$ cat /etc/ansible/roles/common/vars/main.yml
copyright_msg: "Copyrighta 2019"
myvar: "value of myvar from common/vars"
  

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

1. Ansible 2.8.1: hosts_vars (множественное число) теперь отбрасывается как недопустимый. Работает только host_vars .

2. Да, это была просто опечатка, спасибо 🙂

Ответ №1:

Как и ожидалось, исходный файл main.yml будет получен автоматически при выполнении playbook. рассматривайте этот файл как глобальные переменные.

Причина, по которой ansible2.yml не получает исходный код, заключается в том, что ansible ожидает, что вы явно используете исходный код во время выполнения.

Для этого вы можете использовать приведенный ниже код (общий).

 ---
- name: play
  hosts: "{{ hosts }}"
  tasks:
    - include_vars: "{{ hosts }}.yml"
  

триггер —>

 ansible-playbook -i inventory --extra-vars "hosts=ansible2"
  

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

1. Спасибо за ответ , я понимаю, что вы говорите о суффиксе / расширении файла , я хотел бы спросить, какой файл был бы наиболее правильным для размещения include_vars ?

2. Поскольку вы будете передавать значение hosts в play во время выполнения на основе переменных хоста, я бы предложил использовать ту же переменную для include_vars: редактирование моего ответа

3. На самом деле я использую —limit ansible2 для вывода более удобного и понятного вывода, но я пытаюсь достичь чего-то похожего на то, что у меня было с puppet / hiera , я хочу значения по умолчанию из roles / vars (это работает), но я хочу получить, если мне нужны значения с уровня хоста (но я не хочу, чтобы они были на уровне CLI), чтобы заменить значения из roles / rolename / vars

4. ограничение используется для выполнения задач на одном хосте из группы хостов. Вы также можете использовать переменную hosts. Теперь, если одна и та же переменная объявлена в main.yml и ansible2.yml —> ansible2.yml будет иметь приоритет. подобно facter в puppet, у нас есть ansible facts, который собирает информацию для каждого хоста и может использоваться динамически.

5. Здравствуйте, я действительно ценю помощь здесь. На самом деле это не работает, я сделал то, что вы опубликовали: ОШИБКА! поле ‘hosts’ требуется, но не было установлено, я просто изменил masterplaybook, чтобы включить код: [ansible@ansible1 роли]$ cat /etc/ansible/roles/common.yml — # Playbook для веб-серверов — hosts: «{{ hosts }}» — задачи: — include_vars: «{{ hosts }}» роли: — общие [ansible@ansible1 роли] $

Ответ №2:

Ansible использует этот приоритет для значений из переменных :

 From least to most important
role defaults
inventory file or script group vars
inventory group_vars/all
playbook group_vars/all
inventory group_vars/*
playbook group_vars/*
inventory file or script host vars
inventory host_vars/*
playbook host_vars/*
host facts
play vars
play vars_prompt
play vars_files
role vars (defined in role/vars/main.yml)
block vars (only for tasks in block)
task vars (only for the task)
role (and include_role) params
include params
include_vars
set_facts / registered vars
extra vars (always win precedence)
  

Поэтому лучше забыть об использовании roles / vars, потому что он имеет приоритет над host_vars, поэтому я должен использовать вместо этого роли / значения по умолчанию, которые имеют более низкий приоритет.