Разные конфиги для разных хостов
TL;DR: в названии файлов конфигов можно указывать
inventory_hostname_short
, напримерtelegraf.myhost.conf
,_short
чтобы можно было в инвентаре делатьmyhost.this
иmyhost.that
, так как это удобно для разделения ssh-конфигов
Иногда бывает так, что нужно запускать один и тот же плейбук или одну и ту же роль для разных хостов, но чтобы у них были разные конфиги. Кастомизация содержимого конфига будет сильно зависеть от целей. Иногда достаточно прокинуть переменную из инвентаря или указать какой-нибудь флаг в defaults
и вручную менять его перед запуском.
Нас интересует полностью автоматический метод, поэтому остановимся на переменных инвентаря. Примеры написаны для Telegraf, этакий комбайн для сбора, обработки и отправки метрик.
Полностью рабочие примеры проектов можно найти тут: src/00_sources/06_tricks/01_host_specific_configs
. Запускается из папки с инвентарём с помощью ansible-playbook main.yml
.
Переменные инвентаря
Вот список файлов для этого подхода:
├── inventory
├── main.yml
└── roles
└── telegraf
├── defaults
│ └── main.yml
├── tasks
│ └── main.yml
└── templates
└── telegraf.conf.j2
Сначала рассмотрим инвентарь:
deb1 is_net_enabled=true
deb2
is_net_enabled=true
- это тот самый флаг, который поможет внутри шаблона конфига. Условно, будем считать что с одного хоста мы хотим собирать метрики сети (net
), а с другого нет.
Примечание: переменные инвентаря в таком виде будут в первой половине иерархии переменных и велика вероятность, что они перезапишутся из других мест, если указать где-то еще. Будьте внимательны.
И вот он в telegraf.conf.j2
, шаблоне, который рендерится в tasks/main.yml
:
{{ if is_net_enabled }}
# Read metrics about network interface usage
[[inputs.net]]
# no configuration
{{ endif }}
Проблема в том, что со временем конфиги могут сильно отличаться и if-чики в коде начнут сбивать с толку.
inventory_hostname_short
То есть нам по сути нужно как-то завязаться на переменную названия хоста.
Для этого сценария дерево файлов изменится лишь в templates/
:
└── templates
├── telegraf.deb1.conf.j2
└── telegraf.deb2.conf.j2
Возможно появился вопрос, почему именно _short
, а не обычный inventory_hostname
? Это небольшой хак, который позволяет указывать один и тот же хост, только с разными суффиксами. Например, это полезно, когда подключаешься к домашнему серваку дома через локальный IP, а когда на выезде - через какой-нибудь VPN. Так вот, _short
, как уже догадались, возьмёт часть до точки.
deb1.local ; -> deb1
deb1.vpn ; -> deb1
deb2 ; -> deb2
Интересный факт, в разделе Special variables в официальной доке Ansible про это не написано. Зато наглядно показано в этой статье.
И тогда в tasks/main.yml
можно написать так:
- name: Create telegraf configuration from template
template:
src: "templates/telegraf.{{ inventory_hostname_short }}.conf.j2"
dest: "{{ telegraf_directory }}/telegraf.conf"
На выходе получилось два независимых конфига на двух разных хостах.
Это не супер-масштабируемо, так как при добавлении нового хоста для него нужно будет добавлять ещё один конфиг. Зато явно и наглядно.