Как я могу установить переменные уровня 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"
быть истолкованным как правдивый.