Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm wondering how to go about spinning up multiple EC2 servers using knife of the same type, say 4 app servers, and assigning them each an elastic IP from a pool of available Elastic IPs. I have assigned EC2 servers elastic IP's using the ASW cookbook from OpsCode, and the usage instructions tell me to use a data bag to store the IP, but their instructions seem to only make sense when you have a single server that you are spinning up.

My ideal use case would be that I create my app-server cookbook, and in the recipe it pings the Chef server to find out an available elastic IP from a pool. I don't mind manually defining that pool, but I just can't seem to figure out how to remove IPs that are already taken from the pool, so that only available ones are dished out.

Any ideas?

share|improve this question

1 Answer 1

up vote 0 down vote accepted

Here's the answer I came up with:

#
# Cookbook Name:: app-server
# Recipe:: ec2
# 
include_recipe "aws" # http://community.opscode.com/cookbooks/aws

# Assign an Elastic IP to the node on first run
if node[:eip_address].nil?
  # I created two data bags, one for holding AWS credentials,
  # the other for holding on to my IP pool. I pass the names of the 
  # individual bags, in my case, via some environment attributes
  aws = data_bag_item("aws", node[:aws_setup][:credentials])
  eip = data_bag_item("elastic-ips", node[:aws_setup][:eip])

  ip_pool = eip["eip_pool"]

  # Search for servers, and remove used IPs from available list
  search(:node, "chef_environment:#{node.chef_environment} AND role:YOUR_SERVER_ROLE") do |matching_node|
    ip_pool.delete_if {|ip| ip == matching_node[:eip_address]}
  end

  # Attach IP (unless there are no more EIPs in the pool)
  if ip_pool.length <= 0
    Chef::Log.fatal("There are no more EIPs available. Please allocate more and add to the elastics-aps/#{node[:aws_setup][:eip]} data_bag")
  else
    aws_elastic_ip "eip-assignment" do
      aws_access_key aws['aws_access_key']
      aws_secret_access_key aws['aws_secret_access_key']
      ip ip_pool[0]
      action :associate
    end
    # Assign this new IP to the current node, and save
    node.set[:eip_address] = ip_pool[0]
    node.set[:ec2][:public_ipv4] = node[:eip_address]
    node.save
  end
end
share|improve this answer
    
Would you mind sharing the format with example content of the data-bags used here? –  Andrew De Andrade Oct 24 '13 at 18:55

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.