elastic_beans 0.13.0.alpha3 → 0.13.0.alpha4
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/README.md +6 -4
- data/lib/elastic_beans/application.rb +17 -6
- data/lib/elastic_beans/application_version.rb +45 -5
- data/lib/elastic_beans/aws/cloudformation_stack.rb +2 -2
- data/lib/elastic_beans/cli.rb +6 -4
- data/lib/elastic_beans/command/configure.rb +82 -16
- data/lib/elastic_beans/command/deploy.rb +25 -1
- data/lib/elastic_beans/configuration_template/base.rb +55 -25
- data/lib/elastic_beans/configuration_template/exec.rb +9 -5
- data/lib/elastic_beans/configuration_template/scheduler.rb +8 -4
- data/lib/elastic_beans/configuration_template/webserver.rb +22 -18
- data/lib/elastic_beans/configuration_template/worker.rb +12 -8
- data/lib/elastic_beans/configuration_template.rb +60 -8
- data/lib/elastic_beans/environment.rb +6 -0
- data/lib/elastic_beans/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a69e6d19ef9b23f9db1ccddb65d7f49644e72233
|
4
|
+
data.tar.gz: 1b2b65654a6abcc05e7033946f13464d5f51a85b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ced50156c632ae34c5219d7d8f4384cf7ccf1243611dd23e06c57eb552707907305d6bbd03a9bfda390126c220a96ff35a7b363649d72ea94bebc41da91dd5a7
|
7
|
+
data.tar.gz: 87f4ec5eb18640de5d43327b24a29a0539c4d22fbffb08c3fb8968054de09d0d2bff152f38467722ea625e70b68b932a362694846ca00c4872cc2c016ff07bef
|
data/README.md
CHANGED
@@ -24,8 +24,9 @@ As the SDK documentation suggests, using environment variables is recommended.
|
|
24
24
|
|
25
25
|
# Pre-configure the application before creating environments
|
26
26
|
beans configure -n myapp-networking -a myapp \
|
27
|
-
-p INTERNAL_PUBLIC_KEY -s SSL_CERTIFICATE_ARN \
|
28
|
-
-
|
27
|
+
-p INTERNAL_PUBLIC_KEY -s SSL_CERTIFICATE_ARN -k KEYPAIR \
|
28
|
+
[--solution-stack '64bit Amazon Linux 2017.03 v2.4.2 running Ruby 2.3 (Puma)'] \
|
29
|
+
[-o 'OPTION_SETTING_NAMESPACE/OPTION_NAME=VALUE'...]
|
29
30
|
beans setenv -a myapp \
|
30
31
|
DATABASE_URL=mysql2://db.example.com:3306/myapp \
|
31
32
|
SECRET_KEY_BASE=abc123
|
@@ -65,8 +66,9 @@ As the SDK documentation suggests, using environment variables is recommended.
|
|
65
66
|
|
66
67
|
# Update all existing environments and configuration
|
67
68
|
beans configure -n myapp-networking -a myapp \
|
68
|
-
[-p INTERNAL_PUBLIC_KEY] [-s SSL_CERTIFICATE_ARN] \
|
69
|
-
[-
|
69
|
+
[-p INTERNAL_PUBLIC_KEY] [-s SSL_CERTIFICATE_ARN] [-k KEYPAIR] \
|
70
|
+
[--solution-stack '64bit Amazon Linux 2017.03 v2.4.2 running Ruby 2.3 (Puma)'] \
|
71
|
+
[-o 'OPTION_SETTING_NAMESPACE/OPTION_NAME=VALUE'...]
|
70
72
|
|
71
73
|
### API
|
72
74
|
|
@@ -29,7 +29,7 @@ module ElasticBeans
|
|
29
29
|
live_environments = response.environments.select { |environment| environment.status !~ /Terminat/ }
|
30
30
|
environment = live_environments.max_by(&:date_updated)
|
31
31
|
if environment
|
32
|
-
ElasticBeans::ApplicationVersion.new(environment.version_label)
|
32
|
+
ElasticBeans::ApplicationVersion.new(environment.version_label, application: self, elastic_beanstalk: elastic_beanstalk)
|
33
33
|
end
|
34
34
|
rescue ::Aws::ElasticBeanstalk::Errors::Throttling
|
35
35
|
sleep 5
|
@@ -226,11 +226,22 @@ module ElasticBeans
|
|
226
226
|
|
227
227
|
# Returns an ElasticBeans::ApplicationVersion for each version of the Elastic Beanstalk application.
|
228
228
|
def versions
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
229
|
+
application_versions = []
|
230
|
+
next_token = nil
|
231
|
+
loop do
|
232
|
+
begin
|
233
|
+
response = elastic_beanstalk.describe_application_versions(application_name: name, next_token: next_token)
|
234
|
+
next_token = response.next_token
|
235
|
+
application_versions += response.application_versions.map { |version|
|
236
|
+
ElasticBeans::ApplicationVersion.new_from_existing(version, application: self, elastic_beanstalk: elastic_beanstalk)
|
237
|
+
}
|
238
|
+
break unless next_token
|
239
|
+
rescue ::Aws::ElasticBeanstalk::Errors::Throttling
|
240
|
+
sleep 5
|
241
|
+
retry
|
242
|
+
end
|
243
|
+
end
|
244
|
+
application_versions
|
234
245
|
end
|
235
246
|
|
236
247
|
# Returns the +Worker{QUEUE}QueueUrl+ from the application CloudFormation stack.
|
@@ -7,11 +7,23 @@ require "elastic_beans/error"
|
|
7
7
|
|
8
8
|
module ElasticBeans
|
9
9
|
class ApplicationVersion
|
10
|
-
attr_reader :version_label
|
10
|
+
attr_reader :version_label, :application
|
11
|
+
attr_writer :version_description
|
11
12
|
|
12
13
|
# Create a representation of an existing application version in Elastic Beanstalk.
|
13
|
-
|
14
|
+
# Details will be fetched from the Elastic Beanstalk API.
|
15
|
+
def initialize(version_label, application:, elastic_beanstalk:)
|
14
16
|
@version_label = version_label
|
17
|
+
@application = application
|
18
|
+
@elastic_beanstalk = elastic_beanstalk
|
19
|
+
end
|
20
|
+
|
21
|
+
# Create a representation of an existing application version in Elastic Beanstalk.
|
22
|
+
# +version_description+ should be the +Aws::ElasticBeanstalk::Types::ApplicationVersionDescription+ from the AWS API.
|
23
|
+
def self.new_from_existing(version_description, application:, elastic_beanstalk:)
|
24
|
+
version = new(version_description.version_label, application: application, elastic_beanstalk: elastic_beanstalk)
|
25
|
+
version.version_description = version_description
|
26
|
+
version
|
15
27
|
end
|
16
28
|
|
17
29
|
class << self
|
@@ -24,7 +36,7 @@ module ElasticBeans
|
|
24
36
|
def create(working_directory:, application:, elastic_beanstalk:, s3:)
|
25
37
|
version_label = fetch_version_label(working_directory)
|
26
38
|
if application.versions.any? { |version| version.version_label == version_label }
|
27
|
-
return new(version_label)
|
39
|
+
return new(version_label, application: application, elastic_beanstalk: elastic_beanstalk)
|
28
40
|
end
|
29
41
|
|
30
42
|
archive_path = File.join(working_directory, ".elasticbeanstalk", "#{version_label}.zip")
|
@@ -36,7 +48,7 @@ module ElasticBeans
|
|
36
48
|
elastic_beanstalk: elastic_beanstalk,
|
37
49
|
s3: s3,
|
38
50
|
)
|
39
|
-
new(version_label)
|
51
|
+
new(version_label, application: application, elastic_beanstalk: elastic_beanstalk)
|
40
52
|
end
|
41
53
|
|
42
54
|
private
|
@@ -164,12 +176,40 @@ module ElasticBeans
|
|
164
176
|
end
|
165
177
|
end
|
166
178
|
|
179
|
+
def delete
|
180
|
+
elastic_beanstalk.delete_application_version(
|
181
|
+
application_name: application.name,
|
182
|
+
version_label: version_label,
|
183
|
+
delete_source_bundle: true,
|
184
|
+
)
|
185
|
+
rescue ::Aws::ElasticBeanstalk::Errors::Throttling
|
186
|
+
sleep 5
|
187
|
+
retry
|
188
|
+
end
|
189
|
+
|
190
|
+
def date_updated
|
191
|
+
version_description.date_updated
|
192
|
+
end
|
193
|
+
|
167
194
|
def ==(other)
|
168
|
-
version_label == other.version_label
|
195
|
+
version_label == other.version_label &&
|
196
|
+
application.name == other.application.name
|
169
197
|
end
|
170
198
|
|
171
199
|
private
|
172
200
|
|
201
|
+
attr_reader :elastic_beanstalk
|
202
|
+
|
203
|
+
def version_description
|
204
|
+
@version_description ||= elastic_beanstalk.describe_application_versions(
|
205
|
+
application_name: application.name,
|
206
|
+
version_labels: [version_label],
|
207
|
+
).application_versions[0]
|
208
|
+
rescue ::Aws::ElasticBeanstalk::Errors::Throttling
|
209
|
+
sleep 5
|
210
|
+
retry
|
211
|
+
end
|
212
|
+
|
173
213
|
# :nodoc: all
|
174
214
|
# @!visibility private
|
175
215
|
class FailedApplicationVersion < ElasticBeans::Error
|
@@ -55,8 +55,8 @@ module ElasticBeans
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def message
|
58
|
-
"CloudFormation stack `#{@stack_name}' not
|
59
|
-
" Make sure the stack exists and matches the outputs required."
|
58
|
+
"CloudFormation stack `#{@stack_name}' is in progress or does not exist." \
|
59
|
+
" Make sure the stack exists, is stable, and matches the outputs required."
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
data/lib/elastic_beans/cli.rb
CHANGED
@@ -16,21 +16,23 @@ class ElasticBeans::CLI < Thor
|
|
16
16
|
long_desc ElasticBeans::Command::Configure::LONG_DESC
|
17
17
|
option :application, aliases: %w(-a), required: true, desc: APPLICATION_DESC
|
18
18
|
option :network, aliases: %w(-n), required: true, desc: "The name of the CloudFormation stack that contains networking settings"
|
19
|
-
option :image_id, aliases: %w(-i), desc: "A custom AMI to use instead of the default Ruby Elastic Beanstalk AMI"
|
20
|
-
option :instance_type, aliases: %w(-t), desc: "A default instance type to use for all environments instead of c4.large"
|
21
19
|
option :internal, type: :boolean, desc: "Configure the webserver to only be available for internal VPC access"
|
22
20
|
option :keypair, aliases: %w(-k), desc: "Required on first run. The EC2 keypair to use for Elastic Beanstalk instances"
|
21
|
+
option :option_settings, aliases: %w(-o), type: :array, default: [], desc: "Option settings to configure, format is NAMESPACE/OPTION_NAME=VALUE, e.g. aws:ec2:vpc/ELBScheme=internal"
|
22
|
+
option :option_settings_to_remove, aliases: %w(-r), type: :array, default: [], desc: "Option settings to remove, format is NAMESPACE/OPTION_NAME, e.g. aws:ec2:vpc/ELBScheme"
|
23
23
|
option :public_key, aliases: %w(-p), desc: "For end-to-end encryption. The public key of the SSL certificate the ELB will verify to communicate with your Rails app"
|
24
24
|
option :ssl_certificate_arn, aliases: %w(-s), desc: "The ARN of the SSL server certificate stored in IAM to attach to the ELB"
|
25
|
+
option :solution_stack, desc: "Solution stack name to deploy the application on. Defaults to the latest Ruby Puma solution stack."
|
25
26
|
def configure
|
26
27
|
@verbose = options[:verbose]
|
27
28
|
ElasticBeans::Command::Configure.new(
|
28
|
-
image_id: options[:image_id],
|
29
|
-
instance_type: options[:instance_type],
|
30
29
|
internal: options[:internal],
|
31
30
|
keypair: options[:keypair],
|
32
31
|
public_key: options[:public_key],
|
33
32
|
ssl_certificate_arn: options[:ssl_certificate_arn],
|
33
|
+
solution_stack: options[:solution_stack],
|
34
|
+
option_settings: options[:option_settings],
|
35
|
+
option_settings_to_remove: options[:option_settings_to_remove],
|
34
36
|
application: application(name: options[:application]),
|
35
37
|
network: network(stack_name: options[:network]),
|
36
38
|
elastic_beanstalk: elastic_beanstalk_client,
|
@@ -16,24 +16,26 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
|
|
16
16
|
LONG_DESC
|
17
17
|
|
18
18
|
def initialize(
|
19
|
-
image_id:,
|
20
|
-
instance_type:,
|
21
19
|
internal:,
|
22
20
|
keypair:,
|
23
21
|
public_key:,
|
24
22
|
ssl_certificate_arn:,
|
23
|
+
solution_stack:,
|
24
|
+
option_settings:,
|
25
|
+
option_settings_to_remove:,
|
25
26
|
application:,
|
26
27
|
network:,
|
27
28
|
elastic_beanstalk:,
|
28
29
|
iam:,
|
29
30
|
ui:
|
30
31
|
)
|
31
|
-
@image_id = image_id
|
32
|
-
@instance_type = instance_type
|
33
32
|
@internal = internal
|
34
33
|
@keypair = keypair
|
35
34
|
@public_key = public_key
|
36
35
|
@ssl_certificate_arn = ssl_certificate_arn
|
36
|
+
@solution_stack = solution_stack
|
37
|
+
@option_setting_strings = option_settings
|
38
|
+
@option_strings_to_remove = option_settings_to_remove
|
37
39
|
@application = application
|
38
40
|
@network = network
|
39
41
|
@elastic_beanstalk = elastic_beanstalk
|
@@ -71,9 +73,10 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
|
|
71
73
|
)
|
72
74
|
base_config.upsert(
|
73
75
|
network: network,
|
74
|
-
image_id: image_id,
|
75
|
-
instance_type: instance_type,
|
76
76
|
keypair: keypair,
|
77
|
+
solution_stack: solution_stack,
|
78
|
+
option_settings: option_settings,
|
79
|
+
options_to_remove: options_to_remove,
|
77
80
|
iam: iam,
|
78
81
|
)
|
79
82
|
progressbar.increment
|
@@ -85,13 +88,14 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
|
|
85
88
|
)
|
86
89
|
webserver_config.upsert(
|
87
90
|
network: network,
|
88
|
-
image_id: image_id,
|
89
|
-
instance_type: instance_type,
|
90
91
|
internal: internal,
|
91
92
|
keypair: keypair,
|
93
|
+
option_settings: option_settings,
|
94
|
+
options_to_remove: options_to_remove,
|
92
95
|
iam: iam,
|
93
96
|
public_key: public_key,
|
94
97
|
ssl_certificate_arn: ssl_certificate_arn,
|
98
|
+
solution_stack: solution_stack,
|
95
99
|
)
|
96
100
|
webserver_environment = webserver_config.environment
|
97
101
|
if webserver_environment
|
@@ -109,9 +113,10 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
|
|
109
113
|
)
|
110
114
|
exec_config.upsert(
|
111
115
|
network: network,
|
112
|
-
image_id: image_id,
|
113
|
-
instance_type: instance_type,
|
114
116
|
keypair: keypair,
|
117
|
+
solution_stack: solution_stack,
|
118
|
+
option_settings: option_settings,
|
119
|
+
options_to_remove: options_to_remove,
|
115
120
|
iam: iam,
|
116
121
|
)
|
117
122
|
exec_environment = exec_config.environment
|
@@ -130,9 +135,10 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
|
|
130
135
|
)
|
131
136
|
scheduler_config.upsert(
|
132
137
|
network: network,
|
133
|
-
image_id: image_id,
|
134
|
-
instance_type: instance_type,
|
135
138
|
keypair: keypair,
|
139
|
+
solution_stack: solution_stack,
|
140
|
+
option_settings: option_settings,
|
141
|
+
options_to_remove: options_to_remove,
|
136
142
|
iam: iam,
|
137
143
|
)
|
138
144
|
scheduler_environment = scheduler_config.environment
|
@@ -153,9 +159,10 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
|
|
153
159
|
)
|
154
160
|
worker_config.upsert(
|
155
161
|
network: network,
|
156
|
-
image_id: image_id,
|
157
|
-
instance_type: instance_type,
|
158
162
|
keypair: keypair,
|
163
|
+
solution_stack: solution_stack,
|
164
|
+
option_settings: option_settings,
|
165
|
+
options_to_remove: options_to_remove,
|
159
166
|
iam: iam,
|
160
167
|
)
|
161
168
|
worker_environment = worker_config.environment
|
@@ -175,17 +182,76 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
|
|
175
182
|
|
176
183
|
attr_reader(
|
177
184
|
:application,
|
178
|
-
:image_id,
|
179
|
-
:instance_type,
|
180
185
|
:internal,
|
181
186
|
:keypair,
|
182
187
|
:network,
|
183
188
|
:public_key,
|
184
189
|
:ssl_certificate_arn,
|
190
|
+
:solution_stack,
|
185
191
|
:elastic_beanstalk,
|
186
192
|
:iam,
|
187
193
|
:ui,
|
188
194
|
)
|
195
|
+
|
196
|
+
# Coerces +@option_setting_strings+ into object format.
|
197
|
+
def option_settings
|
198
|
+
@option_settings ||= @option_setting_strings.map { |option_setting_string|
|
199
|
+
setting, value = option_setting_string.split('=', 2)
|
200
|
+
if !setting || setting.empty? || !value || value.empty?
|
201
|
+
raise InvalidOptionSettingFormatError
|
202
|
+
end
|
203
|
+
namespace, option_name = setting.split('/', 2)
|
204
|
+
if !namespace || namespace.empty? || !option_name || option_name.empty?
|
205
|
+
raise InvalidOptionSettingFormatError
|
206
|
+
end
|
207
|
+
{namespace: namespace, option_name: option_name, value: value}
|
208
|
+
}
|
209
|
+
end
|
210
|
+
|
211
|
+
# Coerces +@option_strings_to_remove+ into object format.
|
212
|
+
def options_to_remove
|
213
|
+
@options_to_remove ||= @option_strings_to_remove.map { |option_setting_string|
|
214
|
+
namespace, option_name = option_setting_string.split('/', 2)
|
215
|
+
if !namespace || namespace.empty? || !option_name || option_name.empty? || option_name.include?('=')
|
216
|
+
raise InvalidOptionSettingFormatError
|
217
|
+
end
|
218
|
+
{namespace: namespace, option_name: option_name}
|
219
|
+
}
|
220
|
+
end
|
221
|
+
|
222
|
+
# :nodoc: all
|
223
|
+
# @!visibility private
|
224
|
+
class InvalidOptionSettingFormatError < ElasticBeans::Error
|
225
|
+
def message
|
226
|
+
require "elastic_beans/cli"
|
227
|
+
require "elastic_beans/cli/string_shell"
|
228
|
+
<<-MESSAGE
|
229
|
+
Invalid format for --option-settings.
|
230
|
+
Option settings should in the format 'NAMESPACE/OPTION_NAME=VALUE', e.g. 'aws:autoscaling:asg/Cooldown=180'.
|
231
|
+
If you'd like to *remove* option settings, use --option-settings-to-remove 'NAMESPACE/OPTION_NAME'.
|
232
|
+
Please re-run `#{command_as_string "configure"}` with updated syntax.
|
233
|
+
|
234
|
+
#{command_help "configure"}
|
235
|
+
MESSAGE
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
# :nodoc: all
|
240
|
+
# @!visibility private
|
241
|
+
class InvalidOptionSettingsToRemoveFormatError < ElasticBeans::Error
|
242
|
+
def message
|
243
|
+
require "elastic_beans/cli"
|
244
|
+
require "elastic_beans/cli/string_shell"
|
245
|
+
<<-MESSAGE
|
246
|
+
Invalid format for --option-settings-to-remove.
|
247
|
+
Option settings to remove should in the format 'NAMESPACE/OPTION_NAME', e.g. 'aws:autoscaling:asg/Cooldown'.
|
248
|
+
If you'd like to *set* option settings, use --option-settings 'NAMESPACE/OPTION_NAME=VALUE'.
|
249
|
+
Please re-run `#{command_as_string "configure"}` with updated syntax.
|
250
|
+
|
251
|
+
#{command_help "configure"}
|
252
|
+
MESSAGE
|
253
|
+
end
|
254
|
+
end
|
189
255
|
end
|
190
256
|
end
|
191
257
|
end
|
@@ -9,9 +9,14 @@ module ElasticBeans
|
|
9
9
|
DESC = "Deploy the HEAD git commit to all environments in Elastic Beanstalk"
|
10
10
|
LONG_DESC = <<-LONG_DESC
|
11
11
|
Deploy the HEAD git commit of the working directory to all environments in Elastic Beanstalk.
|
12
|
+
Cleans up old application versions in parallel to avoid reaching the 1,000 application version limit.
|
12
13
|
|
13
14
|
Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
|
14
15
|
LONG_DESC
|
16
|
+
# Maximum age of application versions that are left behind and not cleaned up. 1 week.
|
17
|
+
APPLICATION_VERSION_MAX_AGE = 604_800
|
18
|
+
# Minimum number of application versions to leave around.
|
19
|
+
APPLICATION_VERSION_MIN_COUNT = 5
|
15
20
|
|
16
21
|
def initialize(application:, elastic_beanstalk:, s3:, ui:)
|
17
22
|
@application = application
|
@@ -38,15 +43,19 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
|
|
38
43
|
s3: s3,
|
39
44
|
).version_label
|
40
45
|
end
|
46
|
+
cleanup_thread = Thread.new do
|
47
|
+
remove_old_versions
|
48
|
+
end
|
41
49
|
|
42
50
|
loop do
|
43
51
|
sleep 0.5
|
44
52
|
progressbar.increment
|
45
|
-
if !version_thread.alive?
|
53
|
+
if !version_thread.alive? && !cleanup_thread.alive?
|
46
54
|
break
|
47
55
|
end
|
48
56
|
end
|
49
57
|
version_thread.join
|
58
|
+
cleanup_thread.join
|
50
59
|
|
51
60
|
Signal.trap("INT") do
|
52
61
|
puts "\nInterrupting beans"
|
@@ -85,6 +94,21 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
|
|
85
94
|
private
|
86
95
|
|
87
96
|
attr_reader :application, :elastic_beanstalk, :s3, :ui
|
97
|
+
|
98
|
+
# Removes application versions that are old and just taking up space.
|
99
|
+
# Elastic Beanstalk has a limit of 1000 application versions, so we should keep this tidy.
|
100
|
+
def remove_old_versions
|
101
|
+
cutoff = Time.now
|
102
|
+
outdated_versions, leftover_versions = application.versions.partition { |version|
|
103
|
+
version.date_updated + APPLICATION_VERSION_MAX_AGE < cutoff
|
104
|
+
}
|
105
|
+
if leftover_versions.size < APPLICATION_VERSION_MIN_COUNT
|
106
|
+
outdated_versions.pop(APPLICATION_VERSION_MIN_COUNT - leftover_versions.size)
|
107
|
+
end
|
108
|
+
outdated_versions.each do |version|
|
109
|
+
version.delete
|
110
|
+
end
|
111
|
+
end
|
88
112
|
end
|
89
113
|
end
|
90
114
|
end
|
@@ -10,6 +10,13 @@ module ElasticBeans
|
|
10
10
|
super(name: "base", **args)
|
11
11
|
end
|
12
12
|
|
13
|
+
# Returns the specifed +solution_stack+ from #upsert.
|
14
|
+
# Finds the previously-configured solution stack when one was not specified.
|
15
|
+
# Finds the latest available Ruby Puma solution stack (matching +SOLUTION_STACK_PATTERN+) when one was never specified.
|
16
|
+
def solution_stack_name
|
17
|
+
@solution_stack_name ||= (configured_solution_stack || super)
|
18
|
+
end
|
19
|
+
|
13
20
|
protected
|
14
21
|
|
15
22
|
# Constructs the common configuration for all environments.
|
@@ -18,20 +25,21 @@ module ElasticBeans
|
|
18
25
|
network: nil,
|
19
26
|
keypair: nil,
|
20
27
|
iam: nil,
|
21
|
-
image_id: nil,
|
22
|
-
instance_type: nil,
|
23
28
|
min_size: nil,
|
24
29
|
max_size: nil,
|
30
|
+
solution_stack: nil,
|
31
|
+
option_settings: [],
|
25
32
|
**_
|
26
33
|
)
|
34
|
+
@solution_stack_name = solution_stack
|
27
35
|
template = configuration_settings_description("base")
|
28
36
|
|
29
|
-
instance_profile_setting = template_option_setting(template: template, namespace: "aws:autoscaling:launchconfiguration", option_name: "IamInstanceProfile", override: instance_profile(iam))
|
37
|
+
instance_profile_setting = template_option_setting(template: template, namespace: "aws:autoscaling:launchconfiguration", option_name: "IamInstanceProfile", override: instance_profile(iam), new_settings: option_settings)
|
30
38
|
if instance_profile_setting[:value].nil?
|
31
39
|
raise MissingInstanceProfileError
|
32
40
|
end
|
33
41
|
|
34
|
-
keypair_setting = template_option_setting(template: template, namespace: "aws:autoscaling:launchconfiguration", option_name: "EC2KeyName", override: keypair)
|
42
|
+
keypair_setting = template_option_setting(template: template, namespace: "aws:autoscaling:launchconfiguration", option_name: "EC2KeyName", override: keypair, new_settings: option_settings)
|
35
43
|
if keypair_setting[:value].nil?
|
36
44
|
raise MissingOptionsError.new(
|
37
45
|
keypair: keypair_setting[:value],
|
@@ -40,35 +48,57 @@ module ElasticBeans
|
|
40
48
|
|
41
49
|
config_path = "#{application.bucket_name}/#{application.env_vars.s3_key}"
|
42
50
|
settings = [
|
43
|
-
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:command", option_name: "BatchSize", default: "1"),
|
44
|
-
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:command", option_name: "BatchSizeType", default: "Fixed"),
|
45
|
-
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:command", option_name: "DeploymentPolicy", default: "Rolling"),
|
46
|
-
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:application:environment", option_name: "DISABLE_SQS_CONSUMER", default: "true"),
|
47
|
-
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:application:environment", option_name: "ELASTIC_BEANS_ENV_VARS", default: config_path),
|
48
|
-
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:environment", option_name: "ServiceRole", default: "aws-elasticbeanstalk-service-role"),
|
49
|
-
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:healthreporting:system", option_name: "SystemType", default: "enhanced"),
|
50
|
-
template_option_setting(template: template, namespace: "aws:ec2:vpc", option_name: "AssociatePublicIpAddress", default: "false"),
|
51
|
-
template_option_setting(template: template, namespace: "aws:autoscaling:asg", option_name: "MinSize", default: "1", override: min_size),
|
52
|
-
template_option_setting(template: template, namespace: "aws:autoscaling:asg", option_name: "MaxSize", default: "4", override: max_size),
|
53
|
-
template_option_setting(template: template, namespace: "aws:autoscaling:launchconfiguration", option_name: "
|
54
|
-
template_option_setting(template: template, namespace: "aws:autoscaling:
|
55
|
-
template_option_setting(template: template, namespace: "aws:autoscaling:updatepolicy:rollingupdate", option_name: "
|
56
|
-
template_option_setting(template: template, namespace: "aws:autoscaling:
|
57
|
-
template_option_setting(template: template, namespace: "aws:
|
58
|
-
template_option_setting(template: template, namespace: "aws:ec2:vpc", option_name: "
|
59
|
-
template_option_setting(template: template, namespace: "aws:ec2:vpc", option_name: "
|
60
|
-
template_option_setting(template: template, namespace: "aws:ec2:vpc", option_name: "VPCId", override: vpc_id(network)),
|
51
|
+
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:command", option_name: "BatchSize", default: "1", new_settings: option_settings),
|
52
|
+
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:command", option_name: "BatchSizeType", default: "Fixed", new_settings: option_settings),
|
53
|
+
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:command", option_name: "DeploymentPolicy", default: "Rolling", new_settings: option_settings),
|
54
|
+
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:application:environment", option_name: "DISABLE_SQS_CONSUMER", default: "true", new_settings: option_settings),
|
55
|
+
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:application:environment", option_name: "ELASTIC_BEANS_ENV_VARS", default: config_path, new_settings: option_settings),
|
56
|
+
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:environment", option_name: "ServiceRole", default: "aws-elasticbeanstalk-service-role", new_settings: option_settings),
|
57
|
+
template_option_setting(template: template, namespace: "aws:elasticbeanstalk:healthreporting:system", option_name: "SystemType", default: "enhanced", new_settings: option_settings),
|
58
|
+
template_option_setting(template: template, namespace: "aws:ec2:vpc", option_name: "AssociatePublicIpAddress", default: "false", new_settings: option_settings),
|
59
|
+
template_option_setting(template: template, namespace: "aws:autoscaling:asg", option_name: "MinSize", default: "1", override: min_size, new_settings: option_settings),
|
60
|
+
template_option_setting(template: template, namespace: "aws:autoscaling:asg", option_name: "MaxSize", default: "4", override: max_size, new_settings: option_settings),
|
61
|
+
template_option_setting(template: template, namespace: "aws:autoscaling:launchconfiguration", option_name: "SSHSourceRestriction", default: "tcp, 22, 22, 0.0.0.0/32", new_settings: option_settings),
|
62
|
+
template_option_setting(template: template, namespace: "aws:autoscaling:updatepolicy:rollingupdate", option_name: "RollingUpdateType", default: "Health", new_settings: option_settings),
|
63
|
+
template_option_setting(template: template, namespace: "aws:autoscaling:updatepolicy:rollingupdate", option_name: "RollingUpdateEnabled", default: "true", new_settings: option_settings),
|
64
|
+
template_option_setting(template: template, namespace: "aws:autoscaling:launchconfiguration", option_name: "SecurityGroups", override: security_groups(network), new_settings: option_settings),
|
65
|
+
template_option_setting(template: template, namespace: "aws:ec2:vpc", option_name: "ELBSubnets", override: elb_subnets(network), new_settings: option_settings),
|
66
|
+
template_option_setting(template: template, namespace: "aws:ec2:vpc", option_name: "Subnets", override: subnets(network), new_settings: option_settings),
|
67
|
+
template_option_setting(template: template, namespace: "aws:ec2:vpc", option_name: "VPCId", override: vpc_id(network), new_settings: option_settings),
|
61
68
|
instance_profile_setting,
|
62
69
|
keypair_setting,
|
63
70
|
]
|
64
|
-
if
|
65
|
-
settings << template_option_setting(template: template, namespace: "aws:
|
71
|
+
if solution_stack
|
72
|
+
settings << template_option_setting(template: template, namespace: "aws:elasticbeanstalk:customoption", option_name: "SolutionStack", override: solution_stack, new_settings: option_settings)
|
66
73
|
end
|
67
|
-
settings
|
74
|
+
super + settings
|
75
|
+
end
|
76
|
+
|
77
|
+
def source_configuration
|
78
|
+
nil
|
68
79
|
end
|
69
80
|
|
70
81
|
private
|
71
82
|
|
83
|
+
# Finds the previously-configured solution stack when one was not specified.
|
84
|
+
# The solution stack name is stored in a custom option named "SolutionStack",
|
85
|
+
# because updating the template's solution stack is not supported by Elastic Beanstalk.
|
86
|
+
# See http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuration-options-custom.html for more information on custom options.
|
87
|
+
# If the custom option is not set because the application was configured by an older version of beans, returns the template's configured solution stack.
|
88
|
+
def configured_solution_stack
|
89
|
+
template = configuration_settings_description("base")
|
90
|
+
if template
|
91
|
+
setting = template.option_settings.find { |setting|
|
92
|
+
setting.namespace == "aws:elasticbeanstalk:customoption" && setting.option_name == "SolutionStack"
|
93
|
+
}
|
94
|
+
if setting
|
95
|
+
return setting.value
|
96
|
+
else
|
97
|
+
return template.solution_stack_name
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
72
102
|
def elb_subnets(network)
|
73
103
|
if network
|
74
104
|
network.elb_subnets.join(",")
|
@@ -12,14 +12,18 @@ module ElasticBeans
|
|
12
12
|
protected
|
13
13
|
|
14
14
|
# Constructs the configuration for the exec environment.
|
15
|
-
def build_option_settings(**_)
|
15
|
+
def build_option_settings(option_settings: [], **_)
|
16
16
|
super + [
|
17
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTP:80/"),
|
18
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "DISABLE_SQS_CONSUMER", override: "false"),
|
19
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "ELASTIC_BEANS_EXEC_QUEUE_URL", override: application.exec_queue_url),
|
20
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_MIGRATIONS", default: "true"),
|
17
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTP:80/", new_settings: option_settings),
|
18
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "DISABLE_SQS_CONSUMER", override: "false", new_settings: option_settings),
|
19
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "ELASTIC_BEANS_EXEC_QUEUE_URL", override: application.exec_queue_url, new_settings: option_settings),
|
20
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_MIGRATIONS", default: "true", new_settings: option_settings),
|
21
21
|
]
|
22
22
|
end
|
23
|
+
|
24
|
+
def source_configuration
|
25
|
+
SOURCE_CONFIGURATION
|
26
|
+
end
|
23
27
|
end
|
24
28
|
end
|
25
29
|
end
|
@@ -11,13 +11,17 @@ module ElasticBeans
|
|
11
11
|
|
12
12
|
# Constructs the configuration for the scheduler environment.
|
13
13
|
# No special options here!
|
14
|
-
def build_option_settings(**_)
|
14
|
+
def build_option_settings(option_settings: [], **_)
|
15
15
|
super + [
|
16
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTP:80/"),
|
17
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "DISABLE_SQS_CONSUMER", override: "false"),
|
18
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_MIGRATIONS", default: "true"),
|
16
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTP:80/", new_settings: option_settings),
|
17
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "DISABLE_SQS_CONSUMER", override: "false", new_settings: option_settings),
|
18
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_MIGRATIONS", default: "true", new_settings: option_settings),
|
19
19
|
]
|
20
20
|
end
|
21
|
+
|
22
|
+
def source_configuration
|
23
|
+
SOURCE_CONFIGURATION
|
24
|
+
end
|
21
25
|
end
|
22
26
|
end
|
23
27
|
end
|
@@ -13,35 +13,35 @@ module ElasticBeans
|
|
13
13
|
|
14
14
|
# Constructs the configuration for the webserver environment.
|
15
15
|
# All arguments are required on first run.
|
16
|
-
def build_option_settings(network: nil, public_key: nil, ssl_certificate_arn: nil, internal: nil, **_)
|
17
|
-
public_key_policy_names_setting = template_option_setting(namespace: "aws:elb:policies:backendencryption", option_name: "PublicKeyPolicyNames", default: "backendkey")
|
18
|
-
public_key_setting = template_option_setting(namespace: "aws:elb:policies:#{public_key_policy_names_setting[:value]}", option_name: "PublicKey", override: public_key)
|
19
|
-
ssl_certificate_setting = template_option_setting(namespace: "aws:elb:listener:443", option_name: "SSLCertificateId", override: ssl_certificate_arn)
|
16
|
+
def build_option_settings(network: nil, public_key: nil, ssl_certificate_arn: nil, internal: nil, option_settings: [], **_)
|
17
|
+
public_key_policy_names_setting = template_option_setting(namespace: "aws:elb:policies:backendencryption", option_name: "PublicKeyPolicyNames", default: "backendkey", new_settings: option_settings)
|
18
|
+
public_key_setting = template_option_setting(namespace: "aws:elb:policies:#{public_key_policy_names_setting[:value]}", option_name: "PublicKey", override: public_key, new_settings: option_settings)
|
19
|
+
ssl_certificate_setting = template_option_setting(namespace: "aws:elb:listener:443", option_name: "SSLCertificateId", override: ssl_certificate_arn, new_settings: option_settings)
|
20
20
|
if public_key_setting[:value].nil? || ssl_certificate_setting[:value].nil?
|
21
21
|
raise NoEncryptionSettingsError
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTPS:443/", allow_blank: false),
|
26
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_ASSET_COMPILATION", default: "false"),
|
27
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_MIGRATIONS", default: "false"),
|
28
|
-
template_option_setting(namespace: "aws:elb:listener:443", option_name: "InstancePort", default: "443"),
|
29
|
-
template_option_setting(namespace: "aws:elb:listener:443", option_name: "InstanceProtocol", default: "HTTPS"),
|
30
|
-
template_option_setting(namespace: "aws:elb:listener:443", option_name: "ListenerProtocol", default: "HTTPS"),
|
31
|
-
template_option_setting(namespace: "aws:elb:loadbalancer", option_name: "ManagedSecurityGroup", override: managed_security_group(network)),
|
32
|
-
template_option_setting(namespace: "aws:elb:loadbalancer", option_name: "SecurityGroups", override: elb_security_groups(network)),
|
33
|
-
template_option_setting(namespace: "aws:elb:policies", option_name: "ConnectionDrainingEnabled", default: "true"),
|
34
|
-
template_option_setting(namespace: "aws:elb:policies:backendencryption", option_name: "InstancePorts", default: "443"),
|
24
|
+
settings = [
|
25
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTPS:443/", allow_blank: false, new_settings: option_settings),
|
26
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_ASSET_COMPILATION", default: "false", new_settings: option_settings),
|
27
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_MIGRATIONS", default: "false", new_settings: option_settings),
|
28
|
+
template_option_setting(namespace: "aws:elb:listener:443", option_name: "InstancePort", default: "443", new_settings: option_settings),
|
29
|
+
template_option_setting(namespace: "aws:elb:listener:443", option_name: "InstanceProtocol", default: "HTTPS", new_settings: option_settings),
|
30
|
+
template_option_setting(namespace: "aws:elb:listener:443", option_name: "ListenerProtocol", default: "HTTPS", new_settings: option_settings),
|
31
|
+
template_option_setting(namespace: "aws:elb:loadbalancer", option_name: "ManagedSecurityGroup", override: managed_security_group(network), new_settings: option_settings),
|
32
|
+
template_option_setting(namespace: "aws:elb:loadbalancer", option_name: "SecurityGroups", override: elb_security_groups(network), new_settings: option_settings),
|
33
|
+
template_option_setting(namespace: "aws:elb:policies", option_name: "ConnectionDrainingEnabled", default: "true", new_settings: option_settings),
|
34
|
+
template_option_setting(namespace: "aws:elb:policies:backendencryption", option_name: "InstancePorts", default: "443", new_settings: option_settings),
|
35
35
|
public_key_policy_names_setting,
|
36
36
|
public_key_setting,
|
37
37
|
ssl_certificate_setting,
|
38
38
|
]
|
39
39
|
if internal
|
40
|
-
internal_setting = template_option_setting(namespace: "aws:ec2:vpc", option_name: "ELBScheme", override: "internal")
|
41
|
-
|
40
|
+
internal_setting = template_option_setting(namespace: "aws:ec2:vpc", option_name: "ELBScheme", override: "internal", new_settings: option_settings)
|
41
|
+
settings << internal_setting
|
42
42
|
end
|
43
43
|
|
44
|
-
super +
|
44
|
+
super + settings
|
45
45
|
end
|
46
46
|
|
47
47
|
# Removes the "internal" ELB scheme if explicitly disabled with --no-internal.
|
@@ -64,6 +64,10 @@ module ElasticBeans
|
|
64
64
|
network.elb_security_groups[0] if network
|
65
65
|
end
|
66
66
|
|
67
|
+
def source_configuration
|
68
|
+
SOURCE_CONFIGURATION
|
69
|
+
end
|
70
|
+
|
67
71
|
# :nodoc: all
|
68
72
|
# @!visibility private
|
69
73
|
class NoEncryptionSettingsError < ElasticBeans::Error
|
@@ -24,17 +24,21 @@ module ElasticBeans
|
|
24
24
|
# Constructs the configuration for the worker environments.
|
25
25
|
# No special arguments, the +queue+ name is stored from the initializer and is used to look up the appropriate
|
26
26
|
# URL.
|
27
|
-
def build_option_settings(**_)
|
27
|
+
def build_option_settings(option_settings: [], **_)
|
28
28
|
super + [
|
29
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTP:80/"),
|
30
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "DISABLE_SQS_CONSUMER", override: "false"),
|
31
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_MIGRATIONS", default: "true"),
|
32
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:sqsd", option_name: "InactivityTimeout", default: "1800"),
|
33
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:sqsd", option_name: "MaxRetries", default: "10"),
|
34
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:sqsd", option_name: "VisibilityTimeout", default: "1800"),
|
35
|
-
template_option_setting(namespace: "aws:elasticbeanstalk:sqsd", option_name: "WorkerQueueURL", override: application.worker_queue_url(queue)),
|
29
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTP:80/", new_settings: option_settings),
|
30
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "DISABLE_SQS_CONSUMER", override: "false", new_settings: option_settings),
|
31
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_MIGRATIONS", default: "true", new_settings: option_settings),
|
32
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:sqsd", option_name: "InactivityTimeout", default: "1800", new_settings: option_settings),
|
33
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:sqsd", option_name: "MaxRetries", default: "10", new_settings: option_settings),
|
34
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:sqsd", option_name: "VisibilityTimeout", default: "1800", new_settings: option_settings),
|
35
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:sqsd", option_name: "WorkerQueueURL", override: application.worker_queue_url(queue), new_settings: option_settings),
|
36
36
|
]
|
37
37
|
end
|
38
|
+
|
39
|
+
def source_configuration
|
40
|
+
SOURCE_CONFIGURATION
|
41
|
+
end
|
38
42
|
end
|
39
43
|
end
|
40
44
|
end
|
@@ -10,8 +10,11 @@ module ElasticBeans
|
|
10
10
|
# This is an abstract class; use the provided factories in this class or use a subclass (contained within this
|
11
11
|
# namespace) directly.
|
12
12
|
class ConfigurationTemplate
|
13
|
-
#
|
14
|
-
|
13
|
+
# Matches the latest available Ruby Puma solution stack when one was not specified.
|
14
|
+
SOLUTION_STACK_PATTERN = /\A64bit Amazon Linux (?<date>\d+(\.\d+)*) v(?<version>\d+(\.\d+)*) running Ruby (?<ruby_version>\d+(\.\d+)*) \(Puma\)\z/
|
15
|
+
# The source configuration for new configuration templates.
|
16
|
+
# Set to ElasticBeans::ConfigurationTemplate::Base to include all custom configuration that has already been performed.
|
17
|
+
SOURCE_CONFIGURATION = {template_name: "base"}
|
15
18
|
# :category: Internal
|
16
19
|
WORKER_TEMPLATE_NAME_PATTERN = /\Aworker-(?<queue>\w+)\z/
|
17
20
|
|
@@ -102,6 +105,11 @@ module ElasticBeans
|
|
102
105
|
@options_to_remove ||= []
|
103
106
|
end
|
104
107
|
|
108
|
+
# Finds the latest available Ruby Puma solution stack (matching +SOLUTION_STACK_PATTERN+).
|
109
|
+
def solution_stack_name
|
110
|
+
@solution_stack_name ||= latest_solution_stack
|
111
|
+
end
|
112
|
+
|
105
113
|
# Create or update the configuration template in Elastic Beanstalk.
|
106
114
|
# Arguments are passed to #build_option_settings and #build_options_to_remove.
|
107
115
|
# See the appropriate subclass for what the arguments should be.
|
@@ -119,7 +127,8 @@ module ElasticBeans
|
|
119
127
|
elastic_beanstalk.create_configuration_template(
|
120
128
|
application_name: application.name,
|
121
129
|
template_name: name,
|
122
|
-
solution_stack_name:
|
130
|
+
solution_stack_name: solution_stack_name,
|
131
|
+
source_configuration: source_configuration,
|
123
132
|
option_settings: option_settings,
|
124
133
|
)
|
125
134
|
end
|
@@ -135,12 +144,17 @@ module ElasticBeans
|
|
135
144
|
# :category: Internal
|
136
145
|
attr_reader :elastic_beanstalk
|
137
146
|
|
138
|
-
|
139
|
-
|
147
|
+
# Returns option settings that should be set on the template.
|
148
|
+
def build_option_settings(option_settings: [], **_)
|
149
|
+
option_settings
|
140
150
|
end
|
141
151
|
|
142
|
-
|
143
|
-
|
152
|
+
# Returns option settings that should be removed from the template.
|
153
|
+
# Will not remove settings that beans has defaults for, even if they aren't being changed right now.
|
154
|
+
def build_options_to_remove(options_to_remove: [], **_)
|
155
|
+
options_to_remove.reject { |setting|
|
156
|
+
option_settings.any? { |new_setting| new_setting[:namespace] == setting[:namespace] && new_setting[:option_name] == setting[:option_name] }
|
157
|
+
}
|
144
158
|
end
|
145
159
|
|
146
160
|
def configuration_settings_description(template_name = name)
|
@@ -181,6 +195,36 @@ module ElasticBeans
|
|
181
195
|
retry
|
182
196
|
end
|
183
197
|
|
198
|
+
# Finds the latest available Ruby Puma solution stack (matching +SOLUTION_STACK_PATTERN+).
|
199
|
+
def latest_solution_stack
|
200
|
+
latest_stack = nil
|
201
|
+
latest_date = Gem::Version.new("0.0")
|
202
|
+
latest_version = Gem::Version.new("0.0")
|
203
|
+
latest_ruby_version = Gem::Version.new("0.0")
|
204
|
+
elastic_beanstalk.list_available_solution_stacks.solution_stacks.each do |stack|
|
205
|
+
match = SOLUTION_STACK_PATTERN.match(stack)
|
206
|
+
if match
|
207
|
+
stack_date = Gem::Version.new(match[:date])
|
208
|
+
stack_version = Gem::Version.new(match[:version])
|
209
|
+
stack_ruby_version = Gem::Version.new(match[:ruby_version])
|
210
|
+
if stack_date >= latest_date && stack_version >= latest_version && stack_ruby_version >= latest_ruby_version
|
211
|
+
latest_date = stack_date
|
212
|
+
latest_version = stack_version
|
213
|
+
latest_ruby_version = stack_ruby_version
|
214
|
+
latest_stack = stack
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
latest_stack
|
219
|
+
rescue ::Aws::ElasticBeanstalk::Errors::Throttling
|
220
|
+
sleep 5
|
221
|
+
retry
|
222
|
+
end
|
223
|
+
|
224
|
+
def source_configuration
|
225
|
+
SOURCE_CONFIGURATION
|
226
|
+
end
|
227
|
+
|
184
228
|
def template_option_setting(
|
185
229
|
template: configuration_settings_description,
|
186
230
|
environment: environment_configuration_settings_description,
|
@@ -188,13 +232,21 @@ module ElasticBeans
|
|
188
232
|
option_name:,
|
189
233
|
default: nil,
|
190
234
|
override: nil,
|
191
|
-
allow_blank: true
|
235
|
+
allow_blank: true,
|
236
|
+
new_settings:
|
192
237
|
)
|
193
238
|
option_setting = {namespace: namespace, option_name: option_name, value: default}
|
194
239
|
if override
|
195
240
|
return option_setting.merge!(value: override)
|
196
241
|
end
|
197
242
|
|
243
|
+
new_setting = new_settings.find { |setting|
|
244
|
+
setting[:namespace] == namespace && setting[:option_name] == option_name
|
245
|
+
}
|
246
|
+
if new_setting
|
247
|
+
return new_setting
|
248
|
+
end
|
249
|
+
|
198
250
|
existing_settings = []
|
199
251
|
if environment
|
200
252
|
# Persist changes made directly to the environment from the AWS console UI
|
@@ -116,6 +116,7 @@ module ElasticBeans
|
|
116
116
|
elastic_beanstalk.create_environment(
|
117
117
|
application_name: application.name,
|
118
118
|
environment_name: name,
|
119
|
+
solution_stack_name: configuration_template.solution_stack_name,
|
119
120
|
tier: {name: tier_name, type: tier_type},
|
120
121
|
template_name: template_name,
|
121
122
|
version_label: version,
|
@@ -196,6 +197,7 @@ module ElasticBeans
|
|
196
197
|
environment_name: name,
|
197
198
|
option_settings: configuration_template.option_settings,
|
198
199
|
options_to_remove: configuration_template.options_to_remove,
|
200
|
+
solution_stack_name: configuration_template.solution_stack_name,
|
199
201
|
)
|
200
202
|
wait_environment(wait_status: "Updating", wait_health_status: "Info") if blocking
|
201
203
|
rescue ::Aws::ElasticBeanstalk::Errors::InvalidParameterValue
|
@@ -245,6 +247,10 @@ module ElasticBeans
|
|
245
247
|
# :category: Internal
|
246
248
|
attr_reader :elastic_beanstalk
|
247
249
|
|
250
|
+
def configuration_template
|
251
|
+
ElasticBeans::ConfigurationTemplate.new_from_existing(template_name, application: application, elastic_beanstalk: elastic_beanstalk)
|
252
|
+
end
|
253
|
+
|
248
254
|
def environment_description
|
249
255
|
elastic_beanstalk.describe_environments(
|
250
256
|
environment_names: [name],
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastic_beans
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.13.0.
|
4
|
+
version: 0.13.0.alpha4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Stegman
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-07-
|
11
|
+
date: 2017-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|