5

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

3 Answers 3

8

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.

7
  • Ok, so do I need to have ec2 tools installed on each node (via puppet) to get tags or can I just get instance names via facter and then process them into tags before they will be used in puppetmaster ? Commented Jun 27, 2013 at 13:36
  • 1
    You dont need ec2 tools installed, you only need curl. You should learn how to write your own facts, really comes in handy http://docs.puppetlabs.com/guides/custom_facts.html Commented Jun 27, 2013 at 14:04
  • @PiotrJasiulewicz added description of custom fact creation. Commented Jun 27, 2013 at 14:45
  • Yes, found custom facts from my research, this all seams to be straight forward, but how do I go from having the instanceid in facter on the node, to having a tag name from the instance on pupeptmaster? If I have 20 instance id's still hard to classify on that. Commented Jun 28, 2013 at 10:26
  • 1
    Instance ID was used as an example of how to create a custom fact. Ammend the address curl uses to get something from user-data that you use to differential server type. Commented Jun 28, 2013 at 11:24
3

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

1
  • 1
    Tags seem to be missing from the available facts though. That's a shame as it seems none of the other facts are user-configurable. I guess we still can't use this as a makeshift ENC. Commented Apr 26, 2014 at 22:49
1

I agree with Sirch that at this point custom facts seem to be the way to go. AWS describe using Cloud formation facts at:

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

Which is an interesting, if difficult read. The custom fact from it is:

# 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 

They then configure their nodes like:

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

I'm more inclined to implement this via hiera like:

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

Then have something like common.yaml:

classes: cfn # or whatever your custom fact class is 

roles/dbserver.yaml:

classes: mysql 

roles/webserver.yaml:

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

Jeff

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.