Amazon AWS EC2 + Puppet,让 Puppet 了解 AWS 实例标签

Amazon AWS EC2 + Puppet,让 Puppet 了解 AWS 实例标签

我在 AWS 部署中遇到了问题,因为对 AWS 和 Puppet 还不太熟悉。

所以回到我的疑问——您可以使用 AWS 机器标签或 CNAME 域来区分 puppet 节点吗?

关于该计划的一些背景:

  • 有多个机器集群,一个 php 集群,一个旧版 php 集群,一个 java 集群,一个 perl 集群
  • 使用 puppet 控制配置 - 对 puppet 来说仍然很新,但作为开发人员,我喜欢能够对服务器配置进行版本控制的想法
  • 在这些集群上启用了自动缩放 - 显然这是云的主要优势,当涉及到任何合理的性能时,它会产生更高的成本(那些亚马逊机器比我的手机还慢......)
  • 由 Capistrano 控制部署,这让事情变得简单很多

因此,在 AWS 中,您会得到那些超级讨厌的公有/私有机器 DNS……您无法识别这些机器。为了缓解这个问题,AWS 似乎希望您标记所有内容 - 所以我这样做了。借助 Route53 API,找到了一个脚本,该脚本为每台带有“ShortName”标签的机器创建 CNAME 记录。

每台机器都有一个 ShortName 标签作为其 CNAME,不幸的是 puppet 仍然解析私有 dns 名称。

我希望

node 'perl-cluster'{}

在 Puppet 中,有人知道如何实现这一点吗?

谢谢

答案1

我这样做的方法是为服务器编写一个自定义事实,以从用户数据中识别其角色,可以通过 169.254.169.254 访问,请参阅您自己的用户数据...

AWS 用户数据文档

curl http://169.254.169.254/latest/

所以当我输入时,facter role我会得到“dbserver”,“webserver”等等,然后用它来定义一个节点,重要的是不要让自动缩放组丝毫不关心服务器的名称是什么。

/etc/puppet/manifests/nodes.pp

node default{
  include nodes::type
}

/etc/puppet/modules/nodes/manifests/init.pp

import “type.pp”

/etc/puppet/modules/nodes/manifests/type.pp

class nodes::type{
   case $role {
     “dbserver” : {
       include mysql
     }
   }
   case $role {
      “webserver” : {
       include httpd
     }
   }
}

/etc/puppet/manifests/modules.pp

 import nodes

我不想告诉您在您的情况下具体该怎么做,但在这里我将向您展示如何创建自定义事实来报告 EC2 实例 ID。

Facter、curl 已安装。

mkdir -p /home/ec2-user/lib/ruby/facter
export FACTERLIB=/home/ec2-user/lib/ruby/facter

cat > /home/ec2-user/lib/ruby/facter/instance_id < EOF
# instance_id.rb
#
require 'facter'
Facter.add("instance_id") do
    setcode "/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id"
    end
EOF

瞧,一个自定义事实就被写下来了。

现在我可以用它来获取 ec2 实例 ID:

$ facter instance_id
i-a1c0ffee

我没有在这台机器上安装 puppet,但是如果我想让它可用于 puppet,我会把它放在 /var/lib/puppet/lib/facter 中,并将其分发给客户端,确保 puppet.conf 中的 pluginsync=true。

请记住,我所说的一切都非常主观,只是我做事的方式,如果有更好的方法,我会感兴趣。

答案2

从 facter 1.7(2013 年 4 月发布)开始,有内置事实可以报告您的 EC2 实例的各种详细信息。

参考:http://docs.puppetlabs.com/facter/1.7/core_facts.html#ec2ec2-instance-data

答案3

我同意 Sirch 的观点,目前看来,自定义事实似乎是可行的方法。AWS 描述了如何使用云形成事实:

https://s3.amazonaws.com/cloudformation-examples/IntegratingAWSCloudFormationWithPuppet.pdf

这篇文章很有趣,但读起来有些困难。其中的定制事实是:

# cfn.rb 
require 'rubygems' 
require 'json' 
filename = "/var/lib/cfn-init/data/metadata.json" 
if not File.exist?(filename) 
 return 
end 
parsed = JSON.load(File.new(filename)) 
parsed.default = Hash.new 
parsed[\"Puppet\"].each do |key, value| 
 actual_value = value 
 if value.is_a? Array 
  actual_value = value.join(',') 
 end 
 Facter.add(\"cfn_\" + key) do 
  setcode do 
   actual_value 
  end 
 end 
end

然后他们像这样配置他们的节点:

node basenode { 
 include cfn 
} 
node /^.*internal$/ inherits basenode { 
 case $cfn_roles {
   ...cloud formation include...
 } 
} 

我更倾向于通过 hiera 来实现这一点,例如:

---
:backends:
  - yaml
:yaml:
  :datadir: /etc/puppet/hiera
:hierarchy:
  - "roles/%{::cfn_roles}"
  - common

然后有类似 common.yaml 的内容:

classes: cfn # or whatever your custom fact class is

角色/dbserver.yaml:

classes: mysql

角色/webserver.yaml:

classes: httpd
httpd::port: 8080
...

杰夫

相关内容