Замініть розміщення змінної програми відтворення Ansible з командного рядка


110

Це фрагмент ігрової книги, який я використовую ( server.yml):

- name: Determine Remote User
  hosts: web
  gather_facts: false
  roles:
    - { role: remote-user, tags: [remote-user, always] }

Мій файл хостів має різні групи серверів, наприклад

[web]
x.x.x.x

[droplets]
x.x.x.x

Тепер я хочу , щоб виконати ansible-playbook -i hosts/<env> server.ymlі перевизначити hosts: webз server.ymlзапустити цей збірник п'єс для [droplets].

Чи можу я просто переосмислити як одноразову річ, не редагуючи server.ymlбезпосередньо?

Дякую.

Відповіді:


128

Я не думаю, що Ansible надає цю функцію, якою вона повинна бути. Ось що ви можете зробити:

hosts: "{{ variable_host | default('web') }}"

і ви можете переходити variable_hostз командного рядка або з файлу vars, наприклад:

ansible-playbook server.yml --extra-vars "variable_host=newtarget(s)"

3
Потрібна невелика корекція. Це повинно бутиhosts: "{{ variable_host | default('web')}}"
— SPM

16
Ось зауваження, яке, на мою думку, завершить відповідь для чутливих новачків, які шукають це рішення: Приклад:ansible-playbook server.yml --extra-vars "variable_host=newtarget(s)"
— Frobbit

1
Коли (тобто в якому порядку) робить анзібль розбору змінних Змінні в , як group_vars/allвидається , бути розібраний після по hosts:лінії п'єс. Однак змінні в vars:і змінні в vars_files:синтаксичному рівні аналізуються перед hosts:рядком? ПРИМІТКА Я не прошу про перевагу.
— Феліпе Альварес

2
Ви також можете використовувати -eзамість цього --extra-vars.
— іменник

Подивіться інші відповіді для отримання більш детальної інформації
— Anand Varkey Philips

63

Для всіх, хто може прийти шукати рішення.
Слухати книгу

- 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" Отже, ви можете вказати назву групи в додатковій варі


2
Зверніть увагу, будьте обережні з назви вар. Я тестував це, використовуючи play_hostsі не отримуючи очікуваних результатів, бо забув, що play_hostsце внутрішня відповідна вар для всіх хостів у поточній грі.
— Райан Фішер

Я припускаю, що за замовчуванням слід встановити відповідь вище.
— каказ

19

Це трохи пізно, але я думаю, ви могли б скористатися --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прапор, щоб побачити, на яких хостах буде застосована ця конфігурація.


3
Я дуже новачок у службовій відповідальності, але вважаю це дуже ефективним рішенням, набагато більш компактним, ніж інші. Чому це було знято?
— Алессандро Дентелла

16
Це небезпечно. Якщо хтось забуде на limitсписок хостів, на які постраждали, іграшка може завдати великої шкоди.
— Олександр Щеблікін

3
Я вважаю, що використовувати так --extra-vars "variable_host=newtarget(s)"само, як прийняте рішення, настільки ж небезпечно і складніше рішення. Він використовує хости за замовчуванням, webякі можна застосувати і тут all. Ви можете використовувати сувору групу хостів за замовчуванням, щоб уникнути помилки та використовувати --list-hostsпрапор, щоб чітко розуміти, на яких хостів ви впливаєте.
— Джонатан Хамель

3
Рішення з додатковими параметрами дозволяє вказати порожню групу (або неіснуючу) як значення за замовчуванням. Тож якщо ви забудете надати змінну за допомогою командного рядка, нічого поганого не станеться. Рішення з опцією "--limit" є більш небезпечним, оскільки програвач не може використовувати порожню групу як значення за замовчуванням для хостів. Варіант "--llmit" застосовується до значень хостів, отже, він буде застосований до порожніх груп і забезпечить порожній результат. Таким чином, ВИ ВЖЕ використовувати "все" або інший не порожній хост як значення за замовчуванням. А коли-небудь ви забудете надати аргумент "--limit", і програму буде застосовано до всіх хостів.
— Григорій Петухов

4
Це має поєднуватися з відповіддю @ TmTron, щоб зрозуміти випадок, коли абонент не в --limitзмозі надати (інакше це вплине на всіх можливих хостів, що може бути не такою поведінкою, яку ви хочете)
— ncoghlan

14

Ми використовуємо просту невдалу задачу, щоб змусити користувача вказати відповідь опцію граничного рівня , щоб ми не виконувались на всіх хостах за замовчуванням / аварією.

Найпростіший спосіб я знайшов це:

---
- 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варіант) під час запуску ігрової книги, наприклад

ansible-playbook playbook.yml -l www.example.com

Обмеження опції, документи :

Обмеження до одного або декількох хостів Це потрібно, коли потрібно запустити програму "Книга" проти групи хостів, але лише проти одного або декількох членів цієї групи.

Обмежити до одного хоста

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit "host1"

Обмежити до кількох хостів

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit "host1,host2"

Негативний ліміт.
ПРИМІТКА: Одиничні лапки ОБОВ'ЯЗКОВО використовуватися для запобігання удару між інтерполяцією.

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit 'all:!host1'

Обмежити для приймаючої групи

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit 'group1'


7

Я використовую інший підхід, який не потребує інвентаризації, і працює з цією простою командою:

ansible-playbook site.yml -e working_host=myhost

Для цього вам потрібна книга з двома п’єсами:

  • Перша гра запускається на localhost і додає хост (із заданої змінної) у відому групу в запасному інвентарі
  • друга відома група проходить на цій відомій групі

Робочий приклад (скопіюйте його та запустіть його за допомогою попередньої команди):

- 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


7

Я змінив моє значення за замовчуванням на відсутність хоста і маю чек, щоб його зловити. Таким чином, користувач або крон змушений надавати єдиний хост або групу тощо. Мені подобається логіка з коментаря від @wallydrag. Theempty_group містить хостів в інвентарі.

- господарі: "{{varia_host | default ('empty_group')}}"

Потім додайте перевірку в завдання:

   завдання:
   - ім'я: Fail script, якщо необхідний параметр varia_host відсутній
     невдача:
       msg: "Вам потрібно додати --extra-vars = 'varia_host ='"
     коли: (змінний_хост не визначений) або (змінний_хост == "")

5

Щойно натрапив на цей гугл для пошуку рішення. Власне, у відповіді 2.5. Ви можете вказати свій інвентарний файл за допомогою --inventoryтакого:ansible --inventory configs/hosts --list-hosts all


Я вважаю, що це найправильніша відповідь у Рік Господа нашого 2019. Із Відповідь 2,8,4-х:-i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY specify inventory host path or comma separated host list. --inventory-file is deprecated
— pyansharp

3

Якщо ви хочете виконати завдання, пов’язане з хостом, але на іншому хості, спробуйте delegate_to .

У вашому випадку вам слід делегувати своєму локальному хосту (відповідальному майстру) та ansible-playbookкоманді виклику


2

Я використовую ansible 2.5 (саме 2.5.3), і здається, що файл vars завантажується до того, як буде виконаний парам хостів. Таким чином, ви можете встановити хост у файл vars.yml і просто записати 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

0

Ось круте рішення, яке я придумав, щоб безпечно вказати хостів через --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}}"

0

Іншим рішенням є використання спеціальної змінної, ansible_limitяка є вмістом параметра --limitCLI для поточного виконання Ansible.

- hosts: "{{ ansible_limit | default(omit) }}"

Якщо --limitпараметр опущено, то Ansible видає попередження, але нічого не робить, оскільки жоден хост не відповідає.

[WARNING]: Could not match supplied host pattern, ignoring: None

PLAY ****************************************************************
skipping: no hosts matched
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.