Amazon AWS EC2 + Puppet, get Puppet to know AWS instance tags
I am having a problem with my AWS deployment, fairly new to AWS and Puppet.
So coming to my question - can you distinguish puppet nodes with AWS machine tags or CNAME domains?
A little background about the plan:
- have multiple clusters of machines, one php cluster, one legacy php cluster, one java cluster, one perl cluster
- control configuration with puppet - still pretty new to puppet but as a developer I like the idea of being able to version control configuration of servers
- have autoscaling enabled on those clusters - obviously the main benefit of the cloud that makes the much hight cost when it comes to any reasonable performance worth it (those amazon machines are slower than my phone...)
- deployment controlled by Capistrano, this makes things a lot easier
So in AWS you get those super nasty public/private machine dns's... no way you can identify machines on those. In order to easer the problem, seams like AWS want's you to tag everything - so I did. Found a script that makes a CNAME record for each machine with the tag "ShortName" thanks to the Route53 API.
Every machine has a ShortName tag that becomes its CNAME, unfortunately puppet still resolves the private dns name.
I'd like to have
node 'perl-cluster'{}
in puppet, anyone any clue ho to achieve this?
Thanks
The way I've done it is to write a custom fact for the server to identify its role from user data, which can be accessed on 169.254.169.254, see your own user data...
AWS user-data documentation
curl http://169.254.169.254/latest/
so when I type facter role
ill get 'dbserver', 'webserver' whatever, then use that to define a node, its important not to have autoscaling groups care the slightest about what the name of the server is.
/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
I dont want to tell you exactly how to do it in your case, but here I'll show you how to create a custom fact to report the EC2 instance ID.
Facter, curl, are installed.
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
And lo, a custom fact was written.
Now I can use it to get the ec2 instance id:
$ facter instance_id
i-a1c0ffee
I dont have puppet installed on this machine, but if i wanted it available to puppet, id put in it /var/lib/puppet/lib/facter, and to distribute it to clients id ensure pluginsync=true in puppet.conf.
Bear in mind, all that ive said is highly subjective, its just how I do it, if theres a better way, I'd be interested.
As of facter 1.7 (released in April 2013), there are built-in facts that report various details of your EC2 instance.
Reference: http://docs.puppetlabs.com/facter/1.7/core_facts.html#ec2ec2-instance-data