Как я могу установить переменные уровня playbook в Ansible?

Я пытаюсь установить переменные в playbook так, чтобы они были доступны по всей остальной части playbook на уровне playbook, а не на уровне хоста. Пример (где machine_mode переменная передается из командной строки):

- name: configure and install everything for the new boxes
  sudo: True
  hosts: new_hosts
  vars: [
      docker_required_roles: "['app_server', 'other_app_server']",
      pip_required_roles: "['some_server', 'other_server']",
      docker_required: "{{ machine_mode }} in docker_required_roles",
      pip_required: "{{ machine_mode }} in pip_required_roles"
    ]
  pre_tasks:
  - name: Gathering ec2 facts
    action: ec2_facts
  roles:
  #install docker and pip when required
  - { role: bobbyrenwick.pip, when: "pip_required"}
  - { role: angstwad.docker_ubuntu, when: "docker_required"}

К сожалению, когда я запускаю это, он ломается с error while evaluating conditional: dev in pip_required_roles, Есть ли другой способ определить эти переменные, чтобы они были доступны через всю книгу?

2 ответа

Решение

Похоже, вы неправильно понимаете, куда падает ваша книга.

Ошибка говорит вам, что она не может оценить условие, которое вы наложили на роль пипа, когда вы передаете ей строковый литерал "dev in pip_required_roles" скорее, чем true или же false,

Вместо этого вам нужно заставить Ansible правильно оценить ваше условное выражение, чтобы получить логическое значение для вашей условной роли. Вы можете сделать это, изменив свой блок vars следующим образом:

- name: configure and install everything for the new boxes
  sudo: True
  hosts: all
  vars:
    - docker_required_roles: ['app_server', 'other_app_server']
    - pip_required_roles   : ['some_server', 'other_server']
    - docker_required      : machine_mode in docker_required_roles
    - pip_required         : machine_mode in pip_required_roles
  roles:
  #install docker and pip when required
  - { role: bobbyrenwick.pip, when: "pip_required"}
  - { role: angstwad.docker_ubuntu, when: "docker_required"}

Это изменяет ваши строковые литералы для docker_require_roles а также pip_required_roles переменные в списки, а затем docker_required а также pip_required переменные в условия, используя Python in оператор (обратите внимание на отсутствие двойных кавычек вокруг них).

В качестве незначительного замечания я также настроил блок vars, чтобы использовать синтаксис списка YAML, а не выбранный вами синтаксис в стиле Python, но это больше личное предпочтение, чем что-либо еще. Вы также можете разбить списки для docker_require_roles а также pip_required_roles переменные для использования синтаксиса YAML, как это, но по какой-то причине это выглядит немного более неловко для меня:

  ...
  vars:
    - docker_required_roles:
      - 'app_server'
      - 'other_app_server'
    - pip_required_roles   :
      - 'some_server'
      - 'other_server'
    - docker_required      : machine_mode in docker_required_roles
    - pip_required         : machine_mode in pip_required_roles
  roles:
    ...

Что касается более широкого представления о том, что вы связываете для достижения цели, то, похоже, вам лучше было бы делать это с различными файлами инвентаризации и групповыми переменными.

Эта переменная как булева вещь становится хитрой. Вот что я смог получить на работу:

vars:
  docker_required_roles: ['app_server', 'other_app_server']
  pip_required_roles: ['some_server', 'other_server']
  docker_required: '{{"{{machine_mode}}" in docker_required_roles}}'
  pip_required: '{{"{{machine_mode}}" in pip_required_roles}}'
tasks:
  - debug: var=pip_required
  - debug: var=pip_required
    when: '{{pip_required | bool}}'

Обратите внимание на списки строк имен ролей, просто используйте фактический YAML для их правильного обозначения, а не строку кода Python.

Для ссылок вам понадобятся дополнительные фигурные скобки вокруг него, чтобы получить ANSIBLE, чтобы выполнить его через jinja2 и оценить выражение "in" вместо того, чтобы просто оставить строку "dev in docker_required_roles",

При ссылке на переменную вы всегда должны помнить bool фильтр, чтобы избежать строки "False" быть истолкованным как правдивый.

Другие вопросы по тегам