cf_deployer 1.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +29 -0
  3. data/ChangeLog.md +16 -0
  4. data/DETAILS.md +268 -0
  5. data/FAQ.md +61 -0
  6. data/Gemfile +10 -0
  7. data/Gemfile.lock +51 -0
  8. data/LICENSE +22 -0
  9. data/QUICKSTART.md +96 -0
  10. data/README.md +36 -0
  11. data/Rakefile +32 -0
  12. data/bin/cf_deploy +10 -0
  13. data/cf_deployer.gemspec +23 -0
  14. data/lib/cf_deployer/application.rb +74 -0
  15. data/lib/cf_deployer/application_error.rb +4 -0
  16. data/lib/cf_deployer/aws_constants.rb +3 -0
  17. data/lib/cf_deployer/cli.rb +111 -0
  18. data/lib/cf_deployer/component.rb +103 -0
  19. data/lib/cf_deployer/config_loader.rb +189 -0
  20. data/lib/cf_deployer/config_validation.rb +138 -0
  21. data/lib/cf_deployer/defaults.rb +10 -0
  22. data/lib/cf_deployer/deployment_strategy/auto_scaling_group_swap.rb +102 -0
  23. data/lib/cf_deployer/deployment_strategy/base.rb +88 -0
  24. data/lib/cf_deployer/deployment_strategy/blue_green.rb +70 -0
  25. data/lib/cf_deployer/deployment_strategy/cname_swap.rb +108 -0
  26. data/lib/cf_deployer/deployment_strategy/create_or_update.rb +57 -0
  27. data/lib/cf_deployer/driver/auto_scaling_group.rb +86 -0
  28. data/lib/cf_deployer/driver/cloud_formation_driver.rb +85 -0
  29. data/lib/cf_deployer/driver/dry_run.rb +27 -0
  30. data/lib/cf_deployer/driver/elb_driver.rb +17 -0
  31. data/lib/cf_deployer/driver/instance.rb +29 -0
  32. data/lib/cf_deployer/driver/route53_driver.rb +79 -0
  33. data/lib/cf_deployer/driver/verisign_driver.rb +21 -0
  34. data/lib/cf_deployer/hook.rb +32 -0
  35. data/lib/cf_deployer/logger.rb +34 -0
  36. data/lib/cf_deployer/stack.rb +154 -0
  37. data/lib/cf_deployer/status_presenter.rb +195 -0
  38. data/lib/cf_deployer/version.rb +3 -0
  39. data/lib/cf_deployer.rb +97 -0
  40. data/spec/fakes/instance.rb +32 -0
  41. data/spec/fakes/route53_client.rb +23 -0
  42. data/spec/fakes/stack.rb +65 -0
  43. data/spec/functional/deploy_spec.rb +73 -0
  44. data/spec/functional/kill_inactive_spec.rb +57 -0
  45. data/spec/functional_spec_helper.rb +3 -0
  46. data/spec/spec_helper.rb +8 -0
  47. data/spec/unit/application_spec.rb +191 -0
  48. data/spec/unit/component_spec.rb +142 -0
  49. data/spec/unit/config_loader_spec.rb +356 -0
  50. data/spec/unit/config_validation_spec.rb +480 -0
  51. data/spec/unit/deployment_strategy/auto_scaling_group_swap_spec.rb +435 -0
  52. data/spec/unit/deployment_strategy/base_spec.rb +44 -0
  53. data/spec/unit/deployment_strategy/cname_swap_spec.rb +294 -0
  54. data/spec/unit/deployment_strategy/create_or_update_spec.rb +113 -0
  55. data/spec/unit/deployment_strategy/deployment_strategy_spec.rb +29 -0
  56. data/spec/unit/driver/auto_scaling_group_spec.rb +127 -0
  57. data/spec/unit/driver/cloud_formation_spec.rb +32 -0
  58. data/spec/unit/driver/elb_spec.rb +11 -0
  59. data/spec/unit/driver/instance_spec.rb +30 -0
  60. data/spec/unit/driver/route53_spec.rb +85 -0
  61. data/spec/unit/driver/verisign_spec.rb +18 -0
  62. data/spec/unit/hook_spec.rb +64 -0
  63. data/spec/unit/stack_spec.rb +150 -0
  64. data/spec/unit/status_presenter_spec.rb +108 -0
  65. metadata +197 -0
@@ -0,0 +1,102 @@
1
+ module CfDeployer
2
+ module DeploymentStrategy
3
+ class AutoScalingGroupSwap < BlueGreen
4
+
5
+
6
+ def deploy
7
+ check_blue_green_not_both_active 'Deployment'
8
+ Log.info "Found active stack #{active_stack.name}" if active_stack
9
+ delete_stack inactive_stack
10
+ create_inactive_stack
11
+ swap_group
12
+ run_hook(:'after-swap')
13
+ Log.info "Active stack has been set to #{inactive_stack.name}"
14
+ delete_stack(active_stack) if active_stack && !keep_previous_stack
15
+ Log.info "#{component_name} deployed successfully"
16
+ end
17
+
18
+
19
+ def kill_inactive
20
+ check_blue_green_not_both_active 'Kill Inactive'
21
+ raise ApplicationError.new('Only one color stack exists, cannot kill a non-existant version!') unless both_stacks_exist?
22
+ delete_stack inactive_stack
23
+ end
24
+
25
+ def switch
26
+ check_blue_green_not_both_active 'Switch'
27
+ raise ApplicationError.new('Only one color stack exists, cannot switch to a non-existent version!') unless both_stacks_exist?
28
+ warm_up_cooled = true
29
+ swap_group warm_up_cooled
30
+ end
31
+
32
+ private
33
+
34
+
35
+ def check_blue_green_not_both_active action
36
+ active_stacks = get_active_asg(active_stack) + get_active_asg(inactive_stack)
37
+ raise BothStacksActiveError.new("Found both auto-scaling-groups, #{active_stacks}, in green and blue stacks are active. #{action} aborted!") if both_stacks_active?
38
+ end
39
+
40
+ def swap_group is_switching_to_cooled = false
41
+ is_switching_to_cooled ? warm_up_cooled_stack : warm_up_inactive_stack
42
+ cool_down_active_stack if active_stack && (is_switching_to_cooled || keep_previous_stack)
43
+ end
44
+
45
+ def keep_previous_stack
46
+ context[:settings][:'keep-previous-stack']
47
+ end
48
+
49
+ def create_inactive_stack
50
+ inactive_stack.deploy
51
+ get_parameters_outputs(inactive_stack)
52
+ run_hook(:'after-create')
53
+ end
54
+
55
+ def both_stacks_active?
56
+ active_stack && stack_active?(inactive_stack)
57
+ end
58
+
59
+
60
+ def warm_up_cooled_stack
61
+ group_ids(active_stack).each_with_index do |id, index|
62
+ min_max_desired = asg_driver(id).describe
63
+ asg_driver(group_ids(inactive_stack)[index]).warm_up_cooled_group min_max_desired
64
+ end
65
+ end
66
+
67
+ def cool_down_active_stack
68
+ group_ids(active_stack).each do |id|
69
+ asg_driver(id).cool_down
70
+ end
71
+
72
+ end
73
+
74
+
75
+ def stack_active?(stack)
76
+ return false unless stack.exists?
77
+ get_active_asg(stack).any?
78
+ end
79
+
80
+
81
+
82
+ def get_active_asg stack
83
+ return [] unless stack && stack.exists?
84
+ group_ids(stack).select do |id|
85
+ result = asg_driver(id).describe
86
+ result[:min] > 0 && result[:max] > 0 && result[:desired] > 0
87
+ end
88
+ end
89
+
90
+ def asg_driver name
91
+ @auto_scaling_group_drivers[name] ||= CfDeployer::Driver::AutoScalingGroup.new name
92
+ end
93
+
94
+ def asg_id_outputs
95
+ @context[:settings][:'auto-scaling-group-name-output']
96
+ end
97
+
98
+ class BothStacksActiveError < ApplicationError
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,88 @@
1
+
2
+ module CfDeployer
3
+ module DeploymentStrategy
4
+
5
+ def self.create application_name, environment_name, component_name, context
6
+ context[:'deployment-strategy'] ||= 'create-or-update'
7
+ strategy_class_name = 'CfDeployer::DeploymentStrategy::' + context[:'deployment-strategy'].split('-').map(&:capitalize).join
8
+ begin
9
+ eval(strategy_class_name).new application_name, component_name, environment_name, context
10
+ rescue
11
+ raise ApplicationError.new 'strategy_name: ' + strategy_class_name + ' not supported'
12
+ end
13
+ end
14
+
15
+ class Base
16
+ BLUE_GREEN_STRATEGY = true
17
+
18
+ attr_reader :context, :component_name, :application_name, :environment_name
19
+ def initialize(application_name, component_name, environment_name, context)
20
+ @application_name = application_name
21
+ @component_name = component_name
22
+ @environment_name = environment_name
23
+ @context = context
24
+ @auto_scaling_group_drivers = {}
25
+ end
26
+
27
+ def blue_green_strategy?
28
+ BLUE_GREEN_STRATEGY
29
+ end
30
+
31
+ protected
32
+
33
+ def stack_prefix
34
+ "#{@application_name}-#{@environment_name}-#{@component_name}"
35
+ end
36
+
37
+ def delete_stack(stack)
38
+ # Should this be stack.ready? Outputs won't exist if the stack is still starting.
39
+ unless stack.exists?
40
+ CfDeployer::Log.info "Skipping deleting stack #{stack.name} since it doesn't exist."
41
+ return
42
+ end
43
+ get_parameters_outputs stack
44
+ run_hook :'before-destroy'
45
+ stack.delete
46
+ end
47
+
48
+ def run_hook(hook_name)
49
+ CfDeployer::Driver::DryRun.guard "Skipping hook #{hook_name}" do
50
+ hook = Hook.new hook_name, context[hook_name]
51
+ hook.run context
52
+ end
53
+ end
54
+
55
+ def get_parameters_outputs(stack)
56
+ CfDeployer::Driver::DryRun.guard "Skipping get_parameters_outputs" do
57
+ context[:parameters] = stack.parameters
58
+ context[:outputs] = stack.outputs
59
+ end
60
+ end
61
+
62
+ def warm_up_inactive_stack
63
+ group_ids(inactive_stack).each_with_index do |id, index|
64
+ asg_driver(id).warm_up get_desired(id, index)
65
+ end
66
+ end
67
+
68
+ def get_desired(id, index)
69
+ group_id = active_stack ? group_ids(active_stack)[index] : id
70
+ asg_driver(group_id).describe[:desired]
71
+ end
72
+
73
+ def group_ids(stack)
74
+ return [] unless asg_id_outputs
75
+ asg_id_outputs.map { |id| stack.output id }
76
+ end
77
+
78
+ def asg_driver name
79
+ @auto_scaling_group_drivers[name] ||= CfDeployer::Driver::AutoScalingGroup.new name
80
+ end
81
+
82
+ def asg_id_outputs
83
+ @context[:settings][:'auto-scaling-group-name-output']
84
+ end
85
+
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,70 @@
1
+ module CfDeployer
2
+ module DeploymentStrategy
3
+ class BlueGreen < Base
4
+
5
+ def exists?
6
+ green_stack.exists? || blue_stack.exists?
7
+ end
8
+
9
+ def destroy
10
+ delete_stack green_stack
11
+ delete_stack blue_stack
12
+ end
13
+
14
+
15
+ def output_value(key)
16
+ active_stack ? active_stack.output(key) : "The value will be referenced from the output #{key} of undeployed component #{component_name}"
17
+ end
18
+
19
+ def status get_resource_statuses = false
20
+ my_status = {}
21
+ [blue_stack, green_stack].each do |the_stack|
22
+ my_status[the_stack.name] = {}
23
+ my_status[the_stack.name][:active] = stack_active?(the_stack)
24
+ my_status[the_stack.name][:status] = the_stack.status
25
+ my_status[the_stack.name][:resources] = the_stack.resource_statuses if the_stack.exists? && get_resource_statuses
26
+ end
27
+ my_status
28
+ end
29
+
30
+ private
31
+
32
+ def blue_stack
33
+ name = "#{stack_prefix}-B"
34
+ Stack.new(name, component_name, context)
35
+ end
36
+
37
+ def green_stack
38
+ name = "#{stack_prefix}-G"
39
+ Stack.new(name, component_name, context)
40
+ end
41
+
42
+ def both_stacks_exist?
43
+ blue_stack.exists? && green_stack.exists?
44
+ end
45
+
46
+ def active_stack
47
+ @active_stack = get_active_stack unless @active_stack_checked
48
+ @active_stack
49
+ end
50
+
51
+ def inactive_stack
52
+ @inactive_stack ||= get_inactive_stack
53
+ end
54
+
55
+ def get_inactive_stack
56
+ return blue_stack unless active_stack
57
+ stack_active?(green_stack) ? blue_stack : green_stack
58
+ end
59
+
60
+ def get_active_stack
61
+ @active_stack_checked = true
62
+ return green_stack if stack_active?(green_stack)
63
+ return blue_stack if stack_active?(blue_stack)
64
+ nil
65
+ end
66
+
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,108 @@
1
+ module CfDeployer
2
+ module DeploymentStrategy
3
+ class CnameSwap < BlueGreen
4
+
5
+ def deploy
6
+ Log.info "Found active stack #{active_stack.name}" if active_stack
7
+ delete_stack inactive_stack
8
+ create_inactive_stack
9
+ warm_up_inactive_stack
10
+ swap_cname
11
+ Kernel.sleep 60
12
+ run_hook(:'after-swap')
13
+ Log.info "Active stack has been set to #{inactive_stack.name}"
14
+ delete_stack(active_stack) if active_stack && !settings[:'keep-previous-stack']
15
+ Log.info "#{component_name} deployed successfully"
16
+ end
17
+
18
+
19
+ def kill_inactive
20
+ raise ApplicationError.new("Stack: #{inactive_stack.name} does not exist, cannot kill it.") unless inactive_stack.exists?
21
+ delete_stack inactive_stack
22
+ end
23
+
24
+ def switch
25
+ raise ApplicationError.new('There is only one color stack active, you cannot switch back to a non-existent version') unless both_stacks_exist?
26
+ swap_cname
27
+ Log.info "Active stack has been set to #{inactive_stack.name}"
28
+ Log.info "#{component_name} switched successfully"
29
+ end
30
+
31
+ private
32
+
33
+
34
+ def active_cname
35
+ @active_cname ||= get_active_cname
36
+ end
37
+
38
+
39
+
40
+ def create_inactive_stack
41
+ inactive_stack.deploy
42
+ get_parameters_outputs(inactive_stack)
43
+ run_hook(:'after-create')
44
+ end
45
+
46
+ def swap_cname
47
+ set_cname_to(inactive_stack)
48
+ end
49
+
50
+ def set_cname_to(stack)
51
+ cname, zone_id = find_elb_cname_for_stack(stack, elb_output_key)
52
+ dns_driver.set_alias_target(dns_zone, dns_fqdn, zone_id, cname)
53
+ end
54
+
55
+
56
+ def stack_active?(stack)
57
+ return false unless stack.exists?
58
+ return false unless active_cname.length > 0
59
+ cname, zone_id = find_elb_cname_for_stack(stack, elb_output_key)
60
+ active_cname.downcase == cname.downcase
61
+ end
62
+
63
+
64
+ def get_active_cname
65
+ dns_driver.find_alias_target(dns_zone, dns_fqdn) || ""
66
+ end
67
+
68
+
69
+ def elb_output_key
70
+ settings[:'elb-name-output']
71
+ end
72
+
73
+ def dns_fqdn
74
+ settings[:'dns-fqdn']
75
+ end
76
+
77
+ def dns_zone
78
+ settings[:'dns-zone']
79
+ end
80
+
81
+ def dns_driver
82
+ context[:dns_driver] || string_to_class(settings[:'dns-driver'])
83
+ end
84
+
85
+ def elb_driver
86
+ context[:elb_driver] || CfDeployer::Driver::Elb.new
87
+ end
88
+
89
+ def settings
90
+ context[:settings]
91
+ end
92
+
93
+ def find_elb_cname_for_stack(stack, elb_name_output_key)
94
+ return ['', ''] unless stack.exists?
95
+ elb_id = stack.output(elb_name_output_key)
96
+ attrs = elb_driver.find_dns_and_zone_id(elb_id)
97
+ [attrs[:dns_name] || '', attrs[:canonical_hosted_zone_name_id] || '']
98
+ end
99
+
100
+ def string_to_class class_string
101
+ class_string.split('::').inject(Object) do |mod, class_name|
102
+ mod.const_get(class_name)
103
+ end.new
104
+ end
105
+
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,57 @@
1
+ module CfDeployer
2
+ module DeploymentStrategy
3
+ class CreateOrUpdate < Base
4
+ BLUE_GREEN_STRATEGY = false
5
+
6
+ def exists?
7
+ stack.exists?
8
+ end
9
+
10
+ def status get_resource_statuses = false
11
+ my_status = {}
12
+ my_status[stack.name] = {}
13
+ my_status[stack.name][:status] = stack.status
14
+ my_status[stack.name][:resources] = stack.resource_statuses if stack.exists? && get_resource_statuses
15
+ my_status
16
+ end
17
+
18
+
19
+ def deploy
20
+ stack.deploy
21
+ warm_up_inactive_stack
22
+ get_parameters_outputs(inactive_stack)
23
+ run_hook(:'after-create')
24
+ end
25
+
26
+ def output_value(key)
27
+ exists? ? stack.output(key) : "The value will be referenced from the output #{key} of undeployed component #{component_name}"
28
+ end
29
+
30
+ def destroy
31
+ delete_stack stack
32
+ end
33
+
34
+ def kill_inactive
35
+ raise ApplicationError.new('There is no inactive version to kill for Create or Update Deployments.')
36
+ end
37
+
38
+ def switch
39
+ raise ApplicationError.new('There is no inactive version to switch to for Create or Update Deployments. Redeploy the version you want')
40
+ end
41
+
42
+ private
43
+
44
+ def stack
45
+ Stack.new(stack_prefix, @component_name, @context)
46
+ end
47
+
48
+ def inactive_stack
49
+ stack
50
+ end
51
+
52
+ def active_stack
53
+ nil
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,86 @@
1
+ module CfDeployer
2
+ module Driver
3
+ class AutoScalingGroup
4
+ extend Forwardable
5
+
6
+ def_delegators :aws_group, :auto_scaling_instances, :ec2_instances, :load_balancers
7
+
8
+ attr_reader :group_name, :group
9
+
10
+ def initialize name, timeout = CfDeployer::Defaults::Timeout
11
+ @group_name = name
12
+ @timeout = timeout
13
+ end
14
+
15
+ def describe
16
+ { desired: aws_group.desired_capacity, min: aws_group.min_size, max: aws_group.max_size }
17
+ end
18
+
19
+ def warm_up desired
20
+ return if desired < aws_group.min_size
21
+ desired = aws_group.max_size if desired > aws_group.max_size
22
+ Log.info "warming up auto scaling group #{group_name} to #{desired}"
23
+
24
+ CfDeployer::Driver::DryRun.guard "Skipping ASG warmup" do
25
+ aws_group.set_desired_capacity desired
26
+ wait_for_healthy_instance desired
27
+ end
28
+ end
29
+
30
+ def warm_up_cooled_group options
31
+ CfDeployer::Driver::DryRun.guard 'Skipping update of ASG min & max instance count' do
32
+ aws_group.update :min_size => options[:min], :max_size => options[:max]
33
+ end
34
+ warm_up options[:desired]
35
+ end
36
+
37
+ def cool_down
38
+ Log.info "Cooling down #{group_name}"
39
+ CfDeployer::Driver::DryRun.guard "Skipping ASG cooldown" do
40
+ aws_group.update :min_size => 0, :max_size => 0
41
+ aws_group.set_desired_capacity 0
42
+ end
43
+ end
44
+
45
+ def instance_statuses
46
+ instance_info = {}
47
+ ec2_instances.each do |instance|
48
+ instance_info[instance.id] = CfDeployer::Driver::Instance.new(instance).status
49
+ end
50
+ instance_info
51
+ end
52
+
53
+ private
54
+
55
+ def healthy_instance_count
56
+ count = auto_scaling_instances.count do |instance|
57
+ instance.health_status == 'HEALTHY' && (load_balancers.empty? || instance_in_service?( instance.ec2_instance ))
58
+ end
59
+ Log.info "Healthy instance count: #{count}"
60
+ count
61
+ end
62
+
63
+ def instance_in_service? instance
64
+ load_balancers.all? do |load_balancer|
65
+ load_balancer.instances.health.any? do |health|
66
+ health[:instance] == instance ? health[:state] == 'InService' : false
67
+ end
68
+ end
69
+ end
70
+
71
+ def wait_for_healthy_instance number
72
+ Timeout::timeout(@timeout){
73
+ while healthy_instance_count != number
74
+ sleep 15
75
+ end
76
+ }
77
+ end
78
+
79
+
80
+ def aws_group
81
+ @my_group ||= AWS::AutoScaling.new.groups[group_name]
82
+ end
83
+
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,85 @@
1
+ module CfDeployer
2
+ module Driver
3
+ class CloudFormation
4
+
5
+ def initialize stack_name
6
+ @stack_name = stack_name
7
+ end
8
+
9
+ def stack_exists?
10
+ aws_stack.exists?
11
+ end
12
+
13
+ def create_stack template, opts
14
+ CfDeployer::Driver::DryRun.guard "Skipping create_stack" do
15
+ cloud_formation.stacks.create @stack_name, template, opts
16
+ end
17
+ end
18
+
19
+ def update_stack template, opts
20
+ begin
21
+ CfDeployer::Driver::DryRun.guard "Skipping update_stack" do
22
+ aws_stack.update opts.merge(:template => template)
23
+ end
24
+ rescue AWS::CloudFormation::Errors::ValidationError => e
25
+ if e.message =~ /No updates are to be performed/
26
+ Log.info e.message
27
+ else
28
+ raise
29
+ end
30
+ end
31
+ end
32
+
33
+ def stack_status
34
+ aws_stack.status.downcase.to_sym
35
+ end
36
+
37
+ def outputs
38
+ aws_stack.outputs.inject({}) do |memo, o|
39
+ memo[o.key] = o.value
40
+ memo
41
+ end
42
+ end
43
+
44
+ def parameters
45
+ aws_stack.parameters
46
+ end
47
+
48
+ def query_output key
49
+ output = aws_stack.outputs.find { |o| o.key == key }
50
+ output && output.value
51
+ end
52
+
53
+ def delete_stack
54
+ if stack_exists?
55
+ CfDeployer::Driver::DryRun.guard "Skipping create_stack" do
56
+ aws_stack.delete
57
+ end
58
+ else
59
+ Log.info "Stack #{@stack_name} does not exist!"
60
+ end
61
+ end
62
+
63
+ def resource_statuses
64
+ resources = {}
65
+ aws_stack.resource_summaries.each do |rs|
66
+ resources[rs[:resource_type]] ||= {}
67
+ resources[rs[:resource_type]][rs[:physical_resource_id]] = rs[:resource_status]
68
+ end
69
+ resources
70
+ end
71
+
72
+ private
73
+
74
+ def cloud_formation
75
+ AWS::CloudFormation.new
76
+ end
77
+
78
+ def aws_stack
79
+ cloud_formation.stacks[@stack_name]
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,27 @@
1
+ module CfDeployer
2
+ module Driver
3
+ class DryRun
4
+
5
+ @@enabled = false
6
+
7
+ def self.enable
8
+ CfDeployer::Log.info "Enabling Dry-Run Mode"
9
+ @@enabled = true
10
+ end
11
+
12
+ def self.disable
13
+ CfDeployer::Log.info "Disabling Dry-Run Mode"
14
+ @@enabled = false
15
+ end
16
+
17
+ def self.guard description
18
+ if @@enabled
19
+ CfDeployer::Log.info "<Dry Run Enabled> #{description}"
20
+ else
21
+ yield
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ module CfDeployer
2
+ module Driver
3
+ class Elb
4
+ def find_dns_and_zone_id elb_id
5
+ elb = elb_driver.load_balancers[elb_id]
6
+ { :canonical_hosted_zone_name_id => elb.canonical_hosted_zone_name_id, :dns_name => elb.dns_name }
7
+ end
8
+
9
+ private
10
+
11
+ def elb_driver
12
+ AWS::ELB.new
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ module CfDeployer
2
+ module Driver
3
+ class Instance
4
+
5
+ GOOD_STATUSES = [ :running, :pending ]
6
+
7
+ def initialize instance_obj_or_id
8
+ if instance_obj_or_id.is_a?(String)
9
+ @id = instance_obj_or_id
10
+ else
11
+ @instance_obj = instance_obj_or_id
12
+ end
13
+ end
14
+
15
+ def status
16
+ instance_info = { }
17
+ [:status, :public_ip_address, :private_ip_address, :image_id].each do |stat|
18
+ instance_info[stat] = aws_instance.send(stat)
19
+ end
20
+ instance_info[:key_pair] = aws_instance.key_pair.name
21
+ instance_info
22
+ end
23
+
24
+ def aws_instance
25
+ @instance_obj ||= AWS::EC2.new.instances[@id]
26
+ end
27
+ end
28
+ end
29
+ end