0

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?

1 Answer 1

0

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
1
  • Would you mind sharing the format with example content of the data-bags used here? Oct 24, 2013 at 18:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .