#ansible
Вопрос:
У меня есть сценарий, в котором мне нужно проверить установки, версии и т. Д. В довольно большом кластере, собрать эти сведения и записать в файл на узле управления.Например java_version
, elasticsearch_version
и т. Д.
У меня есть динамический инвентарь ( ec2.py
), который я использую для сборника пьес. До сих пор я использовал blockinfile
. Кажется, это нормально работает только для одного узла, который выполняется последним (я использую serial:1
по одному узлу за раз). Как вы, ребята, решаете эту проблему? может быть, нужно создать что — то вроде dictionary
со всеми inventory_hostname
и назначить эти точки данных?
Вот учебник, который напоминает (концептуально .. синтаксис может иметь проблемы, потому что это просто пример кода, чтобы дать больше контекста)
---
- name: collect all the data points
hosts: tag_all_nodes
serial: 1
tasks:
- name: ES version
shell: 'dpkg -s elasticsearch | grep Version'
register: es_version
- name: java version
shell: 'java -version'
register: java_version
- name: write these data points on control node
blockinfile:
path: /path/to/myfile
block: |
details for machine {{ inventory_hostname }}
1. Elasticsearch version {{ es_version }}
2. Java version {{ java_version }}
delegate_to: localhost
Давайте предположим, что если у меня есть 3 узла, я должен ожидать чего-то подобного
details for machine node1
1. Elasticsearch version 7.12.0
2. Java version 1.8.0_181
details for machine node2
1. Elasticsearch version 7.12.0
2. Java version 1.8.0_181
details for machine node3
1. Elasticsearch version 7.12.0
2. Java version 1.8.0_181
но я вижу только
details for machine node3
1. Elasticsearch version 7.12.0
2. Java version 1.8.0_181
что вполне понятно. Как я могу получить желаемый результат (информацию обо всех 3 узлах, а не только об одном последнем узле)?
Ответ №1:
Вы повторно используете одно и то же значение по умолчанию marker
для своего blockinfile
, поэтому оно перезаписывается при каждом запуске, оставляя только последнее, как вы видели.
Просто измените маркер на что-то конкретное для каждого узла. Поскольку ваш файл, похоже, не соответствует какому-либо определенному формату, вы даже можете использовать его, чтобы избавиться от первой вводной строки блока, например
- name: write these data points on control node
blockinfile:
path: /path/to/myfile
marker: "{mark} details for machine {{ inventory_hostname }}"
block: |
1. Elasticsearch version {{ es_version }}
2. Java version {{ java_version }}
delegate_to: localhost
И результат должен быть:
BEGIN details for machine node1
1. Elasticsearch version 7.12.0
2. Java version 1.8.0_181
END details for machine node1
BEGIN details for machine node2
1. Elasticsearch version 7.12.0
2. Java version 1.8.0_181
END details for machine node2
BEGIN details for machine node3
1. Elasticsearch version 7.12.0
2. Java version 1.8.0_181
END details for machine node3
Между тем более чистым подходом в этом случае может быть использование шаблона. Вам не нужно создавать какой-либо диктант, у вас уже есть доступная hostvars
магическая переменная.
Шаблон templates/host_data_points.txt.j2
{% for host in group['tag_all_nodes'] %}
details for machine {{ hostvars[host].inventory_hostname }}
1. Elasticsearch version {{ hostvars[host].es_version }}
2. Java version {{ hostvars[host].java_version }}
{% endfor %}
Затем удалите свою последнюю задачу в вышеприведенной игре и добавьте еще одну игру:
#
# (your first play as above without last task goes here)
#
- name: Write data points to file
hosts: localhost
gather_facts: false
tasks:
- name: Template the data to file
template:
src: host_data_points.txt.j2
dest: /path/to/my_file
Вы даже можете расширить это последнее решение, передав группу и список переменных для динамической записи из задачи шаблона, если хотите.
Комментарии:
1. Это здорово. Спасибо.