Переопределить переменную хоста из Ansible playbook из командной строки
Это фрагмент пьесы, которую я использую (server.yml
):
- name: Determine Remote User
hosts: web
gather_facts: false
roles:
- { role: remote-user, tags: [remote-user, always] }
Мой файл hosts имеет разные группы серверов, например
[web]
x.x.x.x
[droplets]
x.x.x.x
Теперь я хочу выполнить ansible-playbook -i hosts/<env> server.yml
и переопределить hosts: web
из server.yml
, чтобы запустить эту книгу для [droplets]
.
Могу ли я просто переопределить как одно время, без редактирования server.yml
напрямую?
Спасибо.
Ответы
Ответ 1
Я не думаю, что Ansible предоставляет эту функцию, которой она должна. Вот что вы можете сделать:
hosts: "{{ variable_host | default('web') }}"
и вы можете передать variable_host
из командной строки или из файла vars, например:
ansible-playbook server.yml --extra-vars "variable_host=newtarget(s)"
Ответ 2
Для тех, кто может найти решение.
Воспроизвести книгу
- hosts: '{{ host }}'
tasks:
- debug: msg="Host is {{ ansible_fqdn }}"
Инвентаризация
[web]
x.x.x.x
[droplets]
x.x.x.x
Команда: ansible-playbook deplyment.yml -i hosts --extra-vars "host=droplets"
Таким образом, вы можете указать имя группы в extra-vars
Ответ 3
Это немного поздно, но я думаю, вы могли бы использовать команду --limit or -l
, чтобы ограничить шаблон более конкретными хостами. (версия 2.3.2.0)
Вы могли бы
- hosts: all (or group)
tasks:
- some_task
а затем ansible-playbook playbook.yml -l some_more_strict_host_or_pattern
и используйте флаг --list-hosts
, чтобы узнать, на каких хостах будет применена эта конфигурация.
Ответ 4
Я использую другой подход, который не требует инвентаризации и работает с этой простой командой:
ansible-playbook site.yml -e working_host=myhost
Для этого вам нужна книга с двумя пьесами:
- Сначала игра запускается на локальном хосте и добавляется хост (из заданной переменной) в известную группу в инвентаре памяти.
- вторая игра проходит на этой известной группе
Рабочий пример (скопируйте его и запустите с помощью предыдущей команды):
- hosts: localhost
connection: local
tasks:
- add_host:
name: "{{ working_host }}"
groups: working_group
changed_when: false
- hosts: working_group
gather_facts: false
tasks:
- debug:
msg: "I'm on {{ ansible_host }}"
Я использую ANSIBLE 2.4.3 и 2.3.3
Ответ 5
Я изменил свой по умолчанию на отсутствие хоста, и у меня есть проверка, чтобы поймать его. Таким образом, пользователь или cron вынужден предоставлять один хост или группу и т.д. Мне нравится логика из комментария @wallydrag. empty_group
содержит хостов в инвентаре.
- hosts: "{{ variable_host | default('empty_group') }}"
Затем добавьте проверку в задачах:
tasks:
- name: Fail script if required variable_host parameter is missing
fail:
msg: "You have to add the --extra-vars='variable_host='"
when: (variable_host is not defined) or (variable_host == "")
Ответ 6
Мы используем простую задачу fail, чтобы заставить пользователя указать параметр ограничения Anaible limit option, чтобы мы не выполнялись на всех хостах по умолчанию/случайность.
Самый простой способ, который я нашел, это:
---
- name: Force limit
# 'all' is okay here, because the fail task will force the user to specify a limit on the command line, using -l or --limit
hosts: 'all'
tasks:
- name: checking limit arg
fail:
msg: "you must use -l or --limit - when you really want to use all hosts, use -l 'all'"
when: ansible_limit is not defined
run_once: true
Теперь мы должны использовать опцию -l
(= --limit
) при запуске playbook, например,
ansible-playbook playbook.yml -l www.example.com
Ограничить выбор документов:
Ограничение на один или несколько хостов. Это необходимо, если вы хотите запустить playbook против принимающей группы, но только против одного или нескольких участников эта группа.
Limit to one host
ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit "host1"
Limit to multiple hosts
ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit "host1,host2"
Отрицательный лимит.
ПРИМЕЧАНИЕ: одинарные кавычки ДОЛЖНЫ использоваться для предотвращения взлома интерполяция.
ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit 'all:!host1'
Limit to host group
ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit 'group1'
Ответ 7
Если вы хотите запустить задачу, связанную с хостом, но на другом хосте, попробуйте delegate_to.
В вашем случае вы должны делегировать свой localhost (незаменимый мастер) и вызывать команду ansible-playbook
Ответ 8
Просто наткнулся на эту поисковую систему для решения проблемы. На самом деле, есть один в Ansible 2.5. Вы можете указать свой файл инвентаризации с помощью --inventory
, например: ansible --inventory configs/hosts --list-hosts all
Ответ 9
Я использую ansible 2.5 (точно 2.5.3), и кажется, что файл vars загружается до выполнения параметра hosts. Таким образом, вы можете установить хост в файле vars.yml и просто написать hosts: {{ host_var }}
в вашей hosts: {{ host_var }}
Например, в моем playbook.yml:
---
- hosts: "{{ host_name }}"
become: yes
vars_files:
- vars/project.yml
tasks:
...
И внутри vars/project.yml:
---
# general
host_name: your-fancy-host-name
Ответ 10
Вот классное решение, которое я --limit
чтобы безопасно указать хосты с помощью опции --limit
. В этом примере воспроизведение закончится, если --limit
была выполнена без хостов, указанных с помощью опции --limit
.
Это было проверено на Ansible версии 2.7.10
---
- name: Playbook will fail if hosts not specified via --limit option.
# Hosts must be set via limit.
hosts: "{{ play_hosts }}"
connection: local
gather_facts: false
tasks:
- set_fact:
inventory_hosts: []
- set_fact:
inventory_hosts: "{{inventory_hosts + [item]}}"
with_items: "{{hostvars.keys()|list}}"
- meta: end_play
when: "(play_hosts|length) == (inventory_hosts|length)"
- debug:
msg: "About to execute tasks/roles for {{inventory_hostname}}"