elastic_beans 0.2.0 → 0.3.0
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 +91 -16
- data/exe/beans +26 -20
- data/lib/elastic_beans/application.rb +33 -1
- data/lib/elastic_beans/application_version.rb +18 -3
- data/lib/elastic_beans/aws/cloudformation_stack.rb +2 -0
- data/lib/elastic_beans/command/configure.rb +12 -18
- data/lib/elastic_beans/command/create.rb +8 -4
- data/lib/elastic_beans/command/deploy.rb +3 -3
- data/lib/elastic_beans/command/exec.rb +4 -3
- data/lib/elastic_beans/command/scale.rb +2 -2
- data/lib/elastic_beans/command/set_env.rb +4 -3
- data/lib/elastic_beans/command/talk.rb +1 -0
- data/lib/elastic_beans/command/version.rb +1 -0
- data/lib/elastic_beans/command.rb +2 -0
- data/lib/elastic_beans/configuration_template/base.rb +12 -2
- data/lib/elastic_beans/configuration_template/exec.rb +6 -0
- data/lib/elastic_beans/configuration_template/scheduler.rb +4 -0
- data/lib/elastic_beans/configuration_template/webserver.rb +11 -4
- data/lib/elastic_beans/configuration_template/worker.rb +6 -0
- data/lib/elastic_beans/configuration_template.rb +32 -11
- data/lib/elastic_beans/dns_entry.rb +2 -0
- data/lib/elastic_beans/env_vars.rb +6 -0
- data/lib/elastic_beans/environment/exec.rb +13 -4
- data/lib/elastic_beans/environment/scheduler.rb +13 -4
- data/lib/elastic_beans/environment/webserver.rb +13 -4
- data/lib/elastic_beans/environment/worker.rb +15 -4
- data/lib/elastic_beans/environment.rb +74 -18
- data/lib/elastic_beans/error/environments_not_ready.rb +2 -0
- data/lib/elastic_beans/error.rb +1 -0
- data/lib/elastic_beans/exec/init.rb +2 -0
- data/lib/elastic_beans/exec/sqs_consumer.rb +2 -0
- data/lib/elastic_beans/network.rb +1 -0
- data/lib/elastic_beans/rack/exec.rb +5 -0
- data/lib/elastic_beans/ui.rb +2 -0
- data/lib/elastic_beans/version.rb +1 -1
- metadata +2 -2
@@ -3,14 +3,15 @@ require "elastic_beans/error/environments_not_ready"
|
|
3
3
|
|
4
4
|
module ElasticBeans
|
5
5
|
module Command
|
6
|
+
# :nodoc: all
|
6
7
|
class SetEnv
|
7
|
-
USAGE = "setenv
|
8
|
+
USAGE = "setenv KEY=[value] [KEY=[value]]..."
|
8
9
|
DESC = "Update environment variables in the Elastic Beanstalk application"
|
9
10
|
LONG_DESC = <<-LONG_DESC
|
10
11
|
Update environment variables in the Elastic Beanstalk application.
|
11
|
-
|
12
|
+
These are stored in S3 to avoid the 4096-byte limit on environment variables in Elastic Beanstalk.
|
13
|
+
Restarts all running environments so they load the updated environment.
|
12
14
|
|
13
|
-
Requires the application name.
|
14
15
|
Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
|
15
16
|
LONG_DESC
|
16
17
|
|
@@ -2,13 +2,19 @@ require "elastic_beans/error"
|
|
2
2
|
|
3
3
|
module ElasticBeans
|
4
4
|
class ConfigurationTemplate
|
5
|
+
# The "base" configuration template stored in the Elastic Beanstalk application.
|
6
|
+
# Common settings are stored here, such as networking settings and environment variables.
|
7
|
+
# Used as a "source configuration" when creating other configuration templates, so that new templates share the
|
8
|
+
# existing configuration.
|
5
9
|
class Base < ElasticBeans::ConfigurationTemplate
|
10
|
+
# The solution stack used for a new application. Should not be hardcoded, but here we are.
|
6
11
|
SOLUTION_STACK_NAME = "64bit Amazon Linux 2016.09 v2.2.0 running Ruby 2.3 (Puma)"
|
7
12
|
|
8
13
|
def initialize(**args)
|
9
14
|
super(name: "base", **args)
|
10
15
|
end
|
11
16
|
|
17
|
+
# Overrides ElasticBeans::ConfigurationTemplate#upsert to add the solution stack to the base configuration.
|
12
18
|
def upsert(**args)
|
13
19
|
@option_settings = build_option_settings(**args)
|
14
20
|
if configuration_settings_description
|
@@ -32,16 +38,18 @@ module ElasticBeans
|
|
32
38
|
|
33
39
|
protected
|
34
40
|
|
41
|
+
# Constructs the common configuration for all environments.
|
42
|
+
# +network+, +database_url+, +secret_key_base+, +keypair+, and +iam+ are all required on first run.
|
35
43
|
def build_option_settings(
|
36
44
|
network: nil,
|
37
45
|
database_url: nil,
|
38
46
|
secret_key_base: nil,
|
47
|
+
keypair: nil,
|
48
|
+
iam: nil,
|
39
49
|
image_id: nil,
|
40
50
|
instance_type: nil,
|
41
|
-
keypair: nil,
|
42
51
|
min_size: nil,
|
43
52
|
max_size: nil,
|
44
|
-
iam: nil,
|
45
53
|
**_
|
46
54
|
)
|
47
55
|
instance_profile_setting = template_option_setting(namespace: "aws:autoscaling:launchconfiguration", option_name: "IamInstanceProfile", override: instance_profile(iam))
|
@@ -126,6 +134,8 @@ module ElasticBeans
|
|
126
134
|
network.vpc if network
|
127
135
|
end
|
128
136
|
|
137
|
+
# :nodoc: all
|
138
|
+
# @!visibility private
|
129
139
|
class MissingInstanceProfileError < ElasticBeans::Error
|
130
140
|
def message
|
131
141
|
"Could not find Elastic Beanstalk instance profile." \
|
@@ -3,6 +3,8 @@ require "elastic_beans/error"
|
|
3
3
|
|
4
4
|
module ElasticBeans
|
5
5
|
class ConfigurationTemplate
|
6
|
+
# The "exec" configuration template stored in the Elastic Beanstalk application.
|
7
|
+
# Settings for the exec environment are stored here, such as the exec queue URL and the logging endpoint.
|
6
8
|
class Exec < ElasticBeans::ConfigurationTemplate::Base
|
7
9
|
def initialize(**args)
|
8
10
|
super(name: "exec", **args)
|
@@ -10,6 +12,8 @@ module ElasticBeans
|
|
10
12
|
|
11
13
|
protected
|
12
14
|
|
15
|
+
# Constructs the configuration for the exec environment.
|
16
|
+
# +logging_endpoint+, if provided, must be a valid HTTPS URL.
|
13
17
|
def build_option_settings(logging_endpoint: nil, **_)
|
14
18
|
if logging_endpoint
|
15
19
|
begin
|
@@ -36,6 +40,8 @@ module ElasticBeans
|
|
36
40
|
super + settings
|
37
41
|
end
|
38
42
|
|
43
|
+
# :nodoc: all
|
44
|
+
# @!visibility private
|
39
45
|
class InvalidLoggingEndpointError < ElasticBeans::Error
|
40
46
|
def initialize(logging_endpoint:)
|
41
47
|
@logging_endpoint = logging_endpoint
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module ElasticBeans
|
2
2
|
class ConfigurationTemplate
|
3
|
+
# The "scheduler" configuration template stored in the Elastic Beanstalk application.
|
4
|
+
# Settings for the scheduler environment are stored here.
|
3
5
|
class Scheduler < ElasticBeans::ConfigurationTemplate::Base
|
4
6
|
def initialize(**args)
|
5
7
|
super(name: "scheduler", **args)
|
@@ -7,6 +9,8 @@ module ElasticBeans
|
|
7
9
|
|
8
10
|
protected
|
9
11
|
|
12
|
+
# Constructs the configuration for the scheduler environment.
|
13
|
+
# No special options here!
|
10
14
|
def build_option_settings(**_)
|
11
15
|
super + [
|
12
16
|
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTP:80/"),
|
@@ -2,6 +2,8 @@ require "elastic_beans/error"
|
|
2
2
|
|
3
3
|
module ElasticBeans
|
4
4
|
class ConfigurationTemplate
|
5
|
+
# The "webserver" configuration template stored in the Elastic Beanstalk application.
|
6
|
+
# Settings for the webserver environment are stored here.
|
5
7
|
class Webserver < ElasticBeans::ConfigurationTemplate::Base
|
6
8
|
def initialize(**args)
|
7
9
|
super(name: "webserver", **args)
|
@@ -9,10 +11,12 @@ module ElasticBeans
|
|
9
11
|
|
10
12
|
protected
|
11
13
|
|
12
|
-
|
14
|
+
# Constructs the configuration for the webserver environment.
|
15
|
+
# All arguments are required on first run.
|
16
|
+
def build_option_settings(network: nil, public_key: nil, ssl_certificate_arn: nil, **_)
|
13
17
|
public_key_policy_names_setting = template_option_setting(namespace: "aws:elb:policies:backendencryption", option_name: "PublicKeyPolicyNames", default: "backendkey")
|
14
18
|
public_key_setting = template_option_setting(namespace: "aws:elb:policies:#{public_key_policy_names_setting[:value]}", option_name: "PublicKey", override: public_key)
|
15
|
-
ssl_certificate_setting = template_option_setting(namespace: "aws:elb:listener:443", option_name: "SSLCertificateId", override:
|
19
|
+
ssl_certificate_setting = template_option_setting(namespace: "aws:elb:listener:443", option_name: "SSLCertificateId", override: ssl_certificate_arn)
|
16
20
|
if public_key_setting[:value].nil? || ssl_certificate_setting[:value].nil?
|
17
21
|
raise NoEncryptionSettingsError
|
18
22
|
end
|
@@ -42,13 +46,16 @@ module ElasticBeans
|
|
42
46
|
network.elb_security_groups[0] if network
|
43
47
|
end
|
44
48
|
|
49
|
+
# :nodoc: all
|
50
|
+
# @!visibility private
|
45
51
|
class NoEncryptionSettingsError < ElasticBeans::Error
|
46
52
|
def message
|
47
53
|
require "elastic_beans/command/configure"
|
48
54
|
<<-MESSAGE
|
49
|
-
Missing required end-to-end encryption settings.
|
55
|
+
Missing required end-to-end encryption settings.
|
56
|
+
Please re-run `#{command_as_string "configure"}` and make sure to specify SSL certificate ARN and internal public key.
|
50
57
|
|
51
|
-
|
58
|
+
#{`#{$0} help configure`}
|
52
59
|
MESSAGE
|
53
60
|
end
|
54
61
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
module ElasticBeans
|
2
2
|
class ConfigurationTemplate
|
3
|
+
# The worker configuration templates stored in the Elastic Beanstalk application.
|
4
|
+
# Settings for the worker environments are stored here.
|
5
|
+
# This class is used to construct multiple worker configuration templates, one per queue.
|
3
6
|
class Worker < ElasticBeans::ConfigurationTemplate::Base
|
4
7
|
attr_reader :queue
|
5
8
|
|
@@ -10,6 +13,9 @@ module ElasticBeans
|
|
10
13
|
|
11
14
|
protected
|
12
15
|
|
16
|
+
# Constructs the configuration for the worker environments.
|
17
|
+
# No special arguments, the +queue+ name is stored from the initializer and is used to look up the appropriate
|
18
|
+
# URL.
|
13
19
|
def build_option_settings(**_)
|
14
20
|
super + [
|
15
21
|
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTP:80/"),
|
@@ -5,11 +5,20 @@ require "elastic_beans/configuration_template/webserver"
|
|
5
5
|
require "elastic_beans/configuration_template/worker"
|
6
6
|
|
7
7
|
module ElasticBeans
|
8
|
+
# An Elastic Beanstalk saved configuration (also known as a configuration template) which may or may not exist.
|
9
|
+
#
|
10
|
+
# This is an abstract class; use the provided factories in this class or use a subclass (contained within this
|
11
|
+
# namespace) directly.
|
8
12
|
class ConfigurationTemplate
|
13
|
+
# :category: Internal
|
9
14
|
WORKER_TEMPLATE_NAME_PATTERN = /\Aworker-(?<queue>\w+)\z/
|
10
15
|
|
11
16
|
attr_reader :name
|
12
17
|
|
18
|
+
# Create a new configuration template of a particular +type+.
|
19
|
+
# See the particular subclass being created for details on arguments.
|
20
|
+
#
|
21
|
+
# Raises an error if the +type+ is not recognized.
|
13
22
|
def self.new_by_type(type, **args)
|
14
23
|
case type
|
15
24
|
when "base"
|
@@ -27,6 +36,10 @@ module ElasticBeans
|
|
27
36
|
end
|
28
37
|
end
|
29
38
|
|
39
|
+
# Create a representation of an existing configuration template.
|
40
|
+
# Uses the +template_name+ to discover the appropriate type (and queue, in the case of a worker).
|
41
|
+
#
|
42
|
+
# Raises an error if the +template_name+ is not recognized.
|
30
43
|
def self.new_from_existing(template_name, **args)
|
31
44
|
case template_name
|
32
45
|
when "base"
|
@@ -45,6 +58,7 @@ module ElasticBeans
|
|
45
58
|
end
|
46
59
|
end
|
47
60
|
|
61
|
+
# :category: Internal
|
48
62
|
def initialize(
|
49
63
|
name:,
|
50
64
|
application:,
|
@@ -56,6 +70,7 @@ module ElasticBeans
|
|
56
70
|
@elastic_beanstalk = elastic_beanstalk
|
57
71
|
end
|
58
72
|
|
73
|
+
# :category: Internal
|
59
74
|
def option_settings
|
60
75
|
# do not fetch option settings from Elastic Beanstalk, because those cannot be naively used.
|
61
76
|
# the set built in #build_option_settings is what we care about.
|
@@ -63,6 +78,9 @@ module ElasticBeans
|
|
63
78
|
raise MissingConfigurationError
|
64
79
|
end
|
65
80
|
|
81
|
+
# Create or update the configuration template in Elastic Beanstalk.
|
82
|
+
# Arguments are passed to #build_option_settings.
|
83
|
+
# See the appropriate subclass for what the arguments should be.
|
66
84
|
def upsert(**args)
|
67
85
|
@option_settings = build_option_settings(**args)
|
68
86
|
if configuration_settings_description
|
@@ -86,7 +104,10 @@ module ElasticBeans
|
|
86
104
|
|
87
105
|
protected
|
88
106
|
|
89
|
-
|
107
|
+
# :category: Internal
|
108
|
+
attr_reader :application
|
109
|
+
# :category: Internal
|
110
|
+
attr_reader :elastic_beanstalk
|
90
111
|
|
91
112
|
def build_option_settings(**_)
|
92
113
|
[]
|
@@ -123,6 +144,8 @@ module ElasticBeans
|
|
123
144
|
option_setting.merge!(value: setting[:value])
|
124
145
|
end
|
125
146
|
|
147
|
+
# :nodoc: all
|
148
|
+
# @!visibility private
|
126
149
|
class InvalidConfigurationError < ElasticBeans::Error
|
127
150
|
include Nesty::NestedError
|
128
151
|
|
@@ -139,6 +162,8 @@ module ElasticBeans
|
|
139
162
|
end
|
140
163
|
end
|
141
164
|
|
165
|
+
# :nodoc: all
|
166
|
+
# @!visibility private
|
142
167
|
class MissingConfigurationError < ElasticBeans::Error
|
143
168
|
include Nesty::NestedError
|
144
169
|
|
@@ -149,23 +174,19 @@ module ElasticBeans
|
|
149
174
|
def message
|
150
175
|
require "elastic_beans/command/configure"
|
151
176
|
msg = <<-MESSAGE
|
152
|
-
Some configuration must be set before creating an environment
|
153
|
-
|
154
|
-
* keypair
|
155
|
-
* SSL configuration
|
156
|
-
* environment variables that Rails always requires
|
157
|
-
* DATABASE_URL
|
158
|
-
* SECRET_KEY_BASE
|
159
|
-
|
160
|
-
#{$0} #{ElasticBeans::Command::Configure::USAGE}
|
177
|
+
Some configuration is missing and must be set before creating or updating an environment.
|
161
178
|
MESSAGE
|
162
179
|
if nested
|
163
|
-
msg
|
180
|
+
msg << "The error from AWS was \"#{nested.message}\"\n#{msg}\n"
|
181
|
+
else
|
182
|
+
msg << "Please re-run `#{command_as_string "configure"}`.\n\n#{`#{$0} help configure`}"
|
164
183
|
end
|
165
184
|
msg
|
166
185
|
end
|
167
186
|
end
|
168
187
|
|
188
|
+
# :nodoc: all
|
189
|
+
# @!visibility private
|
169
190
|
class UnknownConfigurationType < ElasticBeans::Error
|
170
191
|
def initialize(type:)
|
171
192
|
@type = type
|
@@ -3,6 +3,9 @@ require "aws-sdk"
|
|
3
3
|
require "elastic_beans/error"
|
4
4
|
|
5
5
|
module ElasticBeans
|
6
|
+
# Interfaces with environment variable storage for the Elastic Beanstalk application.
|
7
|
+
# Environment variables are stored in JSON in S3 to avoid the 4096-byte limit on environment variables in Elastic
|
8
|
+
# Beanstalk. An ebextension is used to inject these into the environment variables on the running instance.
|
6
9
|
class EnvVars
|
7
10
|
def initialize(application:, s3:)
|
8
11
|
@application = application
|
@@ -13,6 +16,7 @@ module ElasticBeans
|
|
13
16
|
@s3_key ||= "#{application.name}/env_vars.json"
|
14
17
|
end
|
15
18
|
|
19
|
+
# Updates the environment variables stored in S3 by merging it with the given +env_hash+.
|
16
20
|
def update(env_hash)
|
17
21
|
body = env_script(existing_env_hash.merge(env_hash))
|
18
22
|
s3.put_object(bucket: application.bucket_name, key: s3_key, body: body)
|
@@ -37,6 +41,8 @@ module ElasticBeans
|
|
37
41
|
raise CannotAccessConfigError.new(bucket_name: application.bucket_name, key: s3_key)
|
38
42
|
end
|
39
43
|
|
44
|
+
# :nodoc: all
|
45
|
+
# @!visibility private
|
40
46
|
class CannotAccessConfigError < ElasticBeans::Error
|
41
47
|
def initialize(bucket_name:, key:)
|
42
48
|
@bucket_name = bucket_name
|
@@ -1,14 +1,23 @@
|
|
1
1
|
module ElasticBeans
|
2
2
|
class Environment
|
3
|
+
# The "exec" environment for executing one-off commands.
|
3
4
|
class Exec < ElasticBeans::Environment
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
# :category: Internal
|
6
|
+
TYPE = "exec"
|
7
|
+
# :category: Internal
|
7
8
|
TIER_NAME = "Worker"
|
9
|
+
# :category: Internal
|
8
10
|
TIER_TYPE = "SQS/HTTP"
|
9
11
|
|
12
|
+
# Returns "exec"
|
13
|
+
def type
|
14
|
+
TYPE
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
10
19
|
def template_name
|
11
|
-
|
20
|
+
type
|
12
21
|
end
|
13
22
|
|
14
23
|
def tier_name
|
@@ -1,14 +1,23 @@
|
|
1
1
|
module ElasticBeans
|
2
2
|
class Environment
|
3
|
+
# The "scheduler" environment for processing periodic tasks.
|
3
4
|
class Scheduler < ElasticBeans::Environment
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
# :category: Internal
|
6
|
+
TYPE = "scheduler"
|
7
|
+
# :category: Internal
|
7
8
|
TIER_NAME = "Worker"
|
9
|
+
# :category: Internal
|
8
10
|
TIER_TYPE = "SQS/HTTP"
|
9
11
|
|
12
|
+
# Returns "scheduler"
|
13
|
+
def type
|
14
|
+
TYPE
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
10
19
|
def template_name
|
11
|
-
|
20
|
+
type
|
12
21
|
end
|
13
22
|
|
14
23
|
def tier_name
|
@@ -1,14 +1,23 @@
|
|
1
1
|
module ElasticBeans
|
2
2
|
class Environment
|
3
|
+
# The "webserver" environment for responding to web requests.
|
3
4
|
class Webserver < ElasticBeans::Environment
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
# :category: Internal
|
6
|
+
TYPE = "webserver"
|
7
|
+
# :category: Internal
|
7
8
|
TIER_NAME = "Webserver"
|
9
|
+
# :category: Internal
|
8
10
|
TIER_TYPE = "Standard"
|
9
11
|
|
12
|
+
# Returns "webserver"
|
13
|
+
def type
|
14
|
+
TYPE
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
10
19
|
def template_name
|
11
|
-
|
20
|
+
type
|
12
21
|
end
|
13
22
|
|
14
23
|
def tier_name
|
@@ -1,6 +1,15 @@
|
|
1
1
|
module ElasticBeans
|
2
2
|
class Environment
|
3
|
+
# The worker environments for background job execution.
|
4
|
+
# This class is used to construct multiple worker environments, one per queue.
|
3
5
|
class Worker < ElasticBeans::Environment
|
6
|
+
# :category: Internal
|
7
|
+
TYPE = "worker"
|
8
|
+
# :category: Internal
|
9
|
+
TIER_NAME = "Worker"
|
10
|
+
# :category: Internal
|
11
|
+
TIER_TYPE = "SQS/HTTP"
|
12
|
+
|
4
13
|
attr_reader :queue
|
5
14
|
|
6
15
|
def initialize(name, queue:, **_)
|
@@ -8,13 +17,15 @@ module ElasticBeans
|
|
8
17
|
@queue = queue
|
9
18
|
end
|
10
19
|
|
11
|
-
|
20
|
+
# Returns "worker"
|
21
|
+
def type
|
22
|
+
TYPE
|
23
|
+
end
|
12
24
|
|
13
|
-
|
14
|
-
TIER_TYPE = "SQS/HTTP"
|
25
|
+
protected
|
15
26
|
|
16
27
|
def template_name
|
17
|
-
@template_name ||= "
|
28
|
+
@template_name ||= "#{type}-#{queue}"
|
18
29
|
end
|
19
30
|
|
20
31
|
def tier_name
|