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.
@@ -0,0 +1,33 @@
1
+ module Aws::RailsProvisioner
2
+ module Views
3
+ # @api private
4
+ class Project < View
5
+
6
+ def initialize(options = {})
7
+ @services = options[:services]
8
+ @stack_prefix = options[:stack_prefix]
9
+ @path_prefix = options[:path_prefix]
10
+ end
11
+
12
+ # @return [String]
13
+ attr_reader :stack_prefix
14
+
15
+ # @return [String]
16
+ attr_reader :path_prefix
17
+
18
+ def stacks
19
+ stacks = []
20
+ @services.each do |svc|
21
+ stacks << {
22
+ name: svc.name,
23
+ const_prefix: svc.const_prefix,
24
+ path_prefix: svc.path_prefix,
25
+ stack_prefix: svc.stack_prefix,
26
+ enable_cicd: svc.enable_cicd
27
+ }
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,111 @@
1
+ module Aws::RailsProvisioner
2
+ class Vpc
3
+
4
+ SUBNETS_DEFAULTS = {
5
+ application: {
6
+ cidr_mask: 24,
7
+ type: 'private'
8
+ },
9
+ ingress: {
10
+ cidr_mask: 24,
11
+ type: 'public'
12
+ },
13
+ database: {
14
+ cidr_mask: 28,
15
+ type: 'isolated'
16
+ }
17
+ }
18
+
19
+ # Configuration value under :vpc
20
+ # @param [Hash] options
21
+ #
22
+ # @option options [Integer] :max_azs maximum number
23
+ # of AZs to use in this region, default to 3
24
+ #
25
+ # @option options [String] :cidr CIDR range to use for
26
+ # the VPC, default to '10.0.0.0/21'
27
+ #
28
+ # @option options [Hash] :subnets subnets configuration
29
+ # to build for each AZ, default to following example:
30
+ #
31
+ # @example: at `aws-rails-provisioner.yml`
32
+ # subnets:
33
+ # application:
34
+ # cidr_mask: 24
35
+ # type: private
36
+ # ingress:
37
+ # cidr_mask: 24
38
+ # type: public
39
+ # database:
40
+ # cidr_mask: 28
41
+ # type: isolate
42
+ #
43
+ # @option options [Boolean] :enable_dns whether the DNS
44
+ # resolution is supported for the VPC, default to `true`
45
+ #
46
+ # @option options [Integer] :nat_gateways number of NAT Gateways
47
+ # to create, default to :maxAz value
48
+ #
49
+ # @option options [Hash] :nat_gateway_subnets choose the subnets
50
+ # that will have NAT Gateway attached, default to public:
51
+ #
52
+ # @example: at `aws-rails-provisioner.yml`
53
+ # nat_gateway_subnets:
54
+ # type: public
55
+ #
56
+ # Note: Either subnet `:type` or `:name` can be provided
57
+ # @see {Aws::RailsProvisioner::SubnetSelection}
58
+ #
59
+ # @see AWS CDK VpcNetworkProps
60
+ def initialize(options = {})
61
+ @max_azs = options[:max_azs] || 3
62
+ @cidr = options[:cidr] || '10.0.0.0/21'
63
+ subnets_config = options[:subnets] || SUBNETS_DEFAULTS
64
+ @subnets = subnets_config.map do |name, config|
65
+ Subnet.new(
66
+ cidr_mask: config[:cidr_mask],
67
+ subnet_name: name,
68
+ type: config[:type]
69
+ )
70
+ end
71
+ @enable_dns = options[:enable_dns].nil? ? true : !!options[:enable_dns]
72
+ @nat_gateways = options[:nat_gateways] || @max_azs
73
+ @nat_gateway_subnets = Aws::RailsProvisioner::SubnetSelection.new(options[:nat_gateway_subnets]) if options[:nat_gateway_subnets]
74
+ end
75
+
76
+ # @return [Integer]
77
+ attr_reader :max_azs
78
+
79
+ # @return [Integer]
80
+ attr_reader :nat_gateways
81
+
82
+ # @return [Aws::RailsProvisioner::SubnetSelection | nil]
83
+ attr_reader :nat_gateway_subnets
84
+
85
+ # @return [String]
86
+ attr_reader :cidr
87
+
88
+ # @return [Boolean]
89
+ attr_reader :enable_dns
90
+
91
+ # @return [Array|nil]
92
+ attr_reader :subnets
93
+
94
+ class Subnet
95
+
96
+ def initialize(options)
97
+ @subnet_name = options.fetch(:subnet_name)
98
+ @cidr_mask = options.fetch(:cidr_mask)
99
+ @type = Aws::RailsProvisioner::Utils.subnet_type(options.fetch(:type))
100
+ end
101
+
102
+ attr_reader :subnet_name
103
+
104
+ attr_reader :cidr_mask
105
+
106
+ attr_reader :type
107
+
108
+ end
109
+
110
+ end
111
+ end
@@ -0,0 +1,316 @@
1
+ import cdk = require('@aws-cdk/core');
2
+ {{#services}}
3
+ import {{abbr}} = require('@aws-cdk/aws-{{value}}');
4
+ {{/services}}
5
+
6
+ interface {{stack_prefix}}FargateStackProps {
7
+ vpc: ec2.IVpc,
8
+ cluster: ecs.ICluster,
9
+ }
10
+
11
+ export class {{stack_prefix}}FargateStack extends cdk.Stack {
12
+ public readonly service: ecs.FargateService;
13
+ public readonly repoName: string;
14
+ public readonly dbUrl: string;
15
+ public readonly db: rds.DatabaseCluster;
16
+
17
+ constructor(scope: cdk.App, id: string, props: {{stack_prefix}}FargateStackProps) {
18
+ super(scope, id);
19
+
20
+ // import resources
21
+ const cluster = props.cluster;
22
+ {{#db_cluster}}
23
+ const vpc = props.vpc;
24
+
25
+ // Create secret from SecretsManager
26
+ const username = '{{username}}';
27
+ const secret = new secretsmanager.Secret(this, 'Secret', {
28
+ generateSecretString: {
29
+ excludePunctuation: true
30
+ }
31
+ });
32
+ const password = secret.secretValue;
33
+
34
+ {{#parameter_group}}
35
+ {{#cfn}}
36
+ // Create DB Cluster ParameterGroup
37
+ const clusterParameterGroup = new rds.ClusterParameterGroup(this, 'DBClusterPG', {
38
+ description: '{{description}}',
39
+ family: '{{family}}',
40
+ parameters: {
41
+ {{#parameters}}
42
+ {{{.}}}
43
+ {{/parameters}}
44
+ }
45
+ });
46
+ {{/cfn}}
47
+ {{#name}}
48
+ // Import DB cluster ParameterGroup
49
+ const clusterParameterGroup = rds.ClusterParameterGroup.fromParameterGroupName(
50
+ this, 'DBClusterPG', '{{.}}');
51
+ {{/name}}
52
+ {{/parameter_group}}
53
+ // Create DB Cluster
54
+ const db = new rds.DatabaseCluster(this, 'DBCluster', {
55
+ engine: rds.DatabaseClusterEngine.{{engine}},
56
+ {{#engine_version}}
57
+ engineVersion: '{{.}}',
58
+ {{/engine_version}}
59
+ masterUser: {
60
+ username: username,
61
+ password: password
62
+ },
63
+ instanceProps: {
64
+ instanceType: new ec2.InstanceType('{{instance_type}}'),
65
+ vpc: vpc,
66
+ vpcSubnets: {
67
+ subnetType: ec2.SubnetType.{{instance_subnet}}
68
+ }
69
+ },
70
+ {{#kms_key}}
71
+ kmsKey: kms.Key.fromKeyArn(this, 'DBKMSKey', '{{.}}'),
72
+ {{/kms_key}}
73
+ {{#backup}}
74
+ backup: {
75
+ {{#retention_days}}
76
+ retentionDays: {{.}},
77
+ {{/retention_days}}
78
+ {{#preferred_window}}
79
+ preferred_window: '{{.}}',
80
+ {{/preferred_window}}
81
+ },
82
+ {{/backup}}
83
+ defaultDatabaseName: '{{db_name}}',
84
+ {{#cluster_identifier}}
85
+ clusterIdentifier: '{{.}}',
86
+ {{/cluster_identifier}}
87
+ {{#removal_policy}}
88
+ removalPolicy: cdk.RemovalPolicy.{{.}},
89
+ {{/removal_policy}}
90
+ {{#instance_identifier}}
91
+ instanceIdentifierBase: '{{.}}',
92
+ {{/instance_identifier}}
93
+ instances: {{instances}},
94
+ parameterGroup: clusterParameterGroup
95
+ });
96
+ const dbUrl = {{#postgres}}"postgres://"{{/postgres}}{{^postgres}}"mysql2://"{{/postgres}} + username + ":" + password + "@" + db.clusterEndpoint.socketAddress;
97
+ this.dbUrl = dbUrl;
98
+ {{/db_cluster}}
99
+
100
+ const asset = new ecr_assets.DockerImageAsset(this, 'ImageAssetBuild', {
101
+ directory: '{{source_path}}'
102
+ });
103
+
104
+ // compute repo name from asset image
105
+ const parts = asset.imageUri.split("@")[0].split("/");
106
+ const repoName = parts.slice(1, parts.length).join("/").split(":")[0];
107
+ this.repoName = repoName;
108
+
109
+ const ecrRepo = ecr.Repository.fromRepositoryName(this, 'EcrRepo', repoName);
110
+ const image = ecs.ContainerImage.fromEcrRepository(ecrRepo);
111
+
112
+ {{#fargate}}
113
+ // Fargate service
114
+ const lbFargate = new ecs_patterns.LoadBalancedFargateService(this, 'LBFargate', {
115
+ {{#service_name}}
116
+ serviceName: '{{.}}',
117
+ {{/service_name}}
118
+ cluster: cluster,
119
+ image: image,
120
+ containerName: '{{container_name}}',
121
+ containerPort: {{container_port}},
122
+ {{#certificate}}
123
+ certificate: certificatemanager.Certificate.fromCertificateArn(this, 'Certificate', '{{.}}'),
124
+ {{/certificate}}
125
+ {{#memory}}memoryLimitMiB: {{.}},{{/memory}}
126
+ {{#cpu}}cpu: {{.}},{{/cpu}}
127
+ environment: {
128
+ {{#has_db}}
129
+ 'DATABASE_URL': dbUrl,
130
+ {{/has_db}}
131
+ {{#envs}}
132
+ {{{.}}}
133
+ {{/envs}}
134
+ },
135
+ enableLogging: true,
136
+ desiredCount: {{desired_count}},
137
+ {{#domain_name}}
138
+ domainName: '{{.}}',
139
+ {{/domain_name}}
140
+ {{#domain_zone}}
141
+ domainZone: '{{.}}',
142
+ {{/domain_zone}}
143
+ {{#public}}
144
+ publicLoadBalancer: true,
145
+ publicTasks: true
146
+ {{/public}}
147
+ });
148
+ {{#has_db}}
149
+ db.connections.allowDefaultPortFrom(lbFargate.service, 'From Fargate');
150
+ this.db = db;
151
+ {{/has_db}}
152
+ {{/fargate}}
153
+ {{#scaling}}
154
+
155
+ const scaling = lbFargate.service.autoScaleTaskCount({
156
+ maxCapacity: {{max_capacity}},
157
+ {{#min_capacity}}
158
+ minCapacity: {{.}}
159
+ {{/min_capacity}}
160
+ });
161
+ {{#on_cpu}}
162
+ scaling.scaleOnCpuUtilization('FargateScalingOnCpu', {
163
+ targetUtilizationPercent: {{target_util_percent}},
164
+ {{#disable_scale_in}}
165
+ disableScaleIn: true,
166
+ {{/disable_scale_in}}
167
+ {{#scale_in_cooldown}}
168
+ scaleInCooldownSec: {{.}},
169
+ {{/scale_in_cooldown}}
170
+ {{#scale_out_cooldown}}
171
+ scaleOutCooldownSec: {{.}},
172
+ {{/scale_out_cooldown}}
173
+ });
174
+ {{/on_cpu}}
175
+ {{#on_memory}}
176
+ scaling.scaleOnMemoryUtilization('FargateScalingOnMemory', {
177
+ targetUtilizationPercent: {{target_util_percent}},
178
+ {{#disable_scale_in}}
179
+ disableScaleIn: true,
180
+ {{/disable_scale_in}}
181
+ {{#scale_in_cooldown}}
182
+ scaleInCooldownSec: {{.}},
183
+ {{/scale_in_cooldown}}
184
+ {{#scale_out_cooldown}}
185
+ scaleOutCooldownSec: {{.}},
186
+ {{/scale_out_cooldown}}
187
+ });
188
+ {{/on_memory}}
189
+ {{#on_metric}}
190
+ {{#metric}}
191
+ const metric = new cloudwatch.Metric('Metric', {
192
+ metricName: {{name}},
193
+ metricNamespace: {{namespace}},
194
+ {{#color}}
195
+ color: '{{.}}',
196
+ {{/color}}
197
+ dimensions: {
198
+ {{#dimensions}}
199
+ {{{.}}}
200
+ {{/dimensions}}
201
+ }
202
+ {{#label}}
203
+ label: '{{.}}',
204
+ {{/label}}
205
+ {{#period_sec}}
206
+ periodSec: {{.}},
207
+ {{/period_sec}}
208
+ {{#statistic}}
209
+ statistic: {{.}},
210
+ {{/statistic}}
211
+ {{#unit}}
212
+ unit: cloudwatch.Unit.{{.}},
213
+ {{/unit}}
214
+ });
215
+ {{/metric}}
216
+ scaling.scaleOnMetric('FargateScalingOnMetric', {
217
+ metric: metric,
218
+ {{#scaling_steps?}}
219
+ scalingSteps: [
220
+ {{#scaling_steps}}
221
+ {
222
+ {{#change}}change: {{.}},{{/change}}
223
+ {{#lower}}lower: {{.}},{{/lower}}
224
+ {{#upper}}upper: {{.}}{{/upper}}
225
+ },
226
+ {{/scaling_steps}}
227
+ ],
228
+ {{/scaling_steps?}}
229
+ {{#adjustment_type}}
230
+ adjustmentType: applicationautoscaling.{{.}},
231
+ {{/adjustment_type}}
232
+ {{#cooldown_sec}}
233
+ cooldownSec: {{.}},
234
+ {{/cooldown_sec}}
235
+ {{#min_adjustment_magnitude}}
236
+ minAdjustmentMagnitude: {{.}},
237
+ {{/min_adjustment_magnitude}}
238
+ });
239
+ {{/on_metric}}
240
+ {{#on_request}}
241
+ scaling.scaleOnRequestCount('FargateScalingOnRequest', {
242
+ requestsPerTarget: {{requests_per_target}},
243
+ targetGroup: target,
244
+ {{#disable_scale_in}}
245
+ disableScaleIn: true,
246
+ {{/disable_scale_in}}
247
+ {{#scale_in_cooldown}}
248
+ scaleInCooldownSec: {{.}},
249
+ {{/scale_in_cooldown}}
250
+ {{#scale_out_cooldown}}
251
+ scaleOutCooldownSec: {{.}},
252
+ {{/scale_out_cooldown}}
253
+ });
254
+ {{/on_request}}
255
+ {{#on_schedule}}
256
+ scaling.scaleOnSchedule('FargateScalingOnSchedule', {
257
+ schedule: {{{schedule}}},
258
+ {{#max_capacity}}
259
+ maxCapacity: {{.}},
260
+ {{/max_capacity}}
261
+ {{#min_capacity}}
262
+ minCapacity: {{.}},
263
+ {{/min_capacity}}
264
+ {{#start_time}}
265
+ startTime: new Date({{.}}),
266
+ {{/start_time}}
267
+ {{#end_time}}
268
+ endTime: new Date({{.}}),
269
+ {{/end_time}}
270
+ });
271
+ {{/on_schedule}}
272
+ {{#to_track_custom_metric}}
273
+ {{#metric}}
274
+ const custom_metric = new cloudwatch.Metric('CustomMetric', {
275
+ metricName: {{name}},
276
+ metricNamespace: {{namespace}},
277
+ {{#color}}
278
+ color: '{{.}}',
279
+ {{/color}}
280
+ dimensions: {
281
+ {{#dimensions}}
282
+ {{{.}}}
283
+ {{/dimensions}}
284
+ },
285
+ {{#label}}
286
+ label: '{{.}}',
287
+ {{/label}}
288
+ {{#period_sec}}
289
+ periodSec: {{.}},
290
+ {{/period_sec}}
291
+ {{#statistic}}
292
+ statistic: '{{.}}',
293
+ {{/statistic}}
294
+ {{#unit}}
295
+ unit: cloudwatch.Unit.{{.}},
296
+ {{/unit}}
297
+ });
298
+ {{/metric}}
299
+ scaling.scaleToTrackCustomMetric('FargateScalingOnCustomMetric', {
300
+ metric: custom_metric,
301
+ {{#disable_scale_in}}
302
+ disableScaleIn: true,
303
+ {{/disable_scale_in}}
304
+ {{#scale_in_cooldown}}
305
+ scaleInCooldownSec: {{.}},
306
+ {{/scale_in_cooldown}}
307
+ {{#scale_out_cooldown}}
308
+ scaleOutCooldownSec: {{.}},
309
+ {{/scale_out_cooldown}}
310
+ });
311
+ {{/to_track_custom_metric}}
312
+
313
+ {{/scaling}}
314
+ this.service = lbFargate.service;
315
+ }
316
+ }