elastic_beans 0.13.0.alpha3 → 0.13.0.alpha4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|