Правильный способ выполнения задачи на хосте

#ansible #devops #administration

#ansible #devops #администрирование

Вопрос:

У меня есть инвентарь со следующими хостами, который приведен ниже (1-й кластер)

 [elasticsearch-cluster-india]
elasticsearch-01-mumbai ansible_host=10.0.87.19
elasticsearch-02-mumbai ansible_host=10.0.87.20
elasticsearch-03-mumbai ansible_host=10.0.87.21
 

и у меня другой кластер, который ниже

 [elasticsearch-cluster-kyrgyzstan]
elasticsearch-01-bishkek ansible_host=10.0.92.2
elasticsearch-02-bishkek ansible_host=10.0.92.3
elasticsearch-03-bishkek ansible_host=10.0.92.4
 

и я хочу выполнить следующую задачу

 - name: Set up snapshot cron job
  cron:
    name: "Elasticsearch backup"
    minute: 59
    hour: 23
    job: "{{ es_snapshot_snapshot_script_path }}/snapshot_es.sh"
 

итак, как выполнить эту задачу только на первых хостах в моей группе?
я хочу выполнить эту задачу только на хостах elasticsearch-01-bishkek и elasticsearch-01-mumbai

Ответ №1:

Добавьте переменную на хост:

 [elasticsearch-cluster-india]
elasticsearch-01-mumbai ansible_host=10.0.87.19 do_backup=yes
elasticsearch-02-mumbai ansible_host=10.0.87.20
elasticsearch-03-mumbai ansible_host=10.0.87.21
 

Затем проверьте это:

 - name: Set up snapshot cron job
  cron:
    name: "Elasticsearch backup"
    minute: 59
    hour: 23
    job: "{{ es_snapshot_snapshot_script_path }}/snapshot_es.sh"
  when: do_backup|default(false)|bool
 

Комментарии:

1. Я бы предложил when: do_backup|default(false)|bool

2. Простое замечание: это, безусловно, один из способов выполнить ваши требования. Есть несколько других (проверьте, что мы запускаемся на первом хосте в группе, добавьте определенную группу для «мастеров» ….). Так что это может быть правильным способом в вашей ситуации, но может быть не лучшим в других обстоятельствах.

Ответ №2:

Это все равно не будет исчерпывающим, но после моего комментария к ответу @anemyte я хотел добавить несколько альтернативных решений, чтобы проходящие мимо пользователи могли видеть, что есть разные способы выполнить одно и то же требование и сделать разумный выбор. Как указано в моем комментарии, решение @anemyte определенно работает и должно быть добавлено к приведенным ниже предложениям.

Примечания:

  • Я использовал простые задачи отладки для иллюстрации ниже, поскольку реальная задача, которую вы запускаете, на самом деле не имеет значения для ответа.
  • Я исправил имена групп, используя символы подчеркивания ( _ ), поскольку тире ( - ) устарели.
  • Я использовал термин «мастер» для описания первого хоста в группе. На самом деле это не адаптировано к архитектуре Elasticsearch, но я надеюсь, что вы все равно поймете суть.

Проверьте, запускаемся ли мы на первом хосте в группе

Цель здесь — динамически создать список, содержащий первый элемент каждой группы кластеров, и посмотреть, соответствует ли текущая цель. Я сделал это в одной задаче ниже, но вы можете легко расширить ее с vars помощью своей книги / инвентаря.

Это будет работать без каких-либо изменений в примере инвентаризации в вопросе (помимо фиксированного именования группы с использованием подчеркивания, как указано в моих заметках).

 - name: Run a task if host is first on a set of groups
  debug:
    msg: "I'm a host on top of a cluster group"
  var:
    cluster_groups:
      - elasticsearch_cluster_india
      - elasticsearch_cluster_kyrgyzstan
    first_hosts: "{{ cluster_groups | map('extract', groups) | map('first') | flatten }}"
  when: inventory_hostname in first_hosts
 

Реорганизуйте инвентарь с помощью специализированных групп

Здесь мы модифицируем инвентарь, чтобы добавить «основные» серверы в определенные группы. Инвентарь, который я предлагаю, является простым примером и может быть настроен для конкретных нужд. Пример в формате yaml

 ---
elasticsearch_cluster_india_masters:
  hosts:
    elasticsearch-01-mumbai:
      ansible_host: 10.0.87.19

elasticsearch_cluster_india_clients:
  hosts:
    elasticsearch-02-mumbai:
      ansible_host: 10.0.87.20
    elasticsearch-03-mumbai:
      ansible_host: 10.0.87.21

elasticsearch_cluster_india:
  children:
    elasticsearch_cluster_india_masters:
    elasticsearch_cluster_india_clients:


elasticsearch_cluster_kyrgyzstan_masters:
  hosts:
    elasticsearch-01-bishkek:
      ansible_host: 10.0.92.2

elasticsearch_cluster_kyrgyzstan_clients:
  hosts:
    elasticsearch-02-bishkek:
      ansible_host: 10.0.92.3
    elasticsearch-03-bishkek:
      ansible_host: 10.0.92.4

elasticsearch_cluster_kyrgyzstan:
  children:
    elasticsearch_cluster_kyrgyzstan_masters:
    elasticsearch_cluster_kyrgyzstan_clients:

elasticsearch_cluster_masters:
  children:
    elasticsearch_cluster_india_masters:
    elasticsearch_cluster_kyrgyzstan_masters:

elasticsearch_cluster_clients:
  children:
    elasticsearch_cluster_india_clients:
    elasticsearch_cluster_kyrgyzstan_clients:

elasticsearch_cluster:
  children:
    elasticsearch_cluster_masters:
    elasticsearch_cluster_clients:
 

Тогда у вас будет гораздо больше детализации в вашем учебнике:

 ---
- name: A play on all cluster hosts
  hosts: elasticsearch_cluster
  gather_facts: false

  tasks:
    - name: A task played on all hosts
      debug:
        msg: "Task played on all hosts"

    - name: A task played on masters only
      debug:
        msg: "I will play on masters only"
      when: inventory_hostname in groups['elasticsearch_cluster_masters']

- name: A play targeted to cluster masters only
  hosts: elasticsearch_cluster_masters
  gather_facts: false

  tasks:
    - name: A task for all master hosts
      debug:
        msg: "I don't need a when since play targets masters only"

    - name: An other tasks for masters only
      debug:
        msg: "Yet an other task"