@studion/infra-code-blocks 0.1.9 → 0.2.1
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.
- package/README.md +272 -28
- package/dist/components/database.d.ts +12 -8
- package/dist/components/database.js +8 -8
- package/dist/components/ec2-ssm-connect.d.ts +6 -2
- package/dist/components/ec2-ssm-connect.js +7 -7
- package/dist/components/ecs-service.d.ts +125 -0
- package/dist/components/ecs-service.js +323 -0
- package/dist/components/mongo.d.ts +27 -0
- package/dist/components/mongo.js +63 -0
- package/dist/components/nuxt-ssr.d.ts +43 -0
- package/dist/components/nuxt-ssr.js +277 -0
- package/dist/components/project.d.ts +32 -15
- package/dist/components/project.js +62 -20
- package/dist/components/web-server.d.ts +12 -81
- package/dist/components/web-server.js +60 -254
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/package.json +1 -1
|
@@ -5,49 +5,33 @@ const pulumi = require("@pulumi/pulumi");
|
|
|
5
5
|
const aws = require("@pulumi/aws");
|
|
6
6
|
const constants_1 = require("../constants");
|
|
7
7
|
const acm_certificate_1 = require("./acm-certificate");
|
|
8
|
-
const
|
|
9
|
-
const awsRegion = config.require('region');
|
|
10
|
-
const assumeRolePolicy = {
|
|
11
|
-
Version: '2012-10-17',
|
|
12
|
-
Statement: [
|
|
13
|
-
{
|
|
14
|
-
Action: 'sts:AssumeRole',
|
|
15
|
-
Principal: {
|
|
16
|
-
Service: 'ecs-tasks.amazonaws.com',
|
|
17
|
-
},
|
|
18
|
-
Effect: 'Allow',
|
|
19
|
-
Sid: '',
|
|
20
|
-
},
|
|
21
|
-
],
|
|
22
|
-
};
|
|
8
|
+
const ecs_service_1 = require("./ecs-service");
|
|
23
9
|
const defaults = {
|
|
24
|
-
|
|
25
|
-
minCount: 1,
|
|
26
|
-
maxCount: 10,
|
|
27
|
-
size: 'small',
|
|
28
|
-
environment: [],
|
|
29
|
-
secrets: [],
|
|
30
|
-
healtCheckPath: '/healtcheck',
|
|
31
|
-
taskExecutionRoleInlinePolicies: [],
|
|
32
|
-
taskRoleInlinePolicies: [],
|
|
10
|
+
healthCheckPath: '/healthcheck',
|
|
33
11
|
};
|
|
34
12
|
class WebServer extends pulumi.ComponentResource {
|
|
35
13
|
constructor(name, args, opts = {}) {
|
|
36
|
-
super('studion:WebServer', name,
|
|
14
|
+
super('studion:WebServer', name, args, opts);
|
|
15
|
+
const { vpcId, domain, hostedZoneId } = args;
|
|
16
|
+
const hasCustomDomain = !!domain && !!hostedZoneId;
|
|
17
|
+
if (domain && !hostedZoneId) {
|
|
18
|
+
throw new Error('WebServer:hostedZoneId must be provided when the domain is specified');
|
|
19
|
+
}
|
|
37
20
|
this.name = name;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const { lb, lbTargetGroup, lbHttpListener, lbTlsListener, lbSecurityGroup, } = this.createLoadBalancer(
|
|
21
|
+
if (hasCustomDomain) {
|
|
22
|
+
this.certificate = this.createTlsCertificate({ domain, hostedZoneId });
|
|
23
|
+
}
|
|
24
|
+
const { lb, lbTargetGroup, lbHttpListener, lbTlsListener, lbSecurityGroup, } = this.createLoadBalancer(args);
|
|
42
25
|
this.lb = lb;
|
|
43
26
|
this.lbTargetGroup = lbTargetGroup;
|
|
44
27
|
this.lbHttpListener = lbHttpListener;
|
|
45
28
|
this.lbTlsListener = lbTlsListener;
|
|
46
29
|
this.lbSecurityGroup = lbSecurityGroup;
|
|
47
|
-
this.
|
|
30
|
+
this.serviceSecurityGroup = this.createSecurityGroup(vpcId);
|
|
48
31
|
this.service = this.createEcsService(args);
|
|
49
|
-
|
|
50
|
-
|
|
32
|
+
if (hasCustomDomain) {
|
|
33
|
+
this.createDnsRecord({ domain, hostedZoneId });
|
|
34
|
+
}
|
|
51
35
|
this.registerOutputs();
|
|
52
36
|
}
|
|
53
37
|
createTlsCertificate({ domain, hostedZoneId, }) {
|
|
@@ -57,17 +41,9 @@ class WebServer extends pulumi.ComponentResource {
|
|
|
57
41
|
}, { parent: this });
|
|
58
42
|
return certificate;
|
|
59
43
|
}
|
|
60
|
-
|
|
61
|
-
const logGroup = new aws.cloudwatch.LogGroup(`${this.name}-log-group`, {
|
|
62
|
-
retentionInDays: 14,
|
|
63
|
-
namePrefix: `/ecs/${this.name}-`,
|
|
64
|
-
tags: constants_1.commonTags,
|
|
65
|
-
}, { parent: this });
|
|
66
|
-
return logGroup;
|
|
67
|
-
}
|
|
68
|
-
createLoadBalancer({ vpc, port, healtCheckPath, }) {
|
|
44
|
+
createLoadBalancer({ vpcId, publicSubnetIds, port, healthCheckPath, }) {
|
|
69
45
|
const lbSecurityGroup = new aws.ec2.SecurityGroup(`${this.name}-lb-security-group`, {
|
|
70
|
-
vpcId
|
|
46
|
+
vpcId,
|
|
71
47
|
ingress: [
|
|
72
48
|
{
|
|
73
49
|
protocol: 'tcp',
|
|
@@ -95,7 +71,7 @@ class WebServer extends pulumi.ComponentResource {
|
|
|
95
71
|
const lb = new aws.lb.LoadBalancer(`${this.name}-lb`, {
|
|
96
72
|
namePrefix: 'lb-',
|
|
97
73
|
loadBalancerType: 'application',
|
|
98
|
-
subnets:
|
|
74
|
+
subnets: publicSubnetIds,
|
|
99
75
|
securityGroups: [lbSecurityGroup.id],
|
|
100
76
|
internal: false,
|
|
101
77
|
ipAddressType: 'ipv4',
|
|
@@ -106,45 +82,52 @@ class WebServer extends pulumi.ComponentResource {
|
|
|
106
82
|
port,
|
|
107
83
|
protocol: 'HTTP',
|
|
108
84
|
targetType: 'ip',
|
|
109
|
-
vpcId
|
|
85
|
+
vpcId,
|
|
110
86
|
healthCheck: {
|
|
111
87
|
healthyThreshold: 3,
|
|
112
88
|
unhealthyThreshold: 2,
|
|
113
89
|
interval: 60,
|
|
114
90
|
timeout: 5,
|
|
115
|
-
path:
|
|
91
|
+
path: healthCheckPath || defaults.healthCheckPath,
|
|
116
92
|
},
|
|
117
93
|
tags: Object.assign(Object.assign({}, constants_1.commonTags), { Name: `${this.name}-lb-target-group` }),
|
|
118
94
|
}, { parent: this, dependsOn: [this.lb] });
|
|
95
|
+
const defaultAction = this.certificate
|
|
96
|
+
? {
|
|
97
|
+
type: 'redirect',
|
|
98
|
+
redirect: {
|
|
99
|
+
port: '443',
|
|
100
|
+
protocol: 'HTTPS',
|
|
101
|
+
statusCode: 'HTTP_301',
|
|
102
|
+
},
|
|
103
|
+
}
|
|
104
|
+
: {
|
|
105
|
+
type: 'forward',
|
|
106
|
+
targetGroupArn: lbTargetGroup.arn,
|
|
107
|
+
};
|
|
119
108
|
const lbHttpListener = new aws.lb.Listener(`${this.name}-lb-listener-80`, {
|
|
120
109
|
loadBalancerArn: lb.arn,
|
|
121
110
|
port: 80,
|
|
122
|
-
defaultActions: [
|
|
123
|
-
{
|
|
124
|
-
type: 'redirect',
|
|
125
|
-
redirect: {
|
|
126
|
-
port: '443',
|
|
127
|
-
protocol: 'HTTPS',
|
|
128
|
-
statusCode: 'HTTP_301',
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
],
|
|
132
|
-
tags: constants_1.commonTags,
|
|
133
|
-
}, { parent: this });
|
|
134
|
-
const lbTlsListener = new aws.lb.Listener(`${this.name}-lb-listener-443`, {
|
|
135
|
-
loadBalancerArn: lb.arn,
|
|
136
|
-
port: 443,
|
|
137
|
-
protocol: 'HTTPS',
|
|
138
|
-
sslPolicy: 'ELBSecurityPolicy-2016-08',
|
|
139
|
-
certificateArn: this.certificate.certificate.arn,
|
|
140
|
-
defaultActions: [
|
|
141
|
-
{
|
|
142
|
-
type: 'forward',
|
|
143
|
-
targetGroupArn: lbTargetGroup.arn,
|
|
144
|
-
},
|
|
145
|
-
],
|
|
111
|
+
defaultActions: [defaultAction],
|
|
146
112
|
tags: constants_1.commonTags,
|
|
147
113
|
}, { parent: this });
|
|
114
|
+
let lbTlsListener = undefined;
|
|
115
|
+
if (this.certificate) {
|
|
116
|
+
lbTlsListener = new aws.lb.Listener(`${this.name}-lb-listener-443`, {
|
|
117
|
+
loadBalancerArn: lb.arn,
|
|
118
|
+
port: 443,
|
|
119
|
+
protocol: 'HTTPS',
|
|
120
|
+
sslPolicy: 'ELBSecurityPolicy-2016-08',
|
|
121
|
+
certificateArn: this.certificate.certificate.arn,
|
|
122
|
+
defaultActions: [
|
|
123
|
+
{
|
|
124
|
+
type: 'forward',
|
|
125
|
+
targetGroupArn: lbTargetGroup.arn,
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
tags: constants_1.commonTags,
|
|
129
|
+
}, { parent: this });
|
|
130
|
+
}
|
|
148
131
|
return {
|
|
149
132
|
lb,
|
|
150
133
|
lbTargetGroup,
|
|
@@ -153,129 +136,9 @@ class WebServer extends pulumi.ComponentResource {
|
|
|
153
136
|
lbSecurityGroup,
|
|
154
137
|
};
|
|
155
138
|
}
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
const secretManagerSecretsInlinePolicy = {
|
|
160
|
-
name: `${this.name}-secret-manager-access`,
|
|
161
|
-
policy: JSON.stringify({
|
|
162
|
-
Version: '2012-10-17',
|
|
163
|
-
Statement: [
|
|
164
|
-
{
|
|
165
|
-
Sid: 'AllowContainerToGetSecretManagerSecrets',
|
|
166
|
-
Effect: 'Allow',
|
|
167
|
-
Action: ['secretsmanager:GetSecretValue'],
|
|
168
|
-
Resource: '*',
|
|
169
|
-
},
|
|
170
|
-
],
|
|
171
|
-
}),
|
|
172
|
-
};
|
|
173
|
-
const taskExecutionRole = new aws.iam.Role(`${this.name}-ecs-task-exec-role`, {
|
|
174
|
-
namePrefix: `${this.name}-ecs-task-exec-role-`,
|
|
175
|
-
assumeRolePolicy,
|
|
176
|
-
managedPolicyArns: [
|
|
177
|
-
'arn:aws:iam::aws:policy/CloudWatchFullAccess',
|
|
178
|
-
'arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess',
|
|
179
|
-
],
|
|
180
|
-
inlinePolicies: [
|
|
181
|
-
secretManagerSecretsInlinePolicy,
|
|
182
|
-
...argsWithDefaults.taskExecutionRoleInlinePolicies,
|
|
183
|
-
],
|
|
184
|
-
tags: constants_1.commonTags,
|
|
185
|
-
}, { parent: this });
|
|
186
|
-
const execCmdInlinePolicy = {
|
|
187
|
-
name: `${this.name}-ecs-exec`,
|
|
188
|
-
policy: JSON.stringify({
|
|
189
|
-
Version: '2012-10-17',
|
|
190
|
-
Statement: [
|
|
191
|
-
{
|
|
192
|
-
Sid: 'AllowContainerToCreateECSExecSSMChannel',
|
|
193
|
-
Effect: 'Allow',
|
|
194
|
-
Action: [
|
|
195
|
-
'ssmmessages:CreateControlChannel',
|
|
196
|
-
'ssmmessages:CreateDataChannel',
|
|
197
|
-
'ssmmessages:OpenControlChannel',
|
|
198
|
-
'ssmmessages:OpenDataChannel',
|
|
199
|
-
],
|
|
200
|
-
Resource: '*',
|
|
201
|
-
},
|
|
202
|
-
],
|
|
203
|
-
}),
|
|
204
|
-
};
|
|
205
|
-
const taskRole = new aws.iam.Role(`${this.name}-ecs-task-role`, {
|
|
206
|
-
namePrefix: `${this.name}-ecs-task-role-`,
|
|
207
|
-
assumeRolePolicy,
|
|
208
|
-
inlinePolicies: [
|
|
209
|
-
execCmdInlinePolicy,
|
|
210
|
-
...argsWithDefaults.taskRoleInlinePolicies,
|
|
211
|
-
],
|
|
212
|
-
tags: constants_1.commonTags,
|
|
213
|
-
}, { parent: this });
|
|
214
|
-
const parsedSize = pulumi.all([argsWithDefaults.size]).apply(([size]) => {
|
|
215
|
-
const mapCapabilities = ({ cpu, memory }) => ({
|
|
216
|
-
cpu: String(cpu),
|
|
217
|
-
memory: String(memory),
|
|
218
|
-
});
|
|
219
|
-
if (typeof size === 'string') {
|
|
220
|
-
return mapCapabilities(constants_1.PredefinedSize[size]);
|
|
221
|
-
}
|
|
222
|
-
if (typeof size === 'object') {
|
|
223
|
-
return mapCapabilities(size);
|
|
224
|
-
}
|
|
225
|
-
throw Error('Incorrect EcsService size argument');
|
|
226
|
-
});
|
|
227
|
-
const taskDefinition = new aws.ecs.TaskDefinition(`${this.name}-task-definition`, {
|
|
228
|
-
family: `${this.name}-task-definition-${stack}`,
|
|
229
|
-
networkMode: 'awsvpc',
|
|
230
|
-
executionRoleArn: taskExecutionRole.arn,
|
|
231
|
-
taskRoleArn: taskRole.arn,
|
|
232
|
-
cpu: parsedSize.cpu,
|
|
233
|
-
memory: parsedSize.memory,
|
|
234
|
-
requiresCompatibilities: ['FARGATE'],
|
|
235
|
-
containerDefinitions: pulumi
|
|
236
|
-
.all([
|
|
237
|
-
this.name,
|
|
238
|
-
argsWithDefaults.image,
|
|
239
|
-
argsWithDefaults.port,
|
|
240
|
-
argsWithDefaults.environment,
|
|
241
|
-
argsWithDefaults.secrets,
|
|
242
|
-
this.logGroup.name,
|
|
243
|
-
awsRegion,
|
|
244
|
-
])
|
|
245
|
-
.apply(([containerName, image, port, environment, secrets, logGroup, region,]) => {
|
|
246
|
-
return JSON.stringify([
|
|
247
|
-
{
|
|
248
|
-
readonlyRootFilesystem: false,
|
|
249
|
-
name: containerName,
|
|
250
|
-
image,
|
|
251
|
-
essential: true,
|
|
252
|
-
portMappings: [
|
|
253
|
-
{
|
|
254
|
-
containerPort: port,
|
|
255
|
-
protocol: 'tcp',
|
|
256
|
-
},
|
|
257
|
-
],
|
|
258
|
-
logConfiguration: {
|
|
259
|
-
logDriver: 'awslogs',
|
|
260
|
-
options: {
|
|
261
|
-
'awslogs-group': logGroup,
|
|
262
|
-
'awslogs-region': region,
|
|
263
|
-
'awslogs-stream-prefix': 'ecs',
|
|
264
|
-
},
|
|
265
|
-
},
|
|
266
|
-
environment,
|
|
267
|
-
secrets,
|
|
268
|
-
},
|
|
269
|
-
]);
|
|
270
|
-
}),
|
|
271
|
-
tags: Object.assign(Object.assign({}, constants_1.commonTags), argsWithDefaults.tags),
|
|
272
|
-
}, { parent: this });
|
|
273
|
-
return taskDefinition;
|
|
274
|
-
}
|
|
275
|
-
createEcsService(args) {
|
|
276
|
-
const argsWithDefaults = Object.assign({}, defaults, args);
|
|
277
|
-
const serviceSecurityGroup = new aws.ec2.SecurityGroup(`${this.name}-security-group`, {
|
|
278
|
-
vpcId: argsWithDefaults.vpc.vpcId,
|
|
139
|
+
createSecurityGroup(vpcId) {
|
|
140
|
+
const securityGroup = new aws.ec2.SecurityGroup(`${this.name}-security-group`, {
|
|
141
|
+
vpcId,
|
|
279
142
|
ingress: [
|
|
280
143
|
{
|
|
281
144
|
fromPort: 0,
|
|
@@ -294,34 +157,12 @@ class WebServer extends pulumi.ComponentResource {
|
|
|
294
157
|
],
|
|
295
158
|
tags: constants_1.commonTags,
|
|
296
159
|
}, { parent: this });
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
desiredCount: argsWithDefaults.desiredCount,
|
|
302
|
-
taskDefinition: this.taskDefinition.arn,
|
|
303
|
-
enableExecuteCommand: true,
|
|
304
|
-
loadBalancers: [
|
|
305
|
-
{
|
|
306
|
-
containerName: this.name,
|
|
307
|
-
containerPort: argsWithDefaults.port,
|
|
308
|
-
targetGroupArn: this.lbTargetGroup.arn,
|
|
309
|
-
},
|
|
310
|
-
],
|
|
311
|
-
networkConfiguration: {
|
|
312
|
-
assignPublicIp: true,
|
|
313
|
-
subnets: argsWithDefaults.vpc.publicSubnetIds,
|
|
314
|
-
securityGroups: [serviceSecurityGroup.id],
|
|
315
|
-
},
|
|
316
|
-
tags: Object.assign(Object.assign({}, constants_1.commonTags), argsWithDefaults.tags),
|
|
317
|
-
}, {
|
|
160
|
+
return securityGroup;
|
|
161
|
+
}
|
|
162
|
+
createEcsService(args) {
|
|
163
|
+
const service = new ecs_service_1.EcsService(this.name, Object.assign(Object.assign({}, args), { enableServiceAutoDiscovery: false, lbTargetGroupArn: this.lbTargetGroup.arn, assignPublicIp: true, subnetIds: args.publicSubnetIds, securityGroup: this.serviceSecurityGroup }), {
|
|
318
164
|
parent: this,
|
|
319
|
-
dependsOn: [
|
|
320
|
-
this.lb,
|
|
321
|
-
this.lbTargetGroup,
|
|
322
|
-
this.lbHttpListener,
|
|
323
|
-
this.lbTlsListener,
|
|
324
|
-
],
|
|
165
|
+
dependsOn: [this.lb, this.lbTargetGroup],
|
|
325
166
|
});
|
|
326
167
|
return service;
|
|
327
168
|
}
|
|
@@ -339,40 +180,5 @@ class WebServer extends pulumi.ComponentResource {
|
|
|
339
180
|
],
|
|
340
181
|
}, { parent: this });
|
|
341
182
|
}
|
|
342
|
-
enableAutoscaling(args) {
|
|
343
|
-
const argsWithDefaults = Object.assign({}, defaults, args);
|
|
344
|
-
const autoscalingTarget = new aws.appautoscaling.Target(`${this.name}-autoscale-target`, {
|
|
345
|
-
minCapacity: argsWithDefaults.minCount,
|
|
346
|
-
maxCapacity: argsWithDefaults.maxCount,
|
|
347
|
-
resourceId: pulumi.interpolate `service/${argsWithDefaults.cluster.name}/${this.service.name}`,
|
|
348
|
-
serviceNamespace: 'ecs',
|
|
349
|
-
scalableDimension: 'ecs:service:DesiredCount',
|
|
350
|
-
tags: constants_1.commonTags,
|
|
351
|
-
}, { parent: this });
|
|
352
|
-
const memoryAutoscalingPolicy = new aws.appautoscaling.Policy(`${this.name}-memory-autoscale-policy`, {
|
|
353
|
-
policyType: 'TargetTrackingScaling',
|
|
354
|
-
resourceId: autoscalingTarget.resourceId,
|
|
355
|
-
scalableDimension: autoscalingTarget.scalableDimension,
|
|
356
|
-
serviceNamespace: autoscalingTarget.serviceNamespace,
|
|
357
|
-
targetTrackingScalingPolicyConfiguration: {
|
|
358
|
-
predefinedMetricSpecification: {
|
|
359
|
-
predefinedMetricType: 'ECSServiceAverageMemoryUtilization',
|
|
360
|
-
},
|
|
361
|
-
targetValue: 80,
|
|
362
|
-
},
|
|
363
|
-
}, { parent: this });
|
|
364
|
-
const cpuAutoscalingPolicy = new aws.appautoscaling.Policy(`${this.name}-cpu-autoscale-policy`, {
|
|
365
|
-
policyType: 'TargetTrackingScaling',
|
|
366
|
-
resourceId: autoscalingTarget.resourceId,
|
|
367
|
-
scalableDimension: autoscalingTarget.scalableDimension,
|
|
368
|
-
serviceNamespace: autoscalingTarget.serviceNamespace,
|
|
369
|
-
targetTrackingScalingPolicyConfiguration: {
|
|
370
|
-
predefinedMetricSpecification: {
|
|
371
|
-
predefinedMetricType: 'ECSServiceAverageCPUUtilization',
|
|
372
|
-
},
|
|
373
|
-
targetValue: 60,
|
|
374
|
-
},
|
|
375
|
-
}, { parent: this });
|
|
376
|
-
}
|
|
377
183
|
}
|
|
378
184
|
exports.WebServer = WebServer;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export * from './components/web-server';
|
|
2
|
+
export * from './components/mongo';
|
|
2
3
|
export * from './components/static-site';
|
|
3
4
|
export * from './components/database';
|
|
4
5
|
export * from './components/redis';
|
|
5
6
|
export * from './components/project';
|
|
6
7
|
export * from './components/ec2-ssm-connect';
|
|
8
|
+
export * from './components/ecs-service';
|
|
9
|
+
export * from './components/nuxt-ssr';
|
package/dist/index.js
CHANGED
|
@@ -15,8 +15,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./components/web-server"), exports);
|
|
18
|
+
__exportStar(require("./components/mongo"), exports);
|
|
18
19
|
__exportStar(require("./components/static-site"), exports);
|
|
19
20
|
__exportStar(require("./components/database"), exports);
|
|
20
21
|
__exportStar(require("./components/redis"), exports);
|
|
21
22
|
__exportStar(require("./components/project"), exports);
|
|
22
23
|
__exportStar(require("./components/ec2-ssm-connect"), exports);
|
|
24
|
+
__exportStar(require("./components/ecs-service"), exports);
|
|
25
|
+
__exportStar(require("./components/nuxt-ssr"), exports);
|