Я портирую некоторые сценарии автоматизации, которые использовали ansible со статическими инвентаризациями, чтобы использовать динамический инвентарь (у нас есть стек AWS Cloudformation для каждой среды, и кажется глупым обновлять статические файлы каждый раз, когда мы воссоздаем стек).
В каждом стеке есть один главный узел и несколько рабочих узлов. Чтобы различать мастера и рабочих в playbooks, я использую настраиваемый тег (например, tag_node_type_master
или tag_node_type_worker
) в качестве группы хостов (и используя --limit tag_env_XXX
ограничить одной конкретной средой).
Проблема возникает, когда мне нужно сообщить рабочим узлам, какой из них является их главным узлом. В настоящее время существует шаблон, который ссылается на статически определенную переменную с частным DNS-именем главного узла, и это больше не приемлемый вариант.
Я пытаюсь сделать что-то в разделе vars, например master_node: {{tag_node_type_master[0]}}
(выберите первый и единственный элемент этой группы хостов), но это не работает (в нем говорится, что переменная не определена, что имеет смысл, потому что это не переменная, а группа хостов).
Я не эксперт по Ansible, но хорошо знаком с AWS и другими системами управления конфигурацией. Я бы посоветовал сделать это:
1) Вы можете передать частный IP-адрес или DNS-имя главного узла в экземпляр EC2 с помощью свойства UserData экземпляра в шаблоне CloudFormation (http://is.gd/6cmsRt). Если вы хотите сделать его более общим, я бы поместил частный ELB перед вашим главным узлом, чтобы вам не приходилось заниматься изменениями IP-адресов или имен DNS, когда экземпляр, например, перезапущен. CloudFormation имеет встроенную функцию Fn::GetAtt
которые вы можете использовать для получения таких параметров (http://is.gd/slXkIE).
2) Я бы сохранил такие параметры UserData как локальные факты Ansible (Ansible> = 1.3, http://is.gd/QdZrUm). Фрагмент для UserData:
FACTS=/etc/ansible/facts.d/preferences.fact
echo [MasterNode] > $FACTS
echo Elb={ "Fn::GetAtt" : [ "MasterELB", "DNSName" ]} >> $FACTS
echo Dns={ "Fn::GetAtt" : [ "MasterInstance", "PrivateDnsName" ]} >> $FACTS
echo Ip={ "Fn::GetAtt" : [ "MasterInstance", "PrivateIp" ]} >> $FACTS
3) Я бы использовал такие пользовательские местные факты в ваших сценариях
{{ ansible_local.preferences.MasterNode.Elb }}
{{ ansible_local.preferences.MasterNode.Dns }}
{{ ansible_local.preferences.MasterNode.Ip }}
Это не полное решение. Вам по-прежнему нужна процедура для загрузки экземпляров EC2, создания каталога фактов и т. Д. Я использую аналогичную процедуру с SaltStack, и она хорошо работает. Любые комментарии приветствуются.