[chef] Re: Setting up hosts between multiple boxes on EC2


Chronological Thread 
  • From: Haim Ashkenazi < >
  • To:
  • Subject: [chef] Re: Setting up hosts between multiple boxes on EC2
  • Date: Sun, 20 Nov 2011 17:40:25 +0200

Hi

I've actually implemented something like that with route53 (amazon't DNS service). For each important host (e.g, db) I've created a name (e.g. db.domain.com) and added it as CNAME to the host's internal address (this does not work between regions though). The reason I chose route53 was that I think (It's not yet checked) that It helps reduces TTL since I already query the amazon DNS. 

The update script looks like this:

#!/usr/bin/env ruby

NODENAME       = <%= %{'#{node.name}'} %>
HOSTNAME       = <%= %{'#{node[:ec2][:hostname]}'} %>
DOMAINNAME     = <%= %{'#{node[:company][:internal_domain]}'} %>
EC2_KEY_ID     = <%= %{' 'EC2_KEY_ID']}'} %>
EC2_SECRET_KEY = <%= %{' 'EC2_SECRET_KEY']}'} %>

require 'rubygems'
require 'right_aws'

module Route53Update
  extend self

  def r53
    @r53 ||= RightAws::Route53Interface.new(EC2_KEY_ID, EC2_SECRET_KEY)
  end

  def zone_id
    return @zone_id if @zone_id
    zone = r53.list_hosted_zones.select { |zone|
      zone[:name] =~ /^#{DOMAINNAME}\.?$/
    }.first
    @zone_id = zone ? zone[:aws_id] :
        raise("Zone #{DOMAINNAME} doesn't seem to be registered!")
  end

  def create_cname
    delete_cname
    resource_record_sets = [{
      :name             => NODENAME,
      :type             => 'CNAME',
      :ttl              => 300,
      :resource_records => [HOSTNAME]
    }]
    r53.create_resource_record_sets(zone_id, resource_record_sets, "")
  end

  def delete_cname
    r53.list_resource_record_sets(zone_id).each do |record|
      if record[:name] == "#{NODENAME}."
        r53.delete_resource_record_sets(zone_id, [record], "")
        break
      end
    end
  end

  def validate_cname
    res = r53.list_resource_record_sets(zone_id).select { |record|
      record[:name] =~ /#{NODENAME}\.?$/
    }.first
    res && res[:resource_records].include?(HOSTNAME) ? true : false
  end

  def update_cname
    return if validate_cname
    create_cname
    # TODO: validate sync!
  end
end

if $0 == __FILE__
  Route53Update.update_cname
end

You have to install right_aws gem and add an init script (so it'll run on boot). You can probably figure out the variables.

Using DNS helps with not having to restart application every time a host changes it IP, but you have to consider DNS caching (e.g, Java caches dns results depending on running environment).

HTH

Haim

On Sun, Nov 20, 2011 at 3:32 PM, Luis Correa d'Almeida < "> > wrote:
Let's say I provision two boxes on EC2: db1 and app1

What's the best way to make each box aware of the other? I need to
tell app1 the IP/host/FQDN of the db1 machine so it can connect to it.

One option is to use hosts in the config files - for example, in the
app1 box the config references a host (db1) that I can set up either
in the hosts file or in the local DNS. But I still wouldn't know the
IP of db1 to populate the hosts file with when running chef. At this
point, I need to change my data-bags once I find out the address of
db1 and then provision app1, running a recipe that adds the right
entry to the hosts file with the newly found db1 IP.

Just wondering if there is a better way.

Thanks,

Luis



--
Haim



Archive powered by MHonArc 2.6.16.

§