如何在 Ansible 中将 DNS 名称分配给变量?

如何在 Ansible 中将 DNS 名称分配给变量?

我正在移植一些使用带有静态库存的 ansible 的自动化脚本以使用动态库存(我们每个环境都有一个 AWS Cloudformation 堆栈,每次重新创建堆栈时更新静态文件似乎很愚蠢)。

每个堆栈有一个主节点和一组工作节点。为了在剧本中区分主节点或工作节点,我使用自定义标签(例如tag_node_type_mastertag_node_type_worker)作为主机组(并使用--limit tag_env_XXX限制到一个特定环境)。

当我需要让工作节点知道哪个是它们的主节点时,问题就出现了。目前有一个模板引用了一个静态定义的变量,其中包含主节点的私有 DNS 名称,这不再是一个可接受的选项。

我正在尝试在 vars 部分执行某些操作master_node: {{tag_node_type_master[0]}}(选择该主机组的第一个也是唯一的元素),但这不起作用(它说变量未定义,这是有道理的,因为它不是一个变量而是一个主机组)。

答案1

我不是 Ansible 专家,但我非常熟悉 AWS 和其他配置管理系统。我建议这样做:

1)您可以通过 CloudFormation 模板中的实例 UserData 属性将主节点私有 IP 地址或 DNS 名称传递给 EC2 实例(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 使用了类似的过程,效果很好。欢迎提出任何意见。

相关内容