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.
- checksums.yaml +7 -0
- data/README.md +62 -0
- data/bin/deployee +39 -0
- data/deployee.gemspec +10 -0
- data/lib/aws/scale_group.rb +44 -0
- data/lib/aws/scale_instance.rb +23 -0
- data/lib/aws/scale_loadbalancer.rb +15 -0
- data/lib/deployer/deploy_runner.rb +42 -0
- data/lib/helper/wait_until.rb +11 -0
- data/lib/strategy/at_least_one.rb +31 -0
- data/lib/strategy/blackout.rb +4 -0
- data/lib/strategy/computing_preserve.rb +27 -0
- data/lib/strategy/double_capacity.rb +18 -0
- metadata +75 -0
checksums.yaml
ADDED
@@ -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
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# Deployee
|
2
|
+
|
3
|
+
A tool to simplify deployments using AWS auto scaling engine.
|
4
|
+
|
5
|
+

|
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.
|
data/bin/deployee
ADDED
@@ -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]
|
data/deployee.gemspec
ADDED
@@ -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,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,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: []
|