Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial version

  • Loading branch information...
commit 65033387399b37e84732a693301f42183fe626be 1 parent 7492546
@jnewland jnewland authored
View
31 libraries/elb.rb
@@ -0,0 +1,31 @@
+module WebsterClay
+ module Aws
+ module Elb
+ def elb
+ @@elb ||= Fog::AWS::ELB.new(
+ :aws_access_key_id => new_resource.aws_access_key,
+ :aws_secret_access_key => new_resource.aws_secret_access_key,
+ :region => new_resource.region
+ )
+ end
+
+ def ec2
+ @@ec2 ||= Fog::Compute.new(:provider => 'AWS',
+ :aws_access_key_id => new_resource.aws_access_key,
+ :aws_secret_access_key => new_resource.aws_secret_access_key,
+ :region => new_resource.region
+ )
+ end
+
+ def load_balancer_by_name(name)
+ elb.describe_load_balancers.body["DescribeLoadBalancersResult"]["LoadBalancerDescriptions"].detect { |lb| lb["LoadBalancerName"] == new_resource.lb_name }
+ end
+
+ def availability_zone_for_instances(instances)
+ ec2.describe_instances('instance-id' => [*instances]).body['reservationSet'].map { |r| r['instancesSet'] }.flatten.map { |i| i['placement']['availabilityZone'] }
+ end
+
+ end
+ end
+end
+
View
29 metadata.json
@@ -0,0 +1,29 @@
+{
+ "dependencies": {
+ },
+ "name": "elb",
+ "maintainer_email": "jesse@websterclay.com",
+ "attributes": {
+ },
+ "license": "Apache 2.0",
+ "suggestions": {
+ },
+ "platforms": {
+ },
+ "maintainer": "Jesse Newland",
+ "long_description": "= DESCRIPTION:\n\n= REQUIREMENTS:\n\n= ATTRIBUTES: \n\n= USAGE:\n\n",
+ "version": "0.1.0",
+ "recommendations": {
+ },
+ "recipes": {
+ },
+ "groupings": {
+ },
+ "conflicting": {
+ },
+ "replacing": {
+ },
+ "description": "Configure Elastic Load Balancers at AWS",
+ "providing": {
+ }
+}
View
6 metadata.rb
@@ -0,0 +1,6 @@
+maintainer "Jesse Newland"
+maintainer_email "jesse@websterclay.com"
+license "Apache 2.0"
+description "Configure Elastic Load Balancers at AWS"
+long_description IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version "0.1"
View
138 providers/load_balancer.rb
@@ -0,0 +1,138 @@
+include WebsterClay::Aws::Elb
+
+# TODO: error handling
+# TODO: count instances in each zone and warn if not equal
+# TODO: warn if only one availability zone
+
+def load_current_resource
+
+ @current_lb = load_balancer_by_name(new_resource.lb_name)
+
+ @current_resource = Chef::Resource::ElbLoadBalancer.new(new_resource.lb_name)
+ @current_resource.lb_name(new_resource.lb_name)
+ @current_resource.aws_access_key(new_resource.aws_access_key)
+ @current_resource.aws_secret_access_key(new_resource.aws_secret_access_key)
+ @current_resource.region(new_resource.region)
+ @current_resource.listeners(new_resource.listeners)
+ @current_resource.timeout(new_resource.timeout)
+
+ if @current_lb
+ @current_resource.availability_zones(@current_lb['AvailabilityZones'])
+ @current_resource.instances(@current_lb['Instances'])
+ end
+ @current_resource.availability_zones || @current_resource.availability_zones([])
+ @current_resource.instances || @current_resource.instances([])
+
+ if new_resource.instances.nil? && new_resource.search_query
+ new_resource.instances(search(:node, new_resource.search_query).map { |n| n['ec2']['instance_id']})
+ end
+
+ all_zones = availability_zone_for_instances(new_resource.instances)
+ unique_zones = all_zones.compact.uniq
+
+ if new_resource.availability_zones.nil?
+ new_resource.availability_zones(unique_zones)
+ end
+end
+
+action :create do
+ ruby_block "Create ELB #{new_resource.lb_name}" do
+ block do
+ elb.create_load_balancer(new_resource.availability_zones, new_resource.lb_name, new_resource.listeners)
+ data = nil
+ begin
+ Timeout::timeout(new_resource.timeout) do
+ while true
+ data = load_balancer_by_name(new_resource.lb_name)
+ break if data
+ sleep 3
+ end
+ end
+ rescue Timeout::Error
+ raise "Timed out waiting for ELB data after #{new_resource.timeout} seconds"
+ end
+ node.set[:elb][new_resource.lb_name] = data
+ node.save if !Chef::Config.solo
+ end
+ action :create
+ not_if do
+ if data = load_balancer_by_name(new_resource.lb_name)
+ node.set[:elb][new_resource.lb_name] = data
+ node.save if !Chef::Config.solo
+ true
+ else
+ false
+ end
+ end
+ end
+ new_resource.updated_by_last_action(true)
+
+ instances_to_add = new_resource.instances - current_resource.instances
+ instances_to_delete = current_resource.instances - new_resource.instances
+
+ instances_to_add.each do |instance_to_add|
+ ruby_block "Register instance #{instance_to_add} with ELB #{new_resource.lb_name}" do
+ block do
+ elb.register_instances_with_load_balancer([instance_to_add], new_resource.lb_name)
+ node.set[:elb][new_resource.lb_name] = load_balancer_by_name(new_resource.lb_name)
+ node.save if !Chef::Config.solo
+ end
+ action :create
+ end
+ new_resource.updated_by_last_action(true)
+ end
+
+ instances_to_delete.each do |instance_to_delete|
+ ruby_block "Deregister instance #{instance_to_delete} from ELB #{new_resource.lb_name}" do
+ block do
+ elb.deregister_instances_from_load_balancer([instance_to_delete], new_resource.lb_name)
+ node.set[:elb][new_resource.lb_name] = load_balancer_by_name(new_resource.lb_name)
+ node.save if !Chef::Config.solo
+ end
+ action :create
+ end
+ new_resource.updated_by_last_action(true)
+ end
+
+ zones_to_add = new_resource.availability_zones - current_resource.availability_zones
+ zones_to_delete = current_resource.availability_zones - new_resource.availability_zones
+
+ zones_to_add.each do |zone_to_add|
+ ruby_block "Enabling Availability Zone #{zone_to_add} for ELB #{new_resource.lb_name}" do
+ block do
+ elb.enable_availability_zones_for_load_balancer([zone_to_add], new_resource.lb_name)
+ node.set[:elb][new_resource.lb_name] = load_balancer_by_name(new_resource.lb_name)
+ node.save if !Chef::Config.solo
+ end
+ action :create
+ end
+ new_resource.updated_by_last_action(true)
+ end
+
+ zones_to_delete.each do |zone_to_delete|
+ ruby_block "Disable Availability Zone #{zone_to_delete} for ELB #{new_resource.lb_name}" do
+ block do
+ elb.disable_availability_zones_for_load_balancer([zone_to_delete], new_resource.lb_name)
+ node.set[:elb][new_resource.lb_name] = load_balancer_by_name(new_resource.lb_name)
+ node.save if !Chef::Config.solo
+ end
+ action :create
+ end
+ new_resource.updated_by_last_action(true)
+ end
+
+end
+
+action :delete do
+ ruby_block "Delete ELB #{new_resource.lb_name}" do
+ block do
+ elb.delete_load_balancer(new_resource.lb_name)
+ node.set[:elb][new_resource.lb_name] = nil
+ node.save if !Chef::Config.solo
+ end
+ action :create
+ not_if do
+ !!!load_balancer_by_name(new_resource.lb_name)
+ end
+ end
+end
View
28 recipes/default.rb
@@ -0,0 +1,28 @@
+#
+# Cookbook Name:: elb
+# Recipe:: default
+#
+# Copyright 2011, Webster Clay, LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+r = gem_package "fog" do
+ action :nothing
+end
+
+r.run_action(:install)
+
+require 'rubygems'
+Gem.clear_paths
+require 'fog'
View
11 resources/load_balancer.rb
@@ -0,0 +1,11 @@
+actions :create, :delete
+
+attribute :lb_name, :kind_of => String, :name_attribute => true
+attribute :aws_access_key, :kind_of => String
+attribute :aws_secret_access_key, :kind_of => String
+attribute :region, :kind_of => String, :default => 'us-east-1'
+attribute :availability_zones, :kind_of => Array
+attribute :listeners, :kind_of => Array, :default => [{"InstancePort" => 80, "Protocol" => "HTTP", "LoadBalancerPort" => 80}]
+attribute :instances, :kind_of => Array
+attribute :search_query, :kind_of => String
+attribute :timeout, :default => 60
Please sign in to comment.
Something went wrong with that request. Please try again.