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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8a3bf432fbdd44e7326eaf9e78be738e88e9f3e4
4
- data.tar.gz: 2098b1afc36775fde413f58dd89aabd885e12dd3
3
+ metadata.gz: 61bce2cf3c9e823994645f76257fe43b360f3dfa
4
+ data.tar.gz: 0446b95ef9b12a138b495fd847118981c22452cf
5
5
  SHA512:
6
- metadata.gz: 1de31e8970e914b8cea087335e455356294144327b4d905b2ad1f5fe28cbfafb62134b1b2408a8178927f7dfd99880aba589d05092a0b0df7cb9b05fae3fac77
7
- data.tar.gz: 3faefb2b6faf8ec5caec1ac861828fe95394f81dce54d4ff94b1cec3b02d7275c86872da33e2908f5206ace6868c3b2fa2a56e4f911b48d675709377ad21660a
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 specfied environments on elastic beanstalk
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 everytime EC2 instance
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 achive zero downtime.
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 convient of dev we recommend use md5 digest of the installer so
168
- # that everytime you upload new installer it forms a new version. e.g.
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
- @client.update_environment(:environment_id => env_id,
31
- :version_label => version,
32
- :option_settings => settings,
33
- :tier => environment_tier(tier))
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
- @cf_driver.update_stack(@stack_name, template,
70
- :capabilities => capabilities,
71
- :parameters => params)
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
- @cf_driver.create_stack(@stack_name, template,
80
- :disable_rollback => true,
81
- :capabilities => capabilities,
82
- :parameters => params)
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
 
@@ -1,3 +1,3 @@
1
1
  module EbDeployer
2
- VERSION = "0.6.5"
2
+ VERSION = "0.6.6"
3
3
  end
@@ -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
@@ -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.5
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-02-22 00:00:00.000000000 Z
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