aws-rails-provisioner 0.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }