deployee 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 654aada1c37b70ee8685f7b8195b4e4afa575c65
4
+ data.tar.gz: 1c55894ad2160eca2c34cc2bb0ff4681473e4cbb
5
+ SHA512:
6
+ metadata.gz: ce5df9a66009289ff36c38dd53f6b693c64cf5f3e4e01b89fdef033c10487e04f89e5795a831a9e7d3ed5bddcf85c33a90c0279dcf65db1fb19413fed3b14ec9
7
+ data.tar.gz: 6319b2905e009353fea5606b1f3c6122d13d9bd801f5d802d2ef4fbeb05c84292421696f807a4fa9627d701bf908c54cdb3389317615829e4ea2a5c1754146ed
@@ -0,0 +1,62 @@
1
+ # Deployee
2
+
3
+ A tool to simplify deployments using AWS auto scaling engine.
4
+
5
+ ![MIT](https://octodex.github.com/images/constructocat2.jpg)
6
+
7
+ ## How it works?
8
+
9
+ #### How deployments should work?
10
+ The autoscaling engine allows us a new concept of deployment.
11
+ Basically we promote a new version of an application. When a new instance of an AMI is created, during setup, the latest version of the promoted application is installed on this machine via script.
12
+ In this model, the concept of deployment is only renew existing machines of a group of scalability.
13
+
14
+ #### How the deployment is done (here the magic happens)
15
+ We assume that the issue of promotion and setup is already solved in the setup of AMI.
16
+ This tool helps you to renew all instances of a scale group.
17
+ There are several ways to renew instances. We call these ways of strategies. Below is a list of the available strategies. Feel the urge to create your own strategy and send us a pull request.
18
+
19
+
20
+ * [At Least One](https://github.com/robsonbittencourt/deployee/wiki/At-Least-One)
21
+ * [Blackout](https://github.com/robsonbittencourt/deployee/wiki/Blackout)
22
+ * [Computing Preserve](https://github.com/robsonbittencourt/deployee/wiki/Computing-Preserve)
23
+ * [Double Capacity](https://github.com/robsonbittencourt/deployee/wiki/Double-Capacity)
24
+
25
+ ## Setup
26
+ Install bundle `gem install bundle`
27
+
28
+ Run `bundle install` command to install dependencies listed on `Gemfile`
29
+
30
+ [Configure AWS credentials](http://docs.aws.amazon.com/AWSSdkDocsRuby/latest/DeveloperGuide/ruby-dg-setup.html#set-up-creds)
31
+
32
+ ## Running
33
+ Execute deploy.rb passing as argument the name of the auto scaling group.
34
+
35
+ For example:
36
+ `ruby deploy.rb -g my_group`
37
+
38
+ ## Resources
39
+ [AWS Ruby SDK Documentation](http://docs.aws.amazon.com/AWSRubySDK/latest/_index.html)
40
+
41
+ ## License
42
+ The MIT License (MIT)
43
+
44
+ Copyright (c) 2014 uMov.me
45
+
46
+ Permission is hereby granted, free of charge, to any person obtaining a copy
47
+ of this software and associated documentation files (the "Software"), to deal
48
+ in the Software without restriction, including without limitation the rights
49
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
50
+ copies of the Software, and to permit persons to whom the Software is
51
+ furnished to do so, subject to the following conditions:
52
+
53
+ The above copyright notice and this permission notice shall be included in
54
+ all copies or substantial portions of the Software.
55
+
56
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
57
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
58
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
59
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
60
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
61
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
62
+ THE SOFTWARE.
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require_relative '../lib/deployer/deploy_runner'
5
+
6
+ #require all strategies
7
+ Dir[File.join(File.dirname(__FILE__), '../lib/strategy', '**/*.rb')].sort.each {|file| require File.expand_path(file); }
8
+
9
+ options = {}
10
+
11
+ optparse = OptionParser.new do |opts|
12
+ opts.on('-g', '--group GROUP', 'Auto Scaling Group name') do |group|
13
+ options[:group] = group
14
+ end
15
+
16
+ opts.on('-h', '--help', 'Display this screen') do
17
+ puts opts
18
+ exit
19
+ end
20
+ end
21
+
22
+ begin
23
+ optparse.parse!
24
+ mandatory = [:group]
25
+ missing = mandatory.select{ |param| options[param].nil? }
26
+ if not missing.empty?
27
+ puts "Missing options: #{missing.join(', ')}"
28
+ puts optparse
29
+ exit
30
+ end
31
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument
32
+ puts $!.to_s
33
+ puts optparse
34
+ exit
35
+ end
36
+
37
+ strategy = DoubleCapacityDeployment.new
38
+ deploy = DeployRunner.new strategy
39
+ deploy.run options[:group]
@@ -0,0 +1,10 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "deployee"
3
+ s.version = "0.0.1"
4
+ s.description = "A tool to simplify deployments using AWS auto scaling engine."
5
+ s.summary = ""
6
+ s.author = "Eduardo Bohrer, Gabriel Prestes, Guilherme Elias, Robson Bittencourt"
7
+ s.files = Dir["{lib/**/*,README.md,*.gemspec}"]
8
+ s.executables = "deployee"
9
+ s.add_runtime_dependency 'aws-sdk', '~> 1.52', '>= 1.52.0'
10
+ end
@@ -0,0 +1,44 @@
1
+ require 'aws-sdk'
2
+ require_relative 'scale_instance'
3
+ require_relative 'scale_loadbalancer'
4
+
5
+ class ScaleGroup
6
+
7
+ def initialize group_name
8
+ @delegate = AWS::AutoScaling::Group.new group_name
9
+ end
10
+
11
+ def instances
12
+ @delegate.auto_scaling_instances.map do |instance|
13
+ ScaleInstance.new instance.id, self
14
+ end
15
+ end
16
+
17
+ def min_size
18
+ @delegate.min_size
19
+ end
20
+
21
+ def max_size
22
+ @delegate.max_size
23
+ end
24
+
25
+ def desired_capacity
26
+ @delegate.desired_capacity
27
+ end
28
+
29
+ def update_size new_min_size, new_max_size
30
+ options = {:min_size => new_min_size, :max_size => new_max_size}
31
+ @delegate.update options
32
+ end
33
+
34
+ def health_load_balancer_instances
35
+ load_balancers.map{|lb| lb.healthy_instances}.reduce{|a, b| a + b}
36
+ end
37
+
38
+ def load_balancers
39
+ @delegate.load_balancer_names.map do |lb_name|
40
+ ScaleLoadBalancer.new lb_name
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,23 @@
1
+ require 'aws-sdk'
2
+
3
+ class ScaleInstance
4
+ attr_reader :group
5
+
6
+ def initialize instance_id, group
7
+ @delegate = AWS::EC2::Instance.new instance_id;
8
+ @group = group
9
+ end
10
+
11
+ def id
12
+ @delegate.id
13
+ end
14
+
15
+ def exists?
16
+ @delegate.exists?
17
+ end
18
+
19
+ def terminate
20
+ @delegate.terminate
21
+ end
22
+
23
+ end
@@ -0,0 +1,15 @@
1
+ require 'aws-sdk'
2
+
3
+ class ScaleLoadBalancer
4
+
5
+ def initialize lb_name
6
+ @delegate = AWS::ELB::LoadBalancer.new lb_name
7
+ end
8
+
9
+ def healthy_instances
10
+ @delegate.instances.health.count do |health|
11
+ health[:state] == 'InService'
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,42 @@
1
+ require_relative '../aws/scale_group'
2
+
3
+ class DeployRunner
4
+
5
+ def initialize strategy
6
+ @strategy = strategy
7
+ end
8
+
9
+ def run group_name
10
+ group = ScaleGroup.new group_name
11
+ instances = group.instances
12
+
13
+ @strategy.before_group(group) if @strategy.respond_to? :before_group
14
+ deploy instances
15
+ @strategy.after_group group if @strategy.respond_to? :after_group
16
+ end
17
+
18
+ def deploy instances
19
+ instances.each_with_index do |instance, index|
20
+ puts "Starting deployment #{index + 1}. Instance #{instance.id}"
21
+ deploy_instance instance
22
+ puts "Finished deployment #{index + 1}. Instance #{instance.id}"
23
+ end
24
+ end
25
+
26
+ def deploy_instance instance
27
+ if instance.exists?
28
+ @strategy.before_instance instance if @strategy.respond_to? :before_instance
29
+ renew instance
30
+ @strategy.after_instance instance if @strategy.respond_to? :after_instance
31
+ else
32
+ puts "Instance out. Ignored during renew"
33
+ end
34
+ end
35
+
36
+ def renew instance
37
+ puts "Terminating instance #{instance.id}"
38
+ instance.terminate
39
+ puts "Instance #{instance.id} sucessfully terminated"
40
+ end
41
+
42
+ end
@@ -0,0 +1,11 @@
1
+
2
+ module WaitUntil
3
+
4
+ def wait_until
5
+ sleep(30)
6
+ begin
7
+ sleep(15)
8
+ end until yield
9
+ end
10
+
11
+ end
@@ -0,0 +1,31 @@
1
+ require_relative '../helper/wait_until'
2
+
3
+ class AtLeastOneDeployment
4
+ include WaitUntil
5
+
6
+ def before_group group
7
+ @min_size = group.min_size
8
+ max_size = group.max_size
9
+ new_min_size = 1
10
+
11
+ new_min_size = 2 if group.desired_capacity == 1
12
+
13
+ group.update_size new_min_size, max_size + 1
14
+ end
15
+
16
+ def before_instance instance
17
+ wait_until_instances_ok instance.group
18
+ end
19
+
20
+ def after_group group
21
+ max_size = group.max_size
22
+ group.update_size @min_size, max_size - 1
23
+ end
24
+
25
+ def wait_until_instances_ok group
26
+ wait_until do
27
+ group.health_load_balancer_instances >= 2
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,4 @@
1
+
2
+ class BlackoutDeployment
3
+
4
+ end
@@ -0,0 +1,27 @@
1
+
2
+ class ComputingPreserveDeployment
3
+ include WaitUntil
4
+
5
+ def before_group group
6
+ group.update_size(group.min_size + 1, group.max_size + 1)
7
+ end
8
+
9
+ def before_instance instance
10
+ wait_until_instances_ok instance.group
11
+ end
12
+
13
+ def after_instance instance
14
+ wait_until_instances_ok instance.group
15
+ end
16
+
17
+ def after_group group
18
+ group.update_size(group.min_size - 1, group.max_size - 1)
19
+ end
20
+
21
+ def wait_until_instances_ok group
22
+ wait_until do
23
+ group.health_load_balancer_instances == group.desired_capacity
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,18 @@
1
+
2
+ class DoubleCapacityDeployment
3
+ include WaitUntil
4
+
5
+ def before_group group
6
+ @min_size = group.min_size
7
+ group.update_size(group.instances.size * 2, group.max_size * 2)
8
+ wait_until_instances_ok group
9
+ group.update_size(@min_size, group.max_size / 2)
10
+ end
11
+
12
+ def wait_until_instances_ok group
13
+ wait_until do
14
+ group.health_load_balancer_instances == group.desired_capacity
15
+ end
16
+ end
17
+
18
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: deployee
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Eduardo Bohrer, Gabriel Prestes, Guilherme Elias, Robson Bittencourt
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.52'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.52.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.52'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.52.0
33
+ description: A tool to simplify deployments using AWS auto scaling engine.
34
+ email:
35
+ executables:
36
+ - deployee
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - README.md
41
+ - bin/deployee
42
+ - deployee.gemspec
43
+ - lib/aws/scale_group.rb
44
+ - lib/aws/scale_instance.rb
45
+ - lib/aws/scale_loadbalancer.rb
46
+ - lib/deployer/deploy_runner.rb
47
+ - lib/helper/wait_until.rb
48
+ - lib/strategy/at_least_one.rb
49
+ - lib/strategy/blackout.rb
50
+ - lib/strategy/computing_preserve.rb
51
+ - lib/strategy/double_capacity.rb
52
+ homepage:
53
+ licenses: []
54
+ metadata: {}
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubyforge_project:
71
+ rubygems_version: 2.4.2
72
+ signing_key:
73
+ specification_version: 4
74
+ summary: ''
75
+ test_files: []