eb_deployer 0.6.5 → 0.6.6
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 +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/eb_deployer.rb +13 -5
- data/lib/eb_deployer/aws_driver/beanstalk.rb +12 -7
- data/lib/eb_deployer/cloud_formation_provisioner.rb +19 -12
- data/lib/eb_deployer/default_config.yml +3 -0
- data/lib/eb_deployer/eb_environment.rb +8 -2
- data/lib/eb_deployer/version.rb +1 -1
- data/lib/generators/eb_deployer/install/templates/eb_deployer.yml.erb +3 -0
- data/test/aws_driver_stubs.rb +9 -4
- data/test/resources_deploy_test.rb +55 -0
- data/test/template_deploy_test.rb +13 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61bce2cf3c9e823994645f76257fe43b360f3dfa
|
4
|
+
data.tar.gz: 0446b95ef9b12a138b495fd847118981c22452cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86ab2af9a6e5beaa906486a9929f75914a4f425169d39dd32c077ea63310951ea7c83ca93ff4e3c7aec11fe4bcf00b7ee5b0e5675bc1b01175776eaa6021d8ee
|
7
|
+
data.tar.gz: a699f697841d6e07c2d1b0ee7b682d65431f2d24b1e26a4602e7bb72303eead2866ce9e7014e7652052005a9b30d151481c4909f290e2d97e9b8f63f16777d53
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
0.6.6
|
2
|
+
=====
|
3
|
+
|
4
|
+
* Add support for specifying (and overriding) a [stack policy](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/protect-stack-resources.html) for the CloudFormation resource stack
|
5
|
+
* Fix issue where deployment hangs if resource stack update fails and stack is rolled back, deployment will now fail when the resource stack update fails
|
6
|
+
|
1
7
|
0.6.5
|
2
8
|
=====
|
3
9
|
|
data/lib/eb_deployer.rb
CHANGED
@@ -56,7 +56,7 @@ module EbDeployer
|
|
56
56
|
|
57
57
|
|
58
58
|
#
|
59
|
-
# Deploy a package to
|
59
|
+
# Deploy a package to specified environments on elastic beanstalk
|
60
60
|
#
|
61
61
|
# @param [Hash] opts
|
62
62
|
#
|
@@ -101,7 +101,7 @@ module EbDeployer
|
|
101
101
|
# deploy. For blue-green deployment it terminate the inactive environment
|
102
102
|
# first then recreate it. This is useful to avoiding configuration drift and
|
103
103
|
# accumulating state on the EC2 instances. Also it has the benefit of keeping
|
104
|
-
# your EC2 instance system package upto date, because
|
104
|
+
# your EC2 instance system package upto date, because every time EC2 instance
|
105
105
|
# boot up from AMI it does a system update.
|
106
106
|
#
|
107
107
|
#
|
@@ -116,6 +116,10 @@ module EbDeployer
|
|
116
116
|
# following keys:
|
117
117
|
#
|
118
118
|
# :template => CloudFormation template file with JSON format
|
119
|
+
# :policy => CloudFormation policy file with JSON format
|
120
|
+
# :override_policy => (false) If override_policy is true and a policy file is provided then the
|
121
|
+
# policy will temporarily override any existing policy on the resource stack during this update,
|
122
|
+
# otherwise the provided policy will replace any existing policy on the resource stack
|
119
123
|
# :parameters (or :inputs) => A Hash, input values for the CloudFormation template
|
120
124
|
# :transforms => A Hash with key map to your CloudFormation
|
121
125
|
# template outputs and value as lambda that return a single or array of
|
@@ -151,7 +155,7 @@ module EbDeployer
|
|
151
155
|
#
|
152
156
|
# @option opts [Symbol] :strategy (:blue-green) There are two options:
|
153
157
|
# blue-green or inplace-update. Blue green keep two elastic beanstalk
|
154
|
-
# environments and always deploy to inactive one, to
|
158
|
+
# environments and always deploy to inactive one, to achieve zero downtime.
|
155
159
|
# inplace-update strategy will only keep one environment, and update the
|
156
160
|
# version inplace on deploy. this will save resources but will have downtime.
|
157
161
|
#
|
@@ -164,8 +168,8 @@ module EbDeployer
|
|
164
168
|
# @option opts [Symbol] :version_label *required*. Version label give the
|
165
169
|
# package uploaded a unique identifier. Should use something related to
|
166
170
|
# pipeline counter if you have build pipeline setup to build the installer.
|
167
|
-
# For the
|
168
|
-
# that
|
171
|
+
# For the convenience of dev we recommend use md5 digest of the installer so
|
172
|
+
# that every time you upload new installer it forms a new version. e.g.
|
169
173
|
#
|
170
174
|
# :version_label => ENV['MY_PIPELINE_COUNTER']
|
171
175
|
# || "dev-" + Digest::MD5.file(my_package).hexdigest
|
@@ -178,6 +182,9 @@ module EbDeployer
|
|
178
182
|
# keep. Older versions are removed and deleted from the S3 source bucket as well.
|
179
183
|
# If specified as zero or not specified, all versions will be kept. If a
|
180
184
|
# version_prefix is given, only removes version starting with the prefix.
|
185
|
+
#
|
186
|
+
# @option opts [Symbol] :template_name. Specifies the environement template you wish
|
187
|
+
# to use to build your environment.
|
181
188
|
def self.deploy(opts)
|
182
189
|
if region = opts[:region]
|
183
190
|
Aws.config.update(:region => region)
|
@@ -205,6 +212,7 @@ module EbDeployer
|
|
205
212
|
env.settings = opts[:option_settings] || opts[:settings] || []
|
206
213
|
env.inactive_settings = opts[:inactive_settings] || []
|
207
214
|
env.creation_opts = {
|
215
|
+
:template_name => opts[:template_name],
|
208
216
|
:solution_stack => opts[:solution_stack_name],
|
209
217
|
:cname_prefix => opts[:cname_prefix],
|
210
218
|
:smoke_test => opts[:smoke_test],
|
@@ -25,12 +25,16 @@ module EbDeployer
|
|
25
25
|
@client.update_environment(:environment_id => env_id, :option_settings => settings)
|
26
26
|
end
|
27
27
|
|
28
|
-
def update_environment(app_name, env_name, version, tier, settings)
|
28
|
+
def update_environment(app_name, env_name, version, tier, settings, template_name)
|
29
29
|
env_id = convert_env_name_to_id(app_name, [env_name]).first
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
request = reject_nil({
|
31
|
+
:environment_id => env_id,
|
32
|
+
:version_label => version,
|
33
|
+
:option_settings => settings,
|
34
|
+
:tier => environment_tier(tier),
|
35
|
+
:template_name => template_name
|
36
|
+
})
|
37
|
+
@client.update_environment(request)
|
34
38
|
end
|
35
39
|
|
36
40
|
def environment_exists?(app_name, env_name)
|
@@ -41,7 +45,7 @@ module EbDeployer
|
|
41
45
|
alive_envs(app_name).collect { |env| env[:environment_name] }
|
42
46
|
end
|
43
47
|
|
44
|
-
def create_environment(app_name, env_name, stack_name, cname_prefix, version, tier, tags, settings)
|
48
|
+
def create_environment(app_name, env_name, stack_name, cname_prefix, version, tier, tags, settings, template_name)
|
45
49
|
request = reject_nil({
|
46
50
|
:application_name => app_name,
|
47
51
|
:environment_name => env_name,
|
@@ -50,7 +54,8 @@ module EbDeployer
|
|
50
54
|
:option_settings => settings,
|
51
55
|
:tier => environment_tier(tier),
|
52
56
|
:cname_prefix => cname_prefix,
|
53
|
-
:tags => tags
|
57
|
+
:tags => tags,
|
58
|
+
:template_name => template_name
|
54
59
|
})
|
55
60
|
@client.create_environment(request)
|
56
61
|
end
|
@@ -4,7 +4,7 @@ module EbDeployer
|
|
4
4
|
|
5
5
|
class CloudFormationProvisioner
|
6
6
|
SUCCESS_STATS = ["CREATE_COMPLETE", "UPDATE_COMPLETE"]
|
7
|
-
FAILED_STATS = ["CREATE_FAILED", "UPDATE_FAILED"]
|
7
|
+
FAILED_STATS = ["CREATE_FAILED", "UPDATE_FAILED", "UPDATE_ROLLBACK_COMPLETE"]
|
8
8
|
|
9
9
|
def initialize(stack_name, cf_driver)
|
10
10
|
@stack_name = stack_name
|
@@ -17,13 +17,15 @@ module EbDeployer
|
|
17
17
|
template = File.read(resources[:template])
|
18
18
|
capabilities = resources[:capabilities] || []
|
19
19
|
params = resources[:inputs] || resources[:parameters] || {}
|
20
|
+
policy = File.read(resources[:policy]) if resources[:policy]
|
21
|
+
override_policy = resources[:override_policy] || false
|
20
22
|
anchor = nil
|
21
23
|
begin
|
22
24
|
if stack_exists?
|
23
25
|
anchor = @poller.get_anchor
|
24
|
-
update_stack(template, params, capabilities)
|
26
|
+
update_stack(template, params, capabilities, policy, override_policy)
|
25
27
|
else
|
26
|
-
create_stack(template, params, capabilities)
|
28
|
+
create_stack(template, params, capabilities, policy)
|
27
29
|
end
|
28
30
|
rescue Aws::CloudFormation::Errors::ValidationError => e
|
29
31
|
if e.message =~ /No updates are to be performed/
|
@@ -65,21 +67,26 @@ module EbDeployer
|
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
68
|
-
def update_stack(template, params, capabilities)
|
69
|
-
|
70
|
-
|
71
|
-
|
70
|
+
def update_stack(template, params, capabilities, policy, override_policy)
|
71
|
+
opts = {:capabilities => capabilities, :parameters => params}
|
72
|
+
if (policy)
|
73
|
+
opts[:stack_policy_during_update_body] = policy if override_policy
|
74
|
+
log("Using temporary stack policy to apply resource stack updates") if override_policy
|
75
|
+
opts[:stack_policy_body] = policy unless override_policy
|
76
|
+
log("Applying new stack policy to existing resource stack") unless override_policy
|
77
|
+
end
|
78
|
+
@cf_driver.update_stack(@stack_name, template, opts)
|
72
79
|
end
|
73
80
|
|
74
81
|
def stack_exists?
|
75
82
|
@cf_driver.stack_exists?(@stack_name)
|
76
83
|
end
|
77
84
|
|
78
|
-
def create_stack(template, params, capabilities)
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
85
|
+
def create_stack(template, params, capabilities, policy)
|
86
|
+
opts = {:disable_rollback => true, :capabilities => capabilities, :parameters => params}
|
87
|
+
opts[:stack_policy_body] = policy if policy
|
88
|
+
log("Applying stack policy to new resource stack") if policy
|
89
|
+
@cf_driver.create_stack(@stack_name, template, opts)
|
83
90
|
end
|
84
91
|
|
85
92
|
def transform_output_to_settings(transforms)
|
@@ -122,6 +122,9 @@ common:
|
|
122
122
|
# options settings.
|
123
123
|
# keys:
|
124
124
|
# template => CloudFormation template file with JSON format
|
125
|
+
# policy => CloudFormation policy file with JSON format
|
126
|
+
# override_policy => (false) If override_policy is true and a policy file is provided then the policy will temporarily override any existing policy on the resource stack during this update,
|
127
|
+
# otherwise the provided policy will replace any existing policy on the resource stack
|
125
128
|
# inputs => A Hash, input values for the CloudFormation template
|
126
129
|
# outputs => A Hash with key map to your CloudFormation template outputs and value as elastic beanstalk settings namespace and option_name.
|
127
130
|
# capabilities => An array. You need set it to ['CAPABILITY_IAM'] if the
|
@@ -73,6 +73,10 @@ module EbDeployer
|
|
73
73
|
@creation_opts[:tier]
|
74
74
|
end
|
75
75
|
|
76
|
+
def template_name
|
77
|
+
@creation_opts[:template_name]
|
78
|
+
end
|
79
|
+
|
76
80
|
def has_cname?
|
77
81
|
!configured_tier || configured_tier.downcase == 'webserver'
|
78
82
|
end
|
@@ -93,7 +97,8 @@ module EbDeployer
|
|
93
97
|
version_label,
|
94
98
|
configured_tier,
|
95
99
|
tags,
|
96
|
-
settings
|
100
|
+
settings,
|
101
|
+
template_name)
|
97
102
|
end
|
98
103
|
end
|
99
104
|
|
@@ -103,7 +108,8 @@ module EbDeployer
|
|
103
108
|
@name,
|
104
109
|
version_label,
|
105
110
|
configured_tier,
|
106
|
-
settings
|
111
|
+
settings,
|
112
|
+
template_name)
|
107
113
|
end
|
108
114
|
end
|
109
115
|
|
data/lib/eb_deployer/version.rb
CHANGED
@@ -137,6 +137,9 @@ common:
|
|
137
137
|
# options settings.
|
138
138
|
# keys:
|
139
139
|
# template => CloudFormation template file with JSON format
|
140
|
+
# policy => CloudFormation policy file with JSON format
|
141
|
+
# override_policy => (false) If override_policy is true and a policy file is provided then the policy will temporarily override any existing policy on the resource stack during this update,
|
142
|
+
# otherwise the provided policy will replace any existing policy on the resource stack
|
140
143
|
# inputs => A Hash, input values for the CloudFormation template
|
141
144
|
# outputs => A Hash with key map to your CloudFormation template outputs and value as elastic beanstalk settings namespace and option_name.
|
142
145
|
# capabilities => An array. You need set it to ['CAPABILITY_IAM'] if the
|
data/test/aws_driver_stubs.rb
CHANGED
@@ -24,7 +24,7 @@ class EBStub
|
|
24
24
|
@apps.include?(app)
|
25
25
|
end
|
26
26
|
|
27
|
-
def create_environment(app, env, solution_stack, cname_prefix, version, tier, tags, settings)
|
27
|
+
def create_environment(app, env, solution_stack, cname_prefix, version, tier, tags, settings, template_name)
|
28
28
|
raise 'cname prefix is not avaible' if @envs.values.detect { |env| env[:cname_prefix] == cname_prefix }
|
29
29
|
raise "env name #{env} is longer than 23 chars" if env.size > 23
|
30
30
|
raise "app not exists" unless application_exists?(app)
|
@@ -36,7 +36,8 @@ class EBStub
|
|
36
36
|
:cname_prefix => cname_prefix,
|
37
37
|
:tier => tier,
|
38
38
|
:tags => tags,
|
39
|
-
:settings => settings
|
39
|
+
:settings => settings,
|
40
|
+
:template_name => template_name }
|
40
41
|
set_env_ready(app, env, false)
|
41
42
|
end
|
42
43
|
|
@@ -52,9 +53,9 @@ class EBStub
|
|
52
53
|
end
|
53
54
|
|
54
55
|
|
55
|
-
def update_environment(app, env, version, tier, settings)
|
56
|
+
def update_environment(app, env, version, tier, settings, template_name)
|
56
57
|
raise "not in ready state, consider waiting for previous action finish by pulling envents" unless env_ready?(app, env)
|
57
|
-
@envs[env_key(app, env)].merge!(:version => version, :settings => settings, :tier => tier)
|
58
|
+
@envs[env_key(app, env)].merge!(:version => version, :settings => settings, :tier => tier, :template_name => template_name)
|
58
59
|
set_env_ready(app, env, false)
|
59
60
|
end
|
60
61
|
|
@@ -220,6 +221,10 @@ class EBStub
|
|
220
221
|
@versions_deleted[app_name]
|
221
222
|
end
|
222
223
|
|
224
|
+
def template_name(app_name, env_name)
|
225
|
+
@envs[env_key(app_name, env_name)][:template_name]
|
226
|
+
end
|
227
|
+
|
223
228
|
private
|
224
229
|
|
225
230
|
def set_env_ready(app, env, ready)
|
@@ -11,6 +11,61 @@ class ResourcesDeployTest < DeployTest
|
|
11
11
|
assert @cf_driver.stack_exists?('simple-production')
|
12
12
|
assert_equal({}, @cf_driver.stack_config('simple-production')[:parameters])
|
13
13
|
assert_equal([], @cf_driver.stack_config('simple-production')[:capabilities])
|
14
|
+
assert_nil(@cf_driver.stack_config('simple-production')[:stack_policy_body])
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_deploy_with_resources_declared_will_create_a_cf_stack_for_env_with_policy
|
18
|
+
cf_template = temp_file(JSON.dump({'Resources' => {'R1' => {}}}))
|
19
|
+
cf_policy = sample_file("sample_policy.json", JSON.dump({'Policy' => {'P1' => {}}}))
|
20
|
+
deploy(:application => 'simple', :environment => "production",
|
21
|
+
:resources => {
|
22
|
+
:template => cf_template,
|
23
|
+
:policy => cf_policy
|
24
|
+
})
|
25
|
+
assert @cf_driver.stack_exists?('simple-production')
|
26
|
+
assert_equal({}, @cf_driver.stack_config('simple-production')[:parameters])
|
27
|
+
assert_equal([], @cf_driver.stack_config('simple-production')[:capabilities])
|
28
|
+
assert_equal("{\"Policy\":{\"P1\":{}}}", @cf_driver.stack_config('simple-production')[:stack_policy_body])
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_deploy_with_resources_declared_will_update_a_cf_stack_for_env_with_policy
|
32
|
+
cf_template = temp_file(JSON.dump({'Resources' => {'R1' => {}}}))
|
33
|
+
cf_policy = sample_file("sample_policy.json", JSON.dump({'Policy' => {'P1' => {}}}))
|
34
|
+
deploy(:application => 'simple', :environment => "production",
|
35
|
+
:resources => {
|
36
|
+
:template => cf_template,
|
37
|
+
:policy => cf_policy
|
38
|
+
})
|
39
|
+
assert @cf_driver.stack_exists?('simple-production')
|
40
|
+
deploy(:application => 'simple', :environment => "production",
|
41
|
+
:resources => {
|
42
|
+
:template => cf_template,
|
43
|
+
:policy => cf_policy,
|
44
|
+
:override_policy => false
|
45
|
+
})
|
46
|
+
assert_equal({}, @cf_driver.stack_config('simple-production')[:parameters])
|
47
|
+
assert_equal([], @cf_driver.stack_config('simple-production')[:capabilities])
|
48
|
+
assert_equal("{\"Policy\":{\"P1\":{}}}", @cf_driver.stack_config('simple-production')[:stack_policy_body])
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_deploy_with_resources_declared_will_update_a_cf_stack_for_env_with_temp_policy
|
52
|
+
cf_template = temp_file(JSON.dump({'Resources' => {'R1' => {}}}))
|
53
|
+
cf_policy = sample_file("sample_policy.json", JSON.dump({'Policy' => {'P1' => {}}}))
|
54
|
+
deploy(:application => 'simple', :environment => "production",
|
55
|
+
:resources => {
|
56
|
+
:template => cf_template,
|
57
|
+
:policy => cf_policy
|
58
|
+
})
|
59
|
+
assert @cf_driver.stack_exists?('simple-production')
|
60
|
+
deploy(:application => 'simple', :environment => "production",
|
61
|
+
:resources => {
|
62
|
+
:template => cf_template,
|
63
|
+
:policy => cf_policy,
|
64
|
+
:override_policy => true
|
65
|
+
})
|
66
|
+
assert_equal({}, @cf_driver.stack_config('simple-production')[:parameters])
|
67
|
+
assert_equal([], @cf_driver.stack_config('simple-production')[:capabilities])
|
68
|
+
assert_equal("{\"Policy\":{\"P1\":{}}}", @cf_driver.stack_config('simple-production')[:stack_policy_during_update_body])
|
14
69
|
end
|
15
70
|
|
16
71
|
def test_provision_resources_with_capacities
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'deploy_test'
|
2
|
+
|
3
|
+
class TemplateDeployTest < DeployTest
|
4
|
+
def test_default_no_template
|
5
|
+
deploy(:application => 'simple', :environment => "production")
|
6
|
+
assert_equal nil, @eb.template_name('simple', t('production', 'simple'))
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_can_set_a_template
|
10
|
+
deploy(:application => 'simple', :environment => "production", :template_name => 'SomeTemplate')
|
11
|
+
assert_equal 'SomeTemplate', @eb.template_name('simple', t('production', 'simple'))
|
12
|
+
end
|
13
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eb_deployer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- wpc
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-
|
13
|
+
date: 2016-03-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: aws-sdk
|
@@ -103,6 +103,7 @@ files:
|
|
103
103
|
- test/rails_generators_test.rb
|
104
104
|
- test/resources_deploy_test.rb
|
105
105
|
- test/smoke_test_test.rb
|
106
|
+
- test/template_deploy_test.rb
|
106
107
|
- test/test_helper.rb
|
107
108
|
- test/tier_setting_deploy_test.rb
|
108
109
|
- test/versions_deploy_test.rb
|
@@ -148,6 +149,7 @@ test_files:
|
|
148
149
|
- test/rails_generators_test.rb
|
149
150
|
- test/resources_deploy_test.rb
|
150
151
|
- test/smoke_test_test.rb
|
152
|
+
- test/template_deploy_test.rb
|
151
153
|
- test/test_helper.rb
|
152
154
|
- test/tier_setting_deploy_test.rb
|
153
155
|
- test/versions_deploy_test.rb
|