ошибка неопределенной переменной в ansible при использовании шаблонов jinja2 - PullRequest
1 голос
/ 17 июня 2020

Практикую ansible. Я прошел весь путь через basi c и теперь работаю над созданием шаблона jinja2 и его использованием. Есть упражнение, когда мне нужно построить отчет для групп и загрузить их на соответствующий DNS-сервер. Отчеты для всех серверов в американской группе будут загружены на dns_server_america, аналогично для Азии.

dns_server_america ansible_host=172.20.1.100 ansible_ssh_pass=Passw0rd ansible_user=root
dns_server_asia ansible_host=172.20.1.101 ansible_ssh_pass=Passw0rd ansible_user=root

[america]
web0001 ansible_hostname=web0001.company.com ansible_host=10.1.1.101 
web0002 ansible_hostname=web0002.company.com ansible_host=10.1.1.102 


[asia]
web2001 ansible_hostname=web2001.company.com ansible_host=10.1.1.201 
web2002 ansible_hostname=web2002.company.com ansible_host=10.1.1.202 

Это YAML.

- name: Generate dns hosts files on americas servers
  hosts: dns_server_america
  tasks:
  - template: src=templates/hosts.j2 dest=/tmp/hosts.txt
    vars:
      GROUP_NAME: america

- name: Generate dns hosts files on asia servers
  hosts: dns_server_asia
  tasks:
  - template: src=templates/hosts.j2 dest=/tmp/hosts.txt
    vars:
      GROUP_NAME: asia

Это шаблон jinja2.

{% for host in groups[GROUP_NAME] %}
{{ host }} {{ hostvars[host]['ansible_host'] }}
{% endfor %}

Почему мы не цитируем [host] и [GROUP_NAME] в шаблоне jinja2. Ansible говорит, что когда переменные помещаются в квадратные скобки, они должны быть заключены в кавычки. Когда я заключаю это в кавычки, я получаю сообщение об ошибке «undefined variable», и когда я удаляю кавычки, я могу успешно запустить playbook. Сообщите, пожалуйста, мне что-то не хватает или моя теория понимания переменных может быть неправильной.

1 Ответ

0 голосов
/ 17 июня 2020

Q: «Почему мы не цитируем [host] и [GROUP_NAME] в шаблоне jinja2?»

A: Оба host и GROUP_NAME - переменные. Значение переменных необходимо в индексе. Если имена переменных заключены в кавычки 'host' или 'GROUP_NAME' , имена переменных используются вместо значений переменных.


Прямое и косвенное

Например, шаблон

shell> cat test.txt.j2
{{ dict[index] }}
{{ dict['index'] }}

и playbook

shell> cat playbook.yml
- hosts: localhost
  vars:
    dict:
      index: value of attribute index
      attr1: value of attribute attr1
  tasks:
    - template:
        src: test.txt.j2
        dest: test.txt
      vars:
        index: attr1

дают

shell> cat test.txt
value of attribute attr1
value of attribute index

Это не ограничивается шаблонами. В целом это действительно так. Например,

    - debug:
        msg:
          - "{{ dict[index] }}"
          - "{{ dict['index'] }}"
      vars:
        index: attr1

дает

  msg:
  - value of attribute attr1
  - value of attribute index

Пунктирный

Можно использовать «пунктирную» ссылку. Например,

    - debug:
        var: dict.index

дает

  dict.index: value of attribute index

«Пунктирная» ссылка может использоваться во вложенных словарях. Например, с вложенным словарем

    dict:
      index:
        var1: value of attribute index
      attr1:
        var1: value of attribute attr1

обе версии работают должным образом

    - debug:
        msg:
          - "{{ dict.index.var1 }}"
          - "{{ dict['index'].var1 }}"
      vars:
        index: attr1

дает

  msg:
  - value of attribute index
  - value of attribute index

Пунктирные ссылки в шаблоне

Но есть разница, когда используется шаблон. Когда ссылка помещается в квадратные скобки [], все последующие ссылки также должны быть помещены в квадратные скобки. В противном случае шаблон выйдет из строя. Например,

shell> cat test.txt.j2
{{ dict.index.var1 }}        # OK
{{ dict.index['var1'] }}     # OK
{{ dict['index']['var1'] }}  # OK
{{ dict['index'].var1 }}     # WRONG: has no attribute var1

не удастся

fatal: [localhost]: FAILED! => changed=false 
  msg: 'AnsibleUndefinedVariable:
        ''ansible.parsing.yaml.objects.AnsibleUnicode object''
        has no attribute ''var1'''
...