aws-rails-provisioner 0.0.0.rc1
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 +7 -0
- data/bin/aws-rails-provisioner +132 -0
- data/lib/aws-rails-provisioner.rb +42 -0
- data/lib/aws-rails-provisioner/build.rb +43 -0
- data/lib/aws-rails-provisioner/cdk_builder.rb +68 -0
- data/lib/aws-rails-provisioner/cdk_code_builder.rb +140 -0
- data/lib/aws-rails-provisioner/cdk_deployer.rb +62 -0
- data/lib/aws-rails-provisioner/code_build.rb +28 -0
- data/lib/aws-rails-provisioner/db_cluster.rb +299 -0
- data/lib/aws-rails-provisioner/errors.rb +24 -0
- data/lib/aws-rails-provisioner/fargate.rb +93 -0
- data/lib/aws-rails-provisioner/migration.rb +45 -0
- data/lib/aws-rails-provisioner/parser.rb +22 -0
- data/lib/aws-rails-provisioner/scaling.rb +448 -0
- data/lib/aws-rails-provisioner/service.rb +90 -0
- data/lib/aws-rails-provisioner/services.rb +44 -0
- data/lib/aws-rails-provisioner/subnet_selection.rb +20 -0
- data/lib/aws-rails-provisioner/utils.rb +89 -0
- data/lib/aws-rails-provisioner/version.rb +5 -0
- data/lib/aws-rails-provisioner/view.rb +29 -0
- data/lib/aws-rails-provisioner/views/fargate_stack.rb +100 -0
- data/lib/aws-rails-provisioner/views/init_stack.rb +35 -0
- data/lib/aws-rails-provisioner/views/pipeline_stack.rb +107 -0
- data/lib/aws-rails-provisioner/views/project.rb +33 -0
- data/lib/aws-rails-provisioner/vpc.rb +111 -0
- data/templates/fargate_stack.mustache +316 -0
- data/templates/init_stack.mustache +50 -0
- data/templates/pipeline_stack.mustache +156 -0
- data/templates/project.mustache +33 -0
- metadata +115 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module Aws::RailsProvisioner
|
2
|
+
class CodeBuild
|
3
|
+
|
4
|
+
def initialize(options = {})
|
5
|
+
@project_name = options[:project_name]
|
6
|
+
@description = options[:description]
|
7
|
+
@buildspec = options[:buildspec]
|
8
|
+
@image = options[:build_image].upcase
|
9
|
+
@timeout = options[:timeout]
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [String]
|
13
|
+
attr_reader :project_name
|
14
|
+
|
15
|
+
# @return [String]
|
16
|
+
attr_reader :description
|
17
|
+
|
18
|
+
# @return [String]
|
19
|
+
attr_reader :buildspec
|
20
|
+
|
21
|
+
# @return [Integer]
|
22
|
+
attr_reader :timeout
|
23
|
+
|
24
|
+
# @return [String]
|
25
|
+
attr_reader :image
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,299 @@
|
|
1
|
+
require 'aws-sdk-rds'
|
2
|
+
|
3
|
+
module Aws::RailsProvisioner
|
4
|
+
class DBCluster
|
5
|
+
|
6
|
+
# Configuration value under :db_cluster
|
7
|
+
#
|
8
|
+
# @param [Hash] options
|
9
|
+
#
|
10
|
+
# @option options [String] :username DB username, default
|
11
|
+
# to `SERVICE_NAMEDBAdminUser`
|
12
|
+
#
|
13
|
+
# @option options [required, String] :engine provide the engine for
|
14
|
+
# the database cluster: `aurora`, `aurora-mysql` or `aurora-postgresql`
|
15
|
+
#
|
16
|
+
# @option options [String] :engine_version version of the database to start,
|
17
|
+
# when not provided, default for the engine is used.
|
18
|
+
#
|
19
|
+
# @option options [String] :instance_type type of instance to start
|
20
|
+
# for the replicas, if not provided, a default :instance_type will
|
21
|
+
# be populated responding to the type of engine provided.
|
22
|
+
#
|
23
|
+
# @option options [String] :instance_subnet where to place the instances
|
24
|
+
# within the VPC, default to `isolated` subnet (recommend)
|
25
|
+
#
|
26
|
+
# @option options [Hash] :backup backup config for DB databases
|
27
|
+
#
|
28
|
+
# @example: at `aws-rails-provisioner.yml`
|
29
|
+
# backup:
|
30
|
+
# retention_days: 7
|
31
|
+
# preferred_window: '01:00-02:00'
|
32
|
+
# @see {Aws::RailsProvisioner::DBCluster::BackUp}
|
33
|
+
#
|
34
|
+
# @option options [String] :cluster_identifier An optional identifier for
|
35
|
+
# the cluster, If not supplied, a name is automatically generated
|
36
|
+
#
|
37
|
+
# @option options [required, String] :db_name name for the DB inside the cluster
|
38
|
+
#
|
39
|
+
# @option options [String] :removal_policy policy to apply when
|
40
|
+
# the cluster and its instances are removed from the stack or replaced during an update.
|
41
|
+
# `retain`, `destroy` available, default to `retain`
|
42
|
+
#
|
43
|
+
# @option options [String] :instance_identifier every replica is named
|
44
|
+
# by appending the replica number to this string, default to 'Instance'
|
45
|
+
#
|
46
|
+
# @option options [Integer] :instances how many replicas/instances
|
47
|
+
# to create, defaults to 2
|
48
|
+
#
|
49
|
+
# @option options [Integer] :port if not provided, default value is
|
50
|
+
# based on :engine
|
51
|
+
#
|
52
|
+
# @option options [String] :kms_key_arn the he KMS key arn for storage encryption
|
53
|
+
#
|
54
|
+
# @option options [String] :preferred_maintenance_window daily time
|
55
|
+
# range in 24-hours UTC format in which backups preferably execute
|
56
|
+
#
|
57
|
+
# @option oprions [Hash] :parameter_group default value is based on engine
|
58
|
+
# following example shows default for aurora postgres
|
59
|
+
#
|
60
|
+
# @example: at `aws-rails-provisioner.yml`
|
61
|
+
# parameter_group:
|
62
|
+
# family: 'aurora-postgresql9.6'
|
63
|
+
# description: 'created by AWS RailsProvisioner'
|
64
|
+
# parameters:
|
65
|
+
# key: value
|
66
|
+
# @see {Aws::RailsProvisioner::DBCluster::ParameterGroup}
|
67
|
+
#
|
68
|
+
# @see AWS CDK DatabaseClusterProps
|
69
|
+
def initialize(options = {})
|
70
|
+
@username = options[:username] || 'DBAdminUser'
|
71
|
+
|
72
|
+
@engine = _engine_type(options[:engine])
|
73
|
+
@engine_version = options[:engine_version]
|
74
|
+
@postgres = @engine == 'AURORA_POSTGRESQL'
|
75
|
+
unless @postgres
|
76
|
+
# MySql require username between 1 to 16
|
77
|
+
@username = options[:username][0..15]
|
78
|
+
end
|
79
|
+
|
80
|
+
@instance_type = options[:instance_type] || _default_instance_type
|
81
|
+
@instance_subnet = Aws::RailsProvisioner::Utils.subnet_type(
|
82
|
+
options[:instance_subnet] || 'isolated')
|
83
|
+
|
84
|
+
@backup = BackUp.new(options[:backup]) if options[:backup]
|
85
|
+
@db_name = options.fetch(:db_name)
|
86
|
+
@cluster_identifier = options[:cluster_identifier]
|
87
|
+
@removal_policy = Aws::RailsProvisioner::Utils.removal_policy(
|
88
|
+
options[:removal_policy] || 'retain')
|
89
|
+
|
90
|
+
@instance_identifier = options[:instance_identifier]
|
91
|
+
@instances = options[:instances] || 2
|
92
|
+
|
93
|
+
@kms_key = options[:kms_key_arn]
|
94
|
+
|
95
|
+
@port = options[:port]
|
96
|
+
@preferred_maintenance_window = options[:preferred_maintenance_window]
|
97
|
+
|
98
|
+
pg_opts = options[:parameter_group] || {}
|
99
|
+
pg_opts[:profile] = options[:profile] if options[:profile]
|
100
|
+
pg_opts[:stub_client] = options[:stub_client] # test only
|
101
|
+
@parameter_group = ParameterGroup.new(@engine, pg_opts)
|
102
|
+
@db_port = @port || _default_db_port
|
103
|
+
end
|
104
|
+
|
105
|
+
# @return [Boolean]
|
106
|
+
attr_reader :postgres
|
107
|
+
|
108
|
+
# @return [String]
|
109
|
+
attr_reader :username
|
110
|
+
|
111
|
+
# @return [String]
|
112
|
+
attr_reader :engine
|
113
|
+
|
114
|
+
# @return [String]
|
115
|
+
attr_reader :engine_version
|
116
|
+
|
117
|
+
# @return [String]
|
118
|
+
attr_reader :instance_type
|
119
|
+
|
120
|
+
# @return [String]
|
121
|
+
attr_reader :instance_subnet
|
122
|
+
|
123
|
+
# @return [String]
|
124
|
+
attr_reader :instance_identifier
|
125
|
+
|
126
|
+
# @return [Integer]
|
127
|
+
attr_reader :instances
|
128
|
+
|
129
|
+
# @return [String]
|
130
|
+
attr_reader :db_name
|
131
|
+
|
132
|
+
# @return [String]
|
133
|
+
attr_reader :cluster_identifier
|
134
|
+
|
135
|
+
# @return [String]
|
136
|
+
attr_reader :removal_policy
|
137
|
+
|
138
|
+
# @return [String]
|
139
|
+
attr_reader :kms_key
|
140
|
+
|
141
|
+
# @return [Integer]
|
142
|
+
attr_reader :port
|
143
|
+
|
144
|
+
# @return [String]
|
145
|
+
attr_reader :preferred_maintenance_window
|
146
|
+
|
147
|
+
# @return [ParameterGroup]
|
148
|
+
attr_reader :parameter_group
|
149
|
+
|
150
|
+
# @return [BackUp]
|
151
|
+
attr_reader :backup
|
152
|
+
|
153
|
+
# @return [Integer]
|
154
|
+
attr_reader :db_port
|
155
|
+
|
156
|
+
class BackUp
|
157
|
+
|
158
|
+
# @param [Hash] options
|
159
|
+
#
|
160
|
+
# @option options [required, Integer] :retention_days
|
161
|
+
# days to retain the backup
|
162
|
+
#
|
163
|
+
# @option options [String] :preferred_window A daily
|
164
|
+
# time range in 24-hours UTC format in which backups
|
165
|
+
# preferably execute
|
166
|
+
#
|
167
|
+
def initialize(options = {})
|
168
|
+
@retention_days = options[:retention_days]
|
169
|
+
@preferred_window = options[:preferred_window]
|
170
|
+
end
|
171
|
+
|
172
|
+
# @return [Integer]
|
173
|
+
attr_reader :retention_days
|
174
|
+
|
175
|
+
# @return [String]
|
176
|
+
attr_reader :preferred_window
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
class ParameterGroup
|
181
|
+
|
182
|
+
# @param [Hash] options
|
183
|
+
#
|
184
|
+
# @option options [String] :family
|
185
|
+
#
|
186
|
+
# @option options [String] :description
|
187
|
+
#
|
188
|
+
# @option options [Hash] :parameters
|
189
|
+
#
|
190
|
+
def initialize(engine, options = {})
|
191
|
+
# client
|
192
|
+
@profile = options[:profile]
|
193
|
+
|
194
|
+
@engine = engine
|
195
|
+
@family = options[:family] || _default_family
|
196
|
+
@description = options[:description] || 'created by AWS RailsProvisioner'
|
197
|
+
@cfn = !!options[:parameters]
|
198
|
+
unless @cfn
|
199
|
+
suffix = @engine.downcase.gsub(/_/, '-')
|
200
|
+
@name = "aws-rails-provisioner-default-#{suffix}"
|
201
|
+
_create_default_pg(options[:stub_client])
|
202
|
+
else
|
203
|
+
@parameters = Aws::RailsProvisioner::Utils.to_pairs(options[:parameters])
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# @return [Boolean]
|
208
|
+
attr_reader :cfn
|
209
|
+
|
210
|
+
# @return [String]
|
211
|
+
attr_reader :name
|
212
|
+
|
213
|
+
# @return [String]
|
214
|
+
attr_reader :family
|
215
|
+
|
216
|
+
# @return [String]
|
217
|
+
attr_reader :description
|
218
|
+
|
219
|
+
# @return [Array]
|
220
|
+
attr_reader :parameters
|
221
|
+
|
222
|
+
private
|
223
|
+
|
224
|
+
def _default_family
|
225
|
+
case @engine
|
226
|
+
when 'AURORA_POSTGRESQL' then 'aurora-postgresql9.6'
|
227
|
+
when 'AURORA_MYSQL' then 'aurora-mysql5.7'
|
228
|
+
when 'AURORA' then 'aurora5.6'
|
229
|
+
else
|
230
|
+
msg = 'Failed to locate a default family type for :engine'\
|
231
|
+
' provided, please provide :family for :parameter_group'
|
232
|
+
raise Aws::RailsProvisioner::Errors::ValidationError, msg
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# CDK creation requires parameters input
|
237
|
+
def _create_default_pg(stub_client)
|
238
|
+
if stub_client
|
239
|
+
rds = Aws::RDS::Client.new(stub_responses: true)
|
240
|
+
else
|
241
|
+
rds = @profile ? Aws::RDS::Client.new(profile: @profile) :
|
242
|
+
Aws::RDS::Client.new
|
243
|
+
end
|
244
|
+
|
245
|
+
begin
|
246
|
+
rds.create_db_cluster_parameter_group(
|
247
|
+
db_parameter_group_family: @family,
|
248
|
+
description: @description,
|
249
|
+
db_cluster_parameter_group_name: @name
|
250
|
+
)
|
251
|
+
rescue Aws::RDS::Errors::DBParameterGroupAlreadyExists
|
252
|
+
# Cluster Parameter Group already exists
|
253
|
+
# do nothing
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|
258
|
+
|
259
|
+
private
|
260
|
+
|
261
|
+
def _engine_type(engine)
|
262
|
+
type = engine.dup
|
263
|
+
case type.downcase
|
264
|
+
when 'aurora-postgresql' then 'AURORA_POSTGRESQL'
|
265
|
+
when 'aurora-mysql' then 'AURORA_MYSQL'
|
266
|
+
when 'aurora' then 'AURORA'
|
267
|
+
else
|
268
|
+
msg = "DB engine: #{engine.inspect} not supported"
|
269
|
+
raise Aws::RailsProvisioner::Errors::ValidationError, msg
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def _default_instance_type
|
274
|
+
case @engine
|
275
|
+
when 'AURORA_POSTGRESQL' then 'r4.large'
|
276
|
+
when 'AURORA_MYSQL' then 'r5.large'
|
277
|
+
when 'AURORA' then 'r5.large'
|
278
|
+
else
|
279
|
+
msg = 'Failed to locate a default instance type for :engine'\
|
280
|
+
' provided, please provide :instance_type'
|
281
|
+
raise Aws::RailsProvisioner::Errors::ValidationError, msg
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def _default_db_port
|
286
|
+
case @engine
|
287
|
+
when 'AURORA_POSTGRESQL' then 3306
|
288
|
+
when 'AURORA_MYSQL' then 3306
|
289
|
+
when 'AURORA' then 3306
|
290
|
+
else
|
291
|
+
msg = 'Failed to locate a default db port for :engine'\
|
292
|
+
' provided, please provide :port'
|
293
|
+
raise Aws::RailsProvisioner::Errors::ValidationError, msg
|
294
|
+
end
|
295
|
+
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|
299
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Aws::RailsProvisioner
|
2
|
+
module Errors
|
3
|
+
|
4
|
+
class ValidationError < RuntimeError; end
|
5
|
+
|
6
|
+
class InvalidCommandOption < RuntimeError
|
7
|
+
|
8
|
+
def initialize(type, option)
|
9
|
+
msg = "invalid option: #{option}, #{option} is valid for `#{type}` command."
|
10
|
+
super(msg)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
class InvalidYAMLFile < RuntimeError
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
msg = "Invalid `aws-rails-provisioner.yml` file provided."
|
19
|
+
super(msg)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module Aws::RailsProvisioner
|
2
|
+
class Fargate
|
3
|
+
|
4
|
+
# Configuration value under :fargate
|
5
|
+
#
|
6
|
+
# @param [Hash] options
|
7
|
+
#
|
8
|
+
# @option options [Integer] :desired_count number of
|
9
|
+
# desired copies of running tasks, default to 2
|
10
|
+
#
|
11
|
+
# @option options [Boolean] :public when `true` (default)
|
12
|
+
# Application Load Balancer will be internet-facing
|
13
|
+
#
|
14
|
+
# @option options [String] :domain_name domain name for the service,
|
15
|
+
# e.g. api.example.com
|
16
|
+
#
|
17
|
+
# @option options [String] :domain_zone route53 hosted zone for the domain,
|
18
|
+
# e.g. "example.com.".
|
19
|
+
#
|
20
|
+
# @option options [String] :service_name name for the Fargate service
|
21
|
+
#
|
22
|
+
# @option options [Integer] :memory default to 512 (MB)
|
23
|
+
#
|
24
|
+
# @option options [Integer] :cpu default to 256 (units)
|
25
|
+
#
|
26
|
+
# @option options [Hash] :envs environment variable pairs
|
27
|
+
# for the container used by this Fargate task
|
28
|
+
#
|
29
|
+
# @option options [String] :container_name defaults to `FargateTaskContainer`
|
30
|
+
#
|
31
|
+
# @option options [Integer] :container_port defaults to 80
|
32
|
+
#
|
33
|
+
# @option options [String] :certificate certificate arn. Certificate Manager
|
34
|
+
# certificate to associate with the load balancer. Setting this option
|
35
|
+
# will set the load balancer port to 443.
|
36
|
+
#
|
37
|
+
def initialize(options = {})
|
38
|
+
# code gen only
|
39
|
+
@has_db = !!options[:has_db]
|
40
|
+
|
41
|
+
@service_name = options[:service_name]
|
42
|
+
@desired_count = options[:desired_count] || 2
|
43
|
+
@public = !!options[:public]
|
44
|
+
@domain_name = options[:domain_name]
|
45
|
+
@domain_zone = options[:domain_zone]
|
46
|
+
@certificate = options[:certificate]
|
47
|
+
|
48
|
+
@memory = options[:memory] || 512
|
49
|
+
@cpu = options[:cpu] || 256
|
50
|
+
@envs = Aws::RailsProvisioner::Utils.to_pairs(options[:envs]) if options[:envs]
|
51
|
+
@container_port = options[:container_port] || 80
|
52
|
+
@container_name = options[:container_name] || 'FargateTaskContainer'
|
53
|
+
end
|
54
|
+
|
55
|
+
# @api private
|
56
|
+
# @return [Boolean]
|
57
|
+
attr_reader :has_db
|
58
|
+
|
59
|
+
# @return [Integer]
|
60
|
+
attr_reader :desired_count
|
61
|
+
|
62
|
+
# @return [String]
|
63
|
+
attr_reader :service_name
|
64
|
+
|
65
|
+
# @return [Boolean]
|
66
|
+
attr_reader :public
|
67
|
+
|
68
|
+
# @return [String]
|
69
|
+
attr_reader :domain_name
|
70
|
+
|
71
|
+
# @return [String]
|
72
|
+
attr_reader :domain_zone
|
73
|
+
|
74
|
+
# @return [String]
|
75
|
+
attr_reader :certificate
|
76
|
+
|
77
|
+
# @return [Array]
|
78
|
+
attr_reader :envs
|
79
|
+
|
80
|
+
# @return [Integer]
|
81
|
+
attr_reader :memory
|
82
|
+
|
83
|
+
# @return [Integer]
|
84
|
+
attr_reader :cpu
|
85
|
+
|
86
|
+
# @return [Integer]
|
87
|
+
attr_reader :container_port
|
88
|
+
|
89
|
+
# @return [String]
|
90
|
+
attr_reader :container_name
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Aws::RailsProvisioner
|
2
|
+
class Migration < Aws::RailsProvisioner::CodeBuild
|
3
|
+
|
4
|
+
# An AWS CodeBuild Project that runs DB migration
|
5
|
+
# for the Ruby on Rails App inside private subnet of
|
6
|
+
# the VPC
|
7
|
+
#
|
8
|
+
# configuration for :migration
|
9
|
+
#
|
10
|
+
# @param [Hash] options
|
11
|
+
#
|
12
|
+
# @option options [String] :project_name name for
|
13
|
+
# the CodeBuild project, default to 'SERVICE_NAMEDBMigration'
|
14
|
+
#
|
15
|
+
# @option options [String] :description description for this
|
16
|
+
# CodeBuild project, default to 'running DB Migration for
|
17
|
+
# the rails app inside private subnet'
|
18
|
+
#
|
19
|
+
# @option options [String] :buildspec buildspec.yml file path, default
|
20
|
+
# to `buildspec-db.yml` under root directory, using template under
|
21
|
+
# `buildspecs/`
|
22
|
+
#
|
23
|
+
# @option options [String] :build_image default to codebuild `standard_1_0`
|
24
|
+
# full list of supported images see:
|
25
|
+
# https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-codebuild.LinuxBuildImage.html
|
26
|
+
#
|
27
|
+
# @option options [Integer] :timeout number of minutes after which
|
28
|
+
# CodeBuild stops the build if it’s not complete
|
29
|
+
#
|
30
|
+
def initialize(options = {})
|
31
|
+
unless options[:description]
|
32
|
+
options[:description] = 'running DB Migration for'\
|
33
|
+
' the rails app inside private subnet'
|
34
|
+
end
|
35
|
+
unless options[:buildspec]
|
36
|
+
options[:buildspec] = 'buildspec-db.yml'
|
37
|
+
end
|
38
|
+
unless options[:build_image]
|
39
|
+
options[:build_image] = 'standard_1_0'
|
40
|
+
end
|
41
|
+
# TODO envs support?
|
42
|
+
super(options)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|