autocanary24 0.4.4 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +1 -1
- data/examples/README.md +24 -0
- data/examples/Rakefile +40 -0
- data/lib/autocanary24/canarystack.rb +9 -1
- data/lib/autocanary24/client.rb +47 -12
- data/lib/autocanary24/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4fb0dc82d78df443b153179546ecb97bb5ec993d
|
4
|
+
data.tar.gz: e60978aee96da8e647ec95bc7baacd4fb8ee9db0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27383625a91fb41f9a1b926870bd225d9631c5ba08cc22a959376e9d5efd5274fc9181a7f39b32e74900219067ea85d8825d095038139422a579b30d2c591537
|
7
|
+
data.tar.gz: 693e6587e28fa664a3f73e5082002140ce96f417d91544e711aedcdb393ae4d4b49d5e2eaeb18314d865dd40cdc231ab7001efee7dd08f91825b4fccd4b2f1c4
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
0.5.0 (2018-02-21)
|
2
|
+
------------------
|
3
|
+
* Feature - New methods on the AutoCanary client for rolling back and cleaning up
|
4
|
+
|
5
|
+
See [related GitHub pull request #15](https://github.com/AutoScout24/autocanary24/pull/15).
|
6
|
+
|
1
7
|
0.4.4 (2017-03-15)
|
2
8
|
------------------
|
3
9
|
* Issue - Fails to rollback if no new instances were attached to ELB
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# AutoCanary24
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.org/
|
3
|
+
[![Build Status](https://travis-ci.org/Scout24/autocanary24.svg)](https://travis-ci.org/Scout24/autocanary24)
|
4
4
|
|
5
5
|
AutoCanary24 is a ruby utility to do [blue/green](http://martinfowler.com/bliki/BlueGreenDeployment.html) and [canary](http://martinfowler.com/bliki/CanaryRelease.html) deployments with AWS CloudFormation stacks.
|
6
6
|
|
data/examples/README.md
CHANGED
@@ -47,3 +47,27 @@ How to run: `rake sample_4`
|
|
47
47
|
| Green stack gets some traffic | <img src="../docs/autocanary_80_20.png" height="150" /> |
|
48
48
|
| Green stack gets more traffic | <img src="../docs/autocanary_50_50.png" height="150" /> |
|
49
49
|
| Rollback: All the traffic goes again to blue stack | <img src="../docs/autocanary_100_0.png" height="150" /> |
|
50
|
+
|
51
|
+
## 5) Switch complete stacks at once and roll back when health check fails
|
52
|
+
|
53
|
+
How to run: `rake sample_5`
|
54
|
+
|
55
|
+
| Steps | |
|
56
|
+
| :------------- | :------------- |
|
57
|
+
| Initial state: All the traffic goes to blue stack | <img src="../docs/autocanary_100_none.png" height="150" /> |
|
58
|
+
| Green stack is created | <img src="../docs/autocanary_100_0.png" height="150" /> |
|
59
|
+
| Green stack gets all the traffic. Blue stack will not be deleted | <img src="../docs/autocanary_0_100.png" height="150" /> |
|
60
|
+
| The health check fails | <img src="../docs/autocanary_0_100.png" height="150" /> |
|
61
|
+
| Rollback: All the traffic goes again to blue stack | <img src="../docs/autocanary_100_0.png" height="150" /> |
|
62
|
+
|
63
|
+
## 6) Switch complete stacks at once and clean up when health check succeeds
|
64
|
+
|
65
|
+
How to run: `rake sample_6`
|
66
|
+
|
67
|
+
| Steps | |
|
68
|
+
| :------------- | :------------- |
|
69
|
+
| Initial state: All the traffic goes to blue stack | <img src="../docs/autocanary_100_none.png" height="150" /> |
|
70
|
+
| Green stack is created | <img src="../docs/autocanary_100_0.png" height="150" /> |
|
71
|
+
| Green stack gets all the traffic. Blue stack will not be deleted | <img src="../docs/autocanary_0_100.png" height="150" /> |
|
72
|
+
| The health check succeeds | <img src="../docs/autocanary_0_100.png" height="150" /> |
|
73
|
+
| Blue stack will be deleted | <img src="../docs/autocanary_none_100.png" height="150" /> |
|
data/examples/Rakefile
CHANGED
@@ -76,6 +76,46 @@ task :sample_4 do
|
|
76
76
|
client.deploy_stack(STACK_NAME, ASG_TEMPLATE, ASG_PARAMETER, TAGS, deployment_check)
|
77
77
|
end
|
78
78
|
|
79
|
+
desc 'switch complete stacks at once keeping and rollback after health check fails'
|
80
|
+
task :sample_5 do
|
81
|
+
puts 'executing sample_5: switch complete stacks at once keeping and rollback after health check fails'
|
82
|
+
|
83
|
+
# 1) Create the base stack which includes at least the ELB
|
84
|
+
Stacker.create_or_update_stack(STACK_NAME, BASE_TEMPLATE, {}, nil, TAGS)
|
85
|
+
|
86
|
+
# 2) Create the stack which includes the ASG
|
87
|
+
client = AutoCanary24::Client.new({:keep_inactive_stack => true})
|
88
|
+
client.deploy_stack(STACK_NAME, ASG_TEMPLATE, ASG_PARAMETER, TAGS)
|
89
|
+
|
90
|
+
breaking_deployment_check = false
|
91
|
+
|
92
|
+
if breaking_deployment_check
|
93
|
+
client.cleanup_stack(STACK_NAME)
|
94
|
+
else
|
95
|
+
client.rollback_stack(STACK_NAME)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
desc 'switch complete stacks at once keeping and clean up after health check succeeds'
|
100
|
+
task :sample_6 do
|
101
|
+
puts 'executing sample_6: switch complete stacks at once keeping and clean up after health check succeeds'
|
102
|
+
|
103
|
+
# 1) Create the base stack which includes at least the ELB
|
104
|
+
Stacker.create_or_update_stack(STACK_NAME, BASE_TEMPLATE, {}, nil, TAGS)
|
105
|
+
|
106
|
+
# 2) Create the stack which includes the ASG
|
107
|
+
client = AutoCanary24::Client.new({:keep_inactive_stack => true})
|
108
|
+
client.deploy_stack(STACK_NAME, ASG_TEMPLATE, ASG_PARAMETER, TAGS)
|
109
|
+
|
110
|
+
successful_deployment_check = true
|
111
|
+
|
112
|
+
if successful_deployment_check
|
113
|
+
client.cleanup_stack(STACK_NAME)
|
114
|
+
else
|
115
|
+
client.rollback_stack(STACK_NAME)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
79
119
|
task :cleanup do
|
80
120
|
puts 'executing cleanup'
|
81
121
|
|
@@ -32,7 +32,7 @@ module AutoCanary24
|
|
32
32
|
def is_attached_to(elb)
|
33
33
|
asg = get_autoscaling_group
|
34
34
|
elbs = get_attached_loadbalancers(asg) unless asg.nil?
|
35
|
-
(!elbs.nil? && elbs.any? { |e| e.load_balancer_name == elb })
|
35
|
+
(!elbs.nil? && elbs.any? { |e| e.load_balancer_name == elb && e.state != "Removing" && e.state != "Removed" })
|
36
36
|
end
|
37
37
|
|
38
38
|
def attach_instances_to_elb_and_wait(elb, instances)
|
@@ -82,6 +82,14 @@ module AutoCanary24
|
|
82
82
|
.map{ |i| { instance_id: i[:instance_id] } }
|
83
83
|
end
|
84
84
|
|
85
|
+
def is_stack_created?
|
86
|
+
begin
|
87
|
+
get_instance_ids
|
88
|
+
rescue
|
89
|
+
return false
|
90
|
+
end
|
91
|
+
true
|
92
|
+
end
|
85
93
|
|
86
94
|
private
|
87
95
|
def describe_asg(asg)
|
data/lib/autocanary24/client.rb
CHANGED
@@ -20,10 +20,7 @@ module AutoCanary24
|
|
20
20
|
elb = get_elb(parent_stack_name)
|
21
21
|
raise "No ELB found in stack #{parent_stack_name}" if elb.nil?
|
22
22
|
|
23
|
-
|
24
|
-
green_cs = get_canary_stack("#{parent_stack_name}-G")
|
25
|
-
|
26
|
-
stacks = get_stacks_to_create_and_to_delete_for(blue_cs, green_cs, elb)
|
23
|
+
stacks = get_stacks_to_create_and_to_delete(parent_stack_name, elb)
|
27
24
|
|
28
25
|
before_switch(stacks, template, parameters, parent_stack_name, tags)
|
29
26
|
|
@@ -44,8 +41,52 @@ module AutoCanary24
|
|
44
41
|
|
45
42
|
end
|
46
43
|
|
44
|
+
def rollback_stack(parent_stack_name)
|
45
|
+
write_log(parent_stack_name,"Rolling back stack")
|
46
|
+
|
47
|
+
elb = get_elb(parent_stack_name)
|
48
|
+
|
49
|
+
stacks = get_stacks_to_create_and_to_delete(parent_stack_name, elb)
|
50
|
+
|
51
|
+
attach_stack_to_create_and_detach_stack_to_delete(elb, stacks)
|
52
|
+
end
|
53
|
+
|
54
|
+
def cleanup_stack(parent_stack_name)
|
55
|
+
write_log(parent_stack_name,"Cleaning up stack")
|
56
|
+
|
57
|
+
elb = get_elb(parent_stack_name)
|
58
|
+
|
59
|
+
stacks = get_stacks_to_create_and_to_delete(parent_stack_name, elb)
|
60
|
+
|
61
|
+
old_stack = stacks[:stack_to_create]
|
62
|
+
|
63
|
+
if old_stack.is_stack_created?
|
64
|
+
delete_stack(old_stack.stack_name)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
47
68
|
private
|
48
|
-
def
|
69
|
+
def attach_stack_to_create_and_detach_stack_to_delete(elb, stacks)
|
70
|
+
write_log(stacks[:stack_to_create].stack_name, "Attach to ELB #{elb}")
|
71
|
+
|
72
|
+
if stacks[:stack_to_create].is_stack_created?
|
73
|
+
stacks[:stack_to_create].attach_asg_to_elb_and_wait(elb)
|
74
|
+
end
|
75
|
+
|
76
|
+
unless stacks[:stack_to_delete].nil?
|
77
|
+
write_log(stacks[:stack_to_delete].stack_name, "Detach from ELB #{elb}")
|
78
|
+
stacks[:stack_to_delete].detach_asg_from_elb_and_wait(elb)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_stacks_to_create_and_to_delete(parent_stack_name, elb)
|
83
|
+
blue_cs = get_canary_stack("#{parent_stack_name}-B")
|
84
|
+
green_cs = get_canary_stack("#{parent_stack_name}-G")
|
85
|
+
|
86
|
+
determine_stacks_to_create_and_to_delete_for(blue_cs, green_cs, elb)
|
87
|
+
end
|
88
|
+
|
89
|
+
def determine_stacks_to_create_and_to_delete_for(blue_cs, green_cs, elb)
|
49
90
|
|
50
91
|
green_is_attached = green_cs.is_attached_to(elb)
|
51
92
|
blue_is_attached = blue_cs.is_attached_to(elb)
|
@@ -139,13 +180,7 @@ module AutoCanary24
|
|
139
180
|
end
|
140
181
|
end
|
141
182
|
|
142
|
-
|
143
|
-
stacks[:stack_to_create].attach_asg_to_elb_and_wait(elb)
|
144
|
-
|
145
|
-
unless stacks[:stack_to_delete].nil?
|
146
|
-
write_log(stacks[:stack_to_delete].stack_name, "Detach from ELB #{elb}")
|
147
|
-
stacks[:stack_to_delete].detach_asg_from_elb_and_wait(elb)
|
148
|
-
end
|
183
|
+
attach_stack_to_create_and_detach_stack_to_delete(elb, stacks)
|
149
184
|
end
|
150
185
|
|
151
186
|
def rollback(stacks, elb, already_attached_instances, already_detached_instances)
|
data/lib/autocanary24/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: autocanary24
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Philipp Garbe
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: autostacker24
|
@@ -139,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
139
|
version: '0'
|
140
140
|
requirements: []
|
141
141
|
rubyforge_project:
|
142
|
-
rubygems_version: 2.6.
|
142
|
+
rubygems_version: 2.6.14
|
143
143
|
signing_key:
|
144
144
|
specification_version: 4
|
145
145
|
summary: Library for blue/green and canary deployments with CloudFormation.
|