@studion/infra-code-blocks 0.1.9 → 0.2.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.
- 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 +46 -244
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import * as pulumi from '@pulumi/pulumi';
|
|
2
|
+
import * as aws from '@pulumi/aws';
|
|
3
|
+
import { Size } from '../types/size';
|
|
4
|
+
export declare const awsRegion: string;
|
|
5
|
+
export declare const assumeRolePolicy: aws.iam.PolicyDocument;
|
|
6
|
+
export type RoleInlinePolicy = {
|
|
7
|
+
/**
|
|
8
|
+
* Name of the role policy.
|
|
9
|
+
*/
|
|
10
|
+
name?: pulumi.Input<string>;
|
|
11
|
+
/**
|
|
12
|
+
* Policy document as a JSON formatted string.
|
|
13
|
+
*/
|
|
14
|
+
policy?: pulumi.Input<string>;
|
|
15
|
+
};
|
|
16
|
+
export type EcsServiceArgs = {
|
|
17
|
+
/**
|
|
18
|
+
* The ECR image used to start a container.
|
|
19
|
+
*/
|
|
20
|
+
image: pulumi.Input<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Exposed service port.
|
|
23
|
+
*/
|
|
24
|
+
port: pulumi.Input<number>;
|
|
25
|
+
/**
|
|
26
|
+
* The aws.ecs.Cluster resource.
|
|
27
|
+
*/
|
|
28
|
+
cluster: aws.ecs.Cluster;
|
|
29
|
+
vpcId: pulumi.Input<string>;
|
|
30
|
+
/**
|
|
31
|
+
* The IPv4 CIDR block for the VPC.
|
|
32
|
+
*/
|
|
33
|
+
vpcCidrBlock: pulumi.Input<string>;
|
|
34
|
+
/**
|
|
35
|
+
* If the `assignPublicIp` parameter is set to `true`, the publicSubnetIds
|
|
36
|
+
* must be provided; otherwise, provide the privateSubnetIds.
|
|
37
|
+
*/
|
|
38
|
+
subnetIds: pulumi.Input<pulumi.Input<string>[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Number of instances of the task definition to place and keep running. Defaults to 1.
|
|
41
|
+
*/
|
|
42
|
+
desiredCount?: pulumi.Input<number>;
|
|
43
|
+
/**
|
|
44
|
+
* CPU and memory size used for running the container. Defaults to "small".
|
|
45
|
+
* Available predefined options are:
|
|
46
|
+
* - small (0.25 vCPU, 0.5 GB memory)
|
|
47
|
+
* - medium (0.5 vCPU, 1 GB memory)
|
|
48
|
+
* - large (1 vCPU memory, 2 GB memory)
|
|
49
|
+
* - xlarge (2 vCPU, 4 GB memory)
|
|
50
|
+
*/
|
|
51
|
+
size?: pulumi.Input<Size>;
|
|
52
|
+
/**
|
|
53
|
+
* The environment variables to pass to a container. Don't use this field for
|
|
54
|
+
* sensitive information such as passwords, API keys, etc. For that purpose,
|
|
55
|
+
* please use the `secrets` property.
|
|
56
|
+
* Defaults to [].
|
|
57
|
+
*/
|
|
58
|
+
environment?: aws.ecs.KeyValuePair[];
|
|
59
|
+
/**
|
|
60
|
+
* The secrets to pass to the container. Defaults to [].
|
|
61
|
+
*/
|
|
62
|
+
secrets?: aws.ecs.Secret[];
|
|
63
|
+
/**
|
|
64
|
+
* Enable service auto discovery and assign DNS record to service.
|
|
65
|
+
* Defaults to false.
|
|
66
|
+
*/
|
|
67
|
+
enableServiceAutoDiscovery: pulumi.Input<boolean>;
|
|
68
|
+
/**
|
|
69
|
+
* Location of persistent storage volume.
|
|
70
|
+
*/
|
|
71
|
+
persistentStorageVolumePath?: pulumi.Input<string>;
|
|
72
|
+
/**
|
|
73
|
+
* Alternate docker CMD instruction.
|
|
74
|
+
*/
|
|
75
|
+
dockerCommand?: pulumi.Input<string[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Autoscaling options for ecs service.
|
|
78
|
+
*/
|
|
79
|
+
autoscaling?: pulumi.Input<{
|
|
80
|
+
/**
|
|
81
|
+
* Is autoscaling enabled or disabled. Defaults to false.
|
|
82
|
+
*/
|
|
83
|
+
enabled: pulumi.Input<boolean>;
|
|
84
|
+
/**
|
|
85
|
+
* Min capacity of the scalable target. Defaults to 1.
|
|
86
|
+
*/
|
|
87
|
+
minCount?: pulumi.Input<number>;
|
|
88
|
+
/**
|
|
89
|
+
* Max capacity of the scalable target. Defaults to 1.
|
|
90
|
+
*/
|
|
91
|
+
maxCount?: pulumi.Input<number>;
|
|
92
|
+
}>;
|
|
93
|
+
lbTargetGroupArn?: aws.lb.TargetGroup['arn'];
|
|
94
|
+
/**
|
|
95
|
+
* Custom service security group
|
|
96
|
+
* In case no security group is provided, default security group will be used.
|
|
97
|
+
*/
|
|
98
|
+
securityGroup?: aws.ec2.SecurityGroup;
|
|
99
|
+
/**
|
|
100
|
+
* Assign public IP address to service.
|
|
101
|
+
*/
|
|
102
|
+
assignPublicIp?: pulumi.Input<boolean>;
|
|
103
|
+
taskExecutionRoleInlinePolicies?: pulumi.Input<pulumi.Input<RoleInlinePolicy>[]>;
|
|
104
|
+
taskRoleInlinePolicies?: pulumi.Input<pulumi.Input<RoleInlinePolicy>[]>;
|
|
105
|
+
/**
|
|
106
|
+
* A map of tags to assign to the resource.
|
|
107
|
+
*/
|
|
108
|
+
tags?: pulumi.Input<{
|
|
109
|
+
[key: string]: pulumi.Input<string>;
|
|
110
|
+
}>;
|
|
111
|
+
};
|
|
112
|
+
export declare class EcsService extends pulumi.ComponentResource {
|
|
113
|
+
name: string;
|
|
114
|
+
logGroup: aws.cloudwatch.LogGroup;
|
|
115
|
+
taskDefinition: aws.ecs.TaskDefinition;
|
|
116
|
+
serviceDiscoveryService?: aws.servicediscovery.Service;
|
|
117
|
+
service: aws.ecs.Service;
|
|
118
|
+
constructor(name: string, args: EcsServiceArgs, opts?: pulumi.ComponentResourceOptions);
|
|
119
|
+
private createLogGroup;
|
|
120
|
+
private createPersistentStorage;
|
|
121
|
+
private createTaskDefinition;
|
|
122
|
+
private createServiceDiscovery;
|
|
123
|
+
private createEcsService;
|
|
124
|
+
private enableAutoscaling;
|
|
125
|
+
}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EcsService = exports.assumeRolePolicy = exports.awsRegion = void 0;
|
|
4
|
+
const pulumi = require("@pulumi/pulumi");
|
|
5
|
+
const aws = require("@pulumi/aws");
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
|
+
const config = new pulumi.Config('aws');
|
|
8
|
+
exports.awsRegion = config.require('region');
|
|
9
|
+
exports.assumeRolePolicy = {
|
|
10
|
+
Version: '2012-10-17',
|
|
11
|
+
Statement: [
|
|
12
|
+
{
|
|
13
|
+
Action: 'sts:AssumeRole',
|
|
14
|
+
Principal: {
|
|
15
|
+
Service: 'ecs-tasks.amazonaws.com',
|
|
16
|
+
},
|
|
17
|
+
Effect: 'Allow',
|
|
18
|
+
Sid: '',
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
};
|
|
22
|
+
const defaults = {
|
|
23
|
+
desiredCount: 1,
|
|
24
|
+
size: 'small',
|
|
25
|
+
environment: [],
|
|
26
|
+
secrets: [],
|
|
27
|
+
enableServiceAutoDiscovery: false,
|
|
28
|
+
assignPublicIp: false,
|
|
29
|
+
taskExecutionRoleInlinePolicies: [],
|
|
30
|
+
taskRoleInlinePolicies: [],
|
|
31
|
+
autoscaling: {
|
|
32
|
+
enabled: false,
|
|
33
|
+
minCount: 1,
|
|
34
|
+
maxCount: 1,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
class EcsService extends pulumi.ComponentResource {
|
|
38
|
+
constructor(name, args, opts = {}) {
|
|
39
|
+
super('studion:ecs:Service', name, {}, opts);
|
|
40
|
+
const argsWithDefaults = Object.assign({}, defaults, args);
|
|
41
|
+
this.name = name;
|
|
42
|
+
this.logGroup = this.createLogGroup();
|
|
43
|
+
this.taskDefinition = this.createTaskDefinition(args);
|
|
44
|
+
if (argsWithDefaults.enableServiceAutoDiscovery) {
|
|
45
|
+
this.serviceDiscoveryService = this.createServiceDiscovery(argsWithDefaults.vpcId);
|
|
46
|
+
}
|
|
47
|
+
this.service = this.createEcsService(args, opts);
|
|
48
|
+
if (argsWithDefaults.autoscaling.enabled) {
|
|
49
|
+
this.enableAutoscaling(args);
|
|
50
|
+
}
|
|
51
|
+
this.registerOutputs();
|
|
52
|
+
}
|
|
53
|
+
createLogGroup() {
|
|
54
|
+
const logGroup = new aws.cloudwatch.LogGroup(`${this.name}-log-group`, {
|
|
55
|
+
retentionInDays: 14,
|
|
56
|
+
namePrefix: `/ecs/${this.name}-`,
|
|
57
|
+
tags: constants_1.commonTags,
|
|
58
|
+
}, { parent: this });
|
|
59
|
+
return logGroup;
|
|
60
|
+
}
|
|
61
|
+
createPersistentStorage({ vpcId, vpcCidrBlock, subnetIds, }) {
|
|
62
|
+
const efs = new aws.efs.FileSystem(`${this.name}-efs`, {
|
|
63
|
+
encrypted: true,
|
|
64
|
+
lifecyclePolicies: [
|
|
65
|
+
{
|
|
66
|
+
transitionToPrimaryStorageClass: 'AFTER_1_ACCESS',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
transitionToIa: 'AFTER_7_DAYS',
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
performanceMode: 'generalPurpose',
|
|
73
|
+
throughputMode: 'bursting',
|
|
74
|
+
tags: Object.assign(Object.assign({}, constants_1.commonTags), { Name: `${this.name}-data` }),
|
|
75
|
+
}, { parent: this });
|
|
76
|
+
const securityGroup = new aws.ec2.SecurityGroup(`${this.name}-persistent-storage-security-group`, {
|
|
77
|
+
vpcId: vpcId,
|
|
78
|
+
ingress: [
|
|
79
|
+
{
|
|
80
|
+
fromPort: 2049,
|
|
81
|
+
toPort: 2049,
|
|
82
|
+
protocol: 'tcp',
|
|
83
|
+
cidrBlocks: [vpcCidrBlock],
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
tags: constants_1.commonTags,
|
|
87
|
+
}, { parent: this });
|
|
88
|
+
pulumi.all([subnetIds]).apply(([ids]) => {
|
|
89
|
+
ids.forEach(it => {
|
|
90
|
+
const mountTarget = new aws.efs.MountTarget(`${this.name}-mount-target-${it}`, {
|
|
91
|
+
fileSystemId: efs.id,
|
|
92
|
+
subnetId: it,
|
|
93
|
+
securityGroups: [securityGroup.id],
|
|
94
|
+
}, { parent: this });
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
return efs;
|
|
98
|
+
}
|
|
99
|
+
createTaskDefinition(args) {
|
|
100
|
+
const argsWithDefaults = Object.assign({}, defaults, args);
|
|
101
|
+
const stack = pulumi.getStack();
|
|
102
|
+
const secretManagerSecretsInlinePolicy = {
|
|
103
|
+
name: `${this.name}-secret-manager-access`,
|
|
104
|
+
policy: JSON.stringify({
|
|
105
|
+
Version: '2012-10-17',
|
|
106
|
+
Statement: [
|
|
107
|
+
{
|
|
108
|
+
Sid: 'AllowContainerToGetSecretManagerSecrets',
|
|
109
|
+
Effect: 'Allow',
|
|
110
|
+
Action: ['secretsmanager:GetSecretValue'],
|
|
111
|
+
Resource: '*',
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
}),
|
|
115
|
+
};
|
|
116
|
+
const taskExecutionRole = new aws.iam.Role(`${this.name}-ecs-task-exec-role`, {
|
|
117
|
+
namePrefix: `${this.name}-ecs-task-exec-role-`,
|
|
118
|
+
assumeRolePolicy: exports.assumeRolePolicy,
|
|
119
|
+
managedPolicyArns: [
|
|
120
|
+
'arn:aws:iam::aws:policy/CloudWatchFullAccess',
|
|
121
|
+
'arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess',
|
|
122
|
+
],
|
|
123
|
+
inlinePolicies: [
|
|
124
|
+
secretManagerSecretsInlinePolicy,
|
|
125
|
+
...argsWithDefaults.taskExecutionRoleInlinePolicies,
|
|
126
|
+
],
|
|
127
|
+
tags: constants_1.commonTags,
|
|
128
|
+
}, { parent: this });
|
|
129
|
+
const execCmdInlinePolicy = {
|
|
130
|
+
name: `${this.name}-ecs-exec`,
|
|
131
|
+
policy: JSON.stringify({
|
|
132
|
+
Version: '2012-10-17',
|
|
133
|
+
Statement: [
|
|
134
|
+
{
|
|
135
|
+
Sid: 'AllowContainerToCreateECSExecSSMChannel',
|
|
136
|
+
Effect: 'Allow',
|
|
137
|
+
Action: [
|
|
138
|
+
'ssmmessages:CreateControlChannel',
|
|
139
|
+
'ssmmessages:CreateDataChannel',
|
|
140
|
+
'ssmmessages:OpenControlChannel',
|
|
141
|
+
'ssmmessages:OpenDataChannel',
|
|
142
|
+
],
|
|
143
|
+
Resource: '*',
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
}),
|
|
147
|
+
};
|
|
148
|
+
const taskRole = new aws.iam.Role(`${this.name}-ecs-task-role`, {
|
|
149
|
+
namePrefix: `${this.name}-ecs-task-role-`,
|
|
150
|
+
assumeRolePolicy: exports.assumeRolePolicy,
|
|
151
|
+
inlinePolicies: [
|
|
152
|
+
execCmdInlinePolicy,
|
|
153
|
+
...argsWithDefaults.taskRoleInlinePolicies,
|
|
154
|
+
],
|
|
155
|
+
tags: constants_1.commonTags,
|
|
156
|
+
}, { parent: this });
|
|
157
|
+
const parsedSize = pulumi.all([argsWithDefaults.size]).apply(([size]) => {
|
|
158
|
+
const mapCapabilities = ({ cpu, memory }) => ({
|
|
159
|
+
cpu: String(cpu),
|
|
160
|
+
memory: String(memory),
|
|
161
|
+
});
|
|
162
|
+
if (typeof size === 'string') {
|
|
163
|
+
return mapCapabilities(constants_1.PredefinedSize[size]);
|
|
164
|
+
}
|
|
165
|
+
if (typeof size === 'object') {
|
|
166
|
+
return mapCapabilities(size);
|
|
167
|
+
}
|
|
168
|
+
throw Error('Incorrect EcsService size argument');
|
|
169
|
+
});
|
|
170
|
+
const taskDefinition = new aws.ecs.TaskDefinition(`${this.name}-task-definition`, Object.assign(Object.assign({ family: `${this.name}-task-definition-${stack}`, networkMode: 'awsvpc', executionRoleArn: taskExecutionRole.arn, taskRoleArn: taskRole.arn, cpu: parsedSize.cpu, memory: parsedSize.memory, requiresCompatibilities: ['FARGATE'], containerDefinitions: pulumi
|
|
171
|
+
.all([
|
|
172
|
+
this.name,
|
|
173
|
+
argsWithDefaults.image,
|
|
174
|
+
argsWithDefaults.port,
|
|
175
|
+
argsWithDefaults.environment,
|
|
176
|
+
argsWithDefaults.secrets,
|
|
177
|
+
argsWithDefaults.persistentStorageVolumePath,
|
|
178
|
+
argsWithDefaults.dockerCommand,
|
|
179
|
+
this.logGroup.name,
|
|
180
|
+
exports.awsRegion,
|
|
181
|
+
])
|
|
182
|
+
.apply(([containerName, image, port, environment, secrets, persistentStorageVolumePath, command, logGroup, region,]) => {
|
|
183
|
+
return JSON.stringify([
|
|
184
|
+
Object.assign(Object.assign({ readonlyRootFilesystem: false, name: containerName, image, essential: true, portMappings: [
|
|
185
|
+
{
|
|
186
|
+
containerPort: port,
|
|
187
|
+
protocol: 'tcp',
|
|
188
|
+
},
|
|
189
|
+
] }, (persistentStorageVolumePath && {
|
|
190
|
+
mountPoints: [
|
|
191
|
+
{
|
|
192
|
+
containerPath: persistentStorageVolumePath,
|
|
193
|
+
sourceVolume: `${this.name}-volume`,
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
})), { logConfiguration: {
|
|
197
|
+
logDriver: 'awslogs',
|
|
198
|
+
options: {
|
|
199
|
+
'awslogs-group': logGroup,
|
|
200
|
+
'awslogs-region': region,
|
|
201
|
+
'awslogs-stream-prefix': 'ecs',
|
|
202
|
+
},
|
|
203
|
+
}, command,
|
|
204
|
+
environment,
|
|
205
|
+
secrets }),
|
|
206
|
+
]);
|
|
207
|
+
}) }, (argsWithDefaults.persistentStorageVolumePath && {
|
|
208
|
+
volumes: [
|
|
209
|
+
{
|
|
210
|
+
name: `${this.name}-volume`,
|
|
211
|
+
efsVolumeConfiguration: {
|
|
212
|
+
fileSystemId: this.createPersistentStorage(argsWithDefaults).id,
|
|
213
|
+
transitEncryption: 'ENABLED',
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
})), { tags: Object.assign(Object.assign({}, constants_1.commonTags), argsWithDefaults.tags) }), { parent: this });
|
|
218
|
+
return taskDefinition;
|
|
219
|
+
}
|
|
220
|
+
createServiceDiscovery(vpcId) {
|
|
221
|
+
const privateDnsNamespace = new aws.servicediscovery.PrivateDnsNamespace(`${this.name}-private-dns-namespace`, {
|
|
222
|
+
vpc: vpcId,
|
|
223
|
+
name: this.name,
|
|
224
|
+
tags: constants_1.commonTags,
|
|
225
|
+
}, { parent: this });
|
|
226
|
+
return new aws.servicediscovery.Service(`mongo-service`, {
|
|
227
|
+
name: this.name,
|
|
228
|
+
dnsConfig: {
|
|
229
|
+
namespaceId: privateDnsNamespace.id,
|
|
230
|
+
dnsRecords: [
|
|
231
|
+
{
|
|
232
|
+
ttl: 10,
|
|
233
|
+
type: 'A',
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
routingPolicy: 'MULTIVALUE',
|
|
237
|
+
},
|
|
238
|
+
tags: constants_1.commonTags,
|
|
239
|
+
}, { parent: this });
|
|
240
|
+
}
|
|
241
|
+
createEcsService(args, opts) {
|
|
242
|
+
const argsWithDefaults = Object.assign({}, defaults, args);
|
|
243
|
+
const securityGroup = argsWithDefaults.securityGroup ||
|
|
244
|
+
new aws.ec2.SecurityGroup(`${this.name}-service-security-group`, {
|
|
245
|
+
vpcId: argsWithDefaults.vpcId,
|
|
246
|
+
ingress: [
|
|
247
|
+
{
|
|
248
|
+
fromPort: 0,
|
|
249
|
+
toPort: 0,
|
|
250
|
+
protocol: '-1',
|
|
251
|
+
cidrBlocks: [argsWithDefaults.vpcCidrBlock],
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
egress: [
|
|
255
|
+
{
|
|
256
|
+
fromPort: 0,
|
|
257
|
+
toPort: 0,
|
|
258
|
+
protocol: '-1',
|
|
259
|
+
cidrBlocks: ['0.0.0.0/0'],
|
|
260
|
+
},
|
|
261
|
+
],
|
|
262
|
+
tags: constants_1.commonTags,
|
|
263
|
+
}, { parent: this });
|
|
264
|
+
const service = new aws.ecs.Service(`${this.name}-service`, Object.assign(Object.assign(Object.assign(Object.assign({ name: this.name, cluster: argsWithDefaults.cluster.id, launchType: 'FARGATE', desiredCount: argsWithDefaults.desiredCount, taskDefinition: this.taskDefinition.arn, enableExecuteCommand: true }, (argsWithDefaults.lbTargetGroupArn && {
|
|
265
|
+
loadBalancers: [
|
|
266
|
+
{
|
|
267
|
+
containerName: this.name,
|
|
268
|
+
containerPort: argsWithDefaults.port,
|
|
269
|
+
targetGroupArn: argsWithDefaults.lbTargetGroupArn,
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
})), { networkConfiguration: {
|
|
273
|
+
assignPublicIp: argsWithDefaults.assignPublicIp,
|
|
274
|
+
subnets: argsWithDefaults.subnetIds,
|
|
275
|
+
securityGroups: [securityGroup.id],
|
|
276
|
+
} }), (argsWithDefaults.enableServiceAutoDiscovery &&
|
|
277
|
+
this.serviceDiscoveryService && {
|
|
278
|
+
serviceRegistries: {
|
|
279
|
+
registryArn: this.serviceDiscoveryService.arn,
|
|
280
|
+
},
|
|
281
|
+
})), { tags: Object.assign(Object.assign({}, constants_1.commonTags), argsWithDefaults.tags) }), {
|
|
282
|
+
parent: this,
|
|
283
|
+
dependsOn: opts.dependsOn,
|
|
284
|
+
});
|
|
285
|
+
return service;
|
|
286
|
+
}
|
|
287
|
+
enableAutoscaling(args) {
|
|
288
|
+
const argsWithDefaults = Object.assign({}, defaults, args);
|
|
289
|
+
const autoscalingTarget = new aws.appautoscaling.Target(`${this.name}-autoscale-target`, {
|
|
290
|
+
minCapacity: argsWithDefaults.autoscaling.minCount,
|
|
291
|
+
maxCapacity: argsWithDefaults.autoscaling.maxCount,
|
|
292
|
+
resourceId: pulumi.interpolate `service/${argsWithDefaults.cluster.name}/${this.service.name}`,
|
|
293
|
+
serviceNamespace: 'ecs',
|
|
294
|
+
scalableDimension: 'ecs:service:DesiredCount',
|
|
295
|
+
tags: constants_1.commonTags,
|
|
296
|
+
}, { parent: this });
|
|
297
|
+
const memoryAutoscalingPolicy = new aws.appautoscaling.Policy(`${this.name}-memory-autoscale-policy`, {
|
|
298
|
+
policyType: 'TargetTrackingScaling',
|
|
299
|
+
resourceId: autoscalingTarget.resourceId,
|
|
300
|
+
scalableDimension: autoscalingTarget.scalableDimension,
|
|
301
|
+
serviceNamespace: autoscalingTarget.serviceNamespace,
|
|
302
|
+
targetTrackingScalingPolicyConfiguration: {
|
|
303
|
+
predefinedMetricSpecification: {
|
|
304
|
+
predefinedMetricType: 'ECSServiceAverageMemoryUtilization',
|
|
305
|
+
},
|
|
306
|
+
targetValue: 70,
|
|
307
|
+
},
|
|
308
|
+
}, { parent: this });
|
|
309
|
+
const cpuAutoscalingPolicy = new aws.appautoscaling.Policy(`${this.name}-cpu-autoscale-policy`, {
|
|
310
|
+
policyType: 'TargetTrackingScaling',
|
|
311
|
+
resourceId: autoscalingTarget.resourceId,
|
|
312
|
+
scalableDimension: autoscalingTarget.scalableDimension,
|
|
313
|
+
serviceNamespace: autoscalingTarget.serviceNamespace,
|
|
314
|
+
targetTrackingScalingPolicyConfiguration: {
|
|
315
|
+
predefinedMetricSpecification: {
|
|
316
|
+
predefinedMetricType: 'ECSServiceAverageCPUUtilization',
|
|
317
|
+
},
|
|
318
|
+
targetValue: 70,
|
|
319
|
+
},
|
|
320
|
+
}, { parent: this });
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
exports.EcsService = EcsService;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as pulumi from '@pulumi/pulumi';
|
|
2
|
+
import * as aws from '@pulumi/aws';
|
|
3
|
+
import { EcsService, EcsServiceArgs } from './ecs-service';
|
|
4
|
+
export type MongoArgs = Pick<EcsServiceArgs, 'size' | 'cluster' | 'vpcId' | 'vpcCidrBlock' | 'tags'> & {
|
|
5
|
+
/**
|
|
6
|
+
* Username for the master DB user.
|
|
7
|
+
*/
|
|
8
|
+
username: pulumi.Input<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Password for the master DB user. If not specified it will be autogenerated.
|
|
11
|
+
* The value will be stored as a secret in AWS Secret Manager.
|
|
12
|
+
*/
|
|
13
|
+
password?: pulumi.Input<string>;
|
|
14
|
+
privateSubnetIds: pulumi.Input<pulumi.Input<string>[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Exposed service port. Defaults to 27017.
|
|
17
|
+
*/
|
|
18
|
+
port?: pulumi.Input<number>;
|
|
19
|
+
};
|
|
20
|
+
export declare class Mongo extends pulumi.ComponentResource {
|
|
21
|
+
name: string;
|
|
22
|
+
service: EcsService;
|
|
23
|
+
passwordSecret: aws.secretsmanager.Secret;
|
|
24
|
+
constructor(name: string, args: MongoArgs, opts?: pulumi.ComponentResourceOptions);
|
|
25
|
+
private createRandomPassword;
|
|
26
|
+
private createPasswordSecret;
|
|
27
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.Mongo = void 0;
|
|
15
|
+
const pulumi = require("@pulumi/pulumi");
|
|
16
|
+
const aws = require("@pulumi/aws");
|
|
17
|
+
const random = require("@pulumi/random");
|
|
18
|
+
const constants_1 = require("../constants");
|
|
19
|
+
const ecs_service_1 = require("./ecs-service");
|
|
20
|
+
class Mongo extends pulumi.ComponentResource {
|
|
21
|
+
constructor(name, args, opts = {}) {
|
|
22
|
+
super('studion:Mongo', name, args, opts);
|
|
23
|
+
const port = args.port || 27017;
|
|
24
|
+
const { username, password, privateSubnetIds } = args, ecsServiceArgs = __rest(args, ["username", "password", "privateSubnetIds"]);
|
|
25
|
+
this.name = name;
|
|
26
|
+
const mongoPassword = password || this.createRandomPassword();
|
|
27
|
+
this.passwordSecret = this.createPasswordSecret(mongoPassword);
|
|
28
|
+
this.service = new ecs_service_1.EcsService(name, Object.assign(Object.assign({}, ecsServiceArgs), { port, image: 'mongo:7.0.3@sha256:238b1636bdd7820c752b91bec8a669f92568eb313ad89a1fc4a92903c1b40489', desiredCount: 1, autoscaling: { enabled: false }, enableServiceAutoDiscovery: true, persistentStorageVolumePath: '/data/db', dockerCommand: ['mongod', '--port', port.toString()], assignPublicIp: false, subnetIds: privateSubnetIds, environment: [
|
|
29
|
+
{
|
|
30
|
+
name: 'MONGO_INITDB_ROOT_USERNAME',
|
|
31
|
+
value: username,
|
|
32
|
+
},
|
|
33
|
+
], secrets: [
|
|
34
|
+
{
|
|
35
|
+
name: 'MONGO_INITDB_ROOT_PASSWORD',
|
|
36
|
+
valueFrom: this.passwordSecret.arn,
|
|
37
|
+
},
|
|
38
|
+
] }), Object.assign(Object.assign({}, opts), { parent: this }));
|
|
39
|
+
this.registerOutputs();
|
|
40
|
+
}
|
|
41
|
+
createRandomPassword() {
|
|
42
|
+
const password = new random.RandomPassword(`${this.name}-mongo-password`, {
|
|
43
|
+
length: 16,
|
|
44
|
+
overrideSpecial: '_%$',
|
|
45
|
+
special: true,
|
|
46
|
+
});
|
|
47
|
+
return password.result;
|
|
48
|
+
}
|
|
49
|
+
createPasswordSecret(password) {
|
|
50
|
+
const project = pulumi.getProject();
|
|
51
|
+
const stack = pulumi.getStack();
|
|
52
|
+
const passwordSecret = new aws.secretsmanager.Secret(`${this.name}-password-secret`, {
|
|
53
|
+
namePrefix: `${stack}/${project}/MongoPassword-`,
|
|
54
|
+
tags: constants_1.commonTags,
|
|
55
|
+
}, { parent: this });
|
|
56
|
+
const passwordSecretValue = new aws.secretsmanager.SecretVersion(`${this.name}-password-secret-value`, {
|
|
57
|
+
secretId: passwordSecret.id,
|
|
58
|
+
secretString: password,
|
|
59
|
+
}, { parent: this, dependsOn: [passwordSecret] });
|
|
60
|
+
return passwordSecret;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.Mongo = Mongo;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as pulumi from '@pulumi/pulumi';
|
|
2
|
+
import * as aws from '@pulumi/aws';
|
|
3
|
+
import { AcmCertificate } from './acm-certificate';
|
|
4
|
+
import { EcsService, EcsServiceArgs } from './ecs-service';
|
|
5
|
+
export type NuxtSSRArgs = Pick<EcsServiceArgs, 'image' | 'port' | 'cluster' | 'vpcId' | 'vpcCidrBlock' | 'desiredCount' | 'autoscaling' | 'size' | 'environment' | 'secrets' | 'tags'> & {
|
|
6
|
+
publicSubnetIds: pulumi.Input<pulumi.Input<string>[]>;
|
|
7
|
+
/**
|
|
8
|
+
* The domain which will be used to access the service.
|
|
9
|
+
* The domain or subdomain must belong to the provided hostedZone.
|
|
10
|
+
*/
|
|
11
|
+
domain?: pulumi.Input<string>;
|
|
12
|
+
/**
|
|
13
|
+
* The ID of the hosted zone.
|
|
14
|
+
*/
|
|
15
|
+
hostedZoneId?: pulumi.Input<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Path for the health check request. Defaults to "/".
|
|
18
|
+
*/
|
|
19
|
+
healthCheckPath?: pulumi.Input<string>;
|
|
20
|
+
};
|
|
21
|
+
export declare class NuxtSSR extends pulumi.ComponentResource {
|
|
22
|
+
name: string;
|
|
23
|
+
service: EcsService;
|
|
24
|
+
certificate?: AcmCertificate;
|
|
25
|
+
lbSecurityGroup: aws.ec2.SecurityGroup;
|
|
26
|
+
serviceSecurityGroup: aws.ec2.SecurityGroup;
|
|
27
|
+
customCFHeader: {
|
|
28
|
+
name: pulumi.Output<string>;
|
|
29
|
+
value: pulumi.Output<string>;
|
|
30
|
+
};
|
|
31
|
+
lb: aws.lb.LoadBalancer;
|
|
32
|
+
lbTargetGroup: aws.lb.TargetGroup;
|
|
33
|
+
lbHttpListener: aws.lb.Listener;
|
|
34
|
+
cloudfront: aws.cloudfront.Distribution;
|
|
35
|
+
constructor(name: string, args: NuxtSSRArgs, opts?: pulumi.ComponentResourceOptions);
|
|
36
|
+
private createTlsCertificate;
|
|
37
|
+
private createCustomCFHeader;
|
|
38
|
+
private createLoadBalancer;
|
|
39
|
+
private createSecurityGroup;
|
|
40
|
+
private createEcsService;
|
|
41
|
+
private createCloudfrontDistribution;
|
|
42
|
+
private createDnsRecord;
|
|
43
|
+
}
|