Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
up vote 0 down vote accepted

Here's the answer I came up with:

# Cookbook Name:: app-server
# Recipe:: ec2
include_recipe "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]}

  # 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")
    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
    # 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]
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


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.