dcl-ops-lib 5.17.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.
Files changed (60) hide show
  1. package/README.md +6 -0
  2. package/StaticWebsite.d.ts +24 -0
  3. package/StaticWebsite.js +3 -0
  4. package/acceptAlb.d.ts +4 -0
  5. package/acceptAlb.js +27 -0
  6. package/acceptBastion.d.ts +4 -0
  7. package/acceptBastion.js +27 -0
  8. package/acceptDb.d.ts +4 -0
  9. package/acceptDb.js +27 -0
  10. package/accessTheInternet.d.ts +6 -0
  11. package/accessTheInternet.js +38 -0
  12. package/alb.d.ts +14 -0
  13. package/alb.js +34 -0
  14. package/buildStatic.d.ts +15 -0
  15. package/buildStatic.js +169 -0
  16. package/certificate.d.ts +2 -0
  17. package/certificate.js +42 -0
  18. package/cloudflare.d.ts +24 -0
  19. package/cloudflare.js +72 -0
  20. package/cloudwatchLogs.d.ts +2 -0
  21. package/cloudwatchLogs.js +34 -0
  22. package/createBucketWithUser.d.ts +11 -0
  23. package/createBucketWithUser.js +59 -0
  24. package/createFargateTask.d.ts +100 -0
  25. package/createFargateTask.js +321 -0
  26. package/createImageFromContext.d.ts +12 -0
  27. package/createImageFromContext.js +24 -0
  28. package/domain.d.ts +10 -0
  29. package/domain.js +49 -0
  30. package/exposePublicService.d.ts +26 -0
  31. package/exposePublicService.js +105 -0
  32. package/getAmi.d.ts +7 -0
  33. package/getAmi.js +35 -0
  34. package/getDomainAndSubdomain.d.ts +4 -0
  35. package/getDomainAndSubdomain.js +22 -0
  36. package/getImageRegistryAndCredentials.d.ts +6 -0
  37. package/getImageRegistryAndCredentials.js +33 -0
  38. package/getSecurityGroup.d.ts +6 -0
  39. package/getSecurityGroup.js +51 -0
  40. package/lambda.d.ts +19 -0
  41. package/lambda.js +149 -0
  42. package/network.d.ts +3 -0
  43. package/network.js +17 -0
  44. package/package.json +37 -0
  45. package/secrets.d.ts +3 -0
  46. package/secrets.js +12 -0
  47. package/setupDatabasePermissions.d.ts +2 -0
  48. package/setupDatabasePermissions.js +18 -0
  49. package/stack.d.ts +3 -0
  50. package/stack.js +22 -0
  51. package/supra.d.ts +7 -0
  52. package/supra.js +41 -0
  53. package/utils.d.ts +1 -0
  54. package/utils.js +11 -0
  55. package/values.d.ts +11 -0
  56. package/values.js +51 -0
  57. package/vpc.d.ts +3 -0
  58. package/vpc.js +28 -0
  59. package/withCache.d.ts +1 -0
  60. package/withCache.js +14 -0
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createBucketWithUser = void 0;
4
+ const aws = require("@pulumi/aws");
5
+ const pulumi = require("@pulumi/pulumi");
6
+ function createBucketWithUser(name, bucketArgs) {
7
+ const user = new aws.iam.User(name, {
8
+ name,
9
+ });
10
+ const unprivilegedUserCreds = new aws.iam.AccessKey(name + "-key", {
11
+ user: user.name,
12
+ });
13
+ const bucket = new aws.s3.Bucket(name, bucketArgs);
14
+ const role = new aws.iam.Role(`${name}-role`, {
15
+ description: `Manage ${name} and make it publicly available`,
16
+ assumeRolePolicy: user.arn.apply((arn) => {
17
+ return aws.iam.assumeRolePolicyForPrincipal({ AWS: arn });
18
+ }),
19
+ });
20
+ const policyString = publicReadWithUserWrite(user.arn, bucket.bucket).apply((_) => _);
21
+ const bucketPolicy = new aws.s3.BucketPolicy(`${name}-read-policy`, {
22
+ bucket: bucket.bucket,
23
+ policy: policyString,
24
+ });
25
+ return {
26
+ role,
27
+ user: user.arn,
28
+ bucket: bucket.bucket,
29
+ bucketPolicyId: bucketPolicy.id,
30
+ accessKeyId: unprivilegedUserCreds.id,
31
+ secretAccessKey: unprivilegedUserCreds.secret,
32
+ };
33
+ }
34
+ exports.createBucketWithUser = createBucketWithUser;
35
+ function publicReadWithUserWrite(userArn, bucketName) {
36
+ return pulumi.interpolate `{
37
+ "Version": "2012-10-17",
38
+ "Statement": [
39
+ {
40
+ "Effect": "Allow",
41
+ "Principal": "*",
42
+ "Action": ["s3:GetObject"],
43
+ "Resource": ["arn:aws:s3:::${bucketName}/*"]
44
+ },
45
+ {
46
+ "Effect": "Allow",
47
+ "Action": ["s3:*"],
48
+ "Principal": {
49
+ "AWS": ["${userArn}"]
50
+ },
51
+ "Resource": [
52
+ "arn:aws:s3:::${bucketName}",
53
+ "arn:aws:s3:::${bucketName}/*"
54
+ ]
55
+ }
56
+ ]
57
+ }`;
58
+ }
59
+ //# sourceMappingURL=createBucketWithUser.js.map
@@ -0,0 +1,100 @@
1
+ import * as aws from "@pulumi/aws";
2
+ import * as awsx from "@pulumi/awsx";
3
+ import { ApplicationTargetGroupHealthCheck } from "@pulumi/awsx/lb";
4
+ import * as pulumi from "@pulumi/pulumi";
5
+ import { ExtraExposedServiceOptions } from "./exposePublicService";
6
+ export declare const getDefaultLogs: (serviceName: string, logGroup: aws.cloudwatch.LogGroup) => pulumi.Output<aws.ecs.LogConfiguration>;
7
+ export declare function getClusterInstance(cluster: string | awsx.ecs.Cluster | undefined): awsx.ecs.Cluster;
8
+ export declare type ALBMapping = {
9
+ domain: string;
10
+ dockerListeningPort: number;
11
+ healthCheck?: Partial<ApplicationTargetGroupHealthCheck>;
12
+ extraExposedServiceOptions?: ExtraExposedServiceOptions;
13
+ };
14
+ export declare function getFargateExecutionRole(name: string, policyArnNamedMap: Record<string, pulumi.Input<string> | aws.iam.Policy>): {
15
+ role: aws.iam.Role;
16
+ policies: aws.iam.RolePolicyAttachment[];
17
+ };
18
+ export declare function getFargateTaskRole(name: string, policyArnNamedMap: Record<string, pulumi.Input<string> | aws.iam.Policy>): {
19
+ role: aws.iam.Role;
20
+ policies: aws.iam.RolePolicyAttachment[];
21
+ };
22
+ /**
23
+ *
24
+ * @param serviceName A name for this service. For example, "builder-api"
25
+ * @param dockerImage The docker image to run. "decentraland/builder-server" or "https://myregistry.com/org/imagename"
26
+ * @param dockerListeningPort The port where the HTTP API is exposed.
27
+ * @param environment Mapping of environment variables for the container
28
+ * @param hostname Domain where to serve this API
29
+ * @param options.securityGroups Additional Security Groups to add to the container. For example, the security group allowed to access a DB or an S3 bucket.
30
+ * @param options.cluster The cluster where to run this. If none is provided, the `defaultCluster` will be used ({@see infra/defaultCluster.ts})
31
+ * @param options.healthCheckPath
32
+ * @param options.policyArnNamedMap key-value named map of policies to attach to the default execution role for this task
33
+ */
34
+ export declare function createFargateTask(serviceName: string, dockerImage: string | Promise<string> | pulumi.OutputInstance<string> | awsx.ecs.ContainerImageProvider, dockerListeningPort: number, environment: {
35
+ name: string;
36
+ value: pulumi.Input<string>;
37
+ secret?: boolean;
38
+ }[], hostname: string, options: {
39
+ securityGroups?: (string | pulumi.Output<string>)[];
40
+ cluster?: awsx.ecs.Cluster | string;
41
+ healthCheck?: Partial<ApplicationTargetGroupHealthCheck>;
42
+ desiredCount?: number;
43
+ memoryReservation?: number;
44
+ cpuReservation?: number;
45
+ /**
46
+ * @deprecated use createInternalService() instead
47
+ */
48
+ dontExpose?: true;
49
+ version?: string;
50
+ essential?: boolean;
51
+ command?: string[];
52
+ extraExposedServiceOptions?: ExtraExposedServiceOptions;
53
+ extraPortMappings?: aws.ecs.PortMapping[];
54
+ extraALBMappings?: ALBMapping[];
55
+ executionRolePolicies?: Record<string, pulumi.Input<string> | aws.iam.Policy>;
56
+ taskRolePolicies?: Record<string, pulumi.Input<string> | aws.iam.Policy>;
57
+ secrets?: aws.ecs.Secret[] | pulumi.Input<aws.ecs.Secret[]>;
58
+ ignoreServiceDiscovery?: boolean;
59
+ team: "dapps" | "platform" | "data" | "marketing" | "infra";
60
+ metrics?: {
61
+ port?: number | string;
62
+ path: "/metrics";
63
+ jobName?: string;
64
+ };
65
+ dontAssignPublicIp?: boolean;
66
+ dependsOn?: pulumi.Resource[];
67
+ volumes?: aws.types.input.ecs.TaskDefinitionVolume[] | pulumi.Input<aws.types.input.ecs.TaskDefinitionVolume[]>;
68
+ deregistrationDelay?: pulumi.Input<number>;
69
+ mountPoints?: pulumi.Input<aws.ecs.MountPoint[]>;
70
+ }): Promise<{
71
+ service: awsx.ecs.FargateService;
72
+ endpoint: string;
73
+ exposed?: undefined;
74
+ } | {
75
+ endpoint: string;
76
+ service: awsx.ecs.FargateService;
77
+ exposed: {
78
+ domain: string;
79
+ certificate: pulumi.Input<string>;
80
+ record: void | aws.route53.Record;
81
+ targetGroup: awsx.elasticloadbalancingv2.ApplicationTargetGroup;
82
+ cloudflareRecord: void | import("@pulumi/cloudflare").Record;
83
+ };
84
+ }>;
85
+ export declare type InternalServiceOptions = {
86
+ serviceName: string;
87
+ cluster?: string | awsx.ecs.Cluster;
88
+ securityGroups?: awsx.ec2.SecurityGroupOrId[];
89
+ ignoreServiceDiscovery?: boolean;
90
+ serviceDiscoveryPort?: number;
91
+ desiredCount?: number;
92
+ executionRole?: aws.iam.Role;
93
+ taskRole?: aws.iam.Role;
94
+ containerInfo: awsx.ecs.Container;
95
+ assignPublicIp?: boolean;
96
+ dependsOn?: pulumi.Resource[];
97
+ volumes?: pulumi.Input<aws.types.input.ecs.TaskDefinitionVolume[]>;
98
+ team: string;
99
+ };
100
+ export declare function createInternalService(config: InternalServiceOptions): Promise<awsx.ecs.FargateService>;
@@ -0,0 +1,321 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.createInternalService = exports.createFargateTask = exports.getFargateTaskRole = exports.getFargateExecutionRole = exports.getClusterInstance = exports.getDefaultLogs = void 0;
13
+ const aws = require("@pulumi/aws");
14
+ const awsx = require("@pulumi/awsx");
15
+ const pulumi = require("@pulumi/pulumi");
16
+ const acceptAlb_1 = require("./acceptAlb");
17
+ const acceptBastion_1 = require("./acceptBastion");
18
+ const accessTheInternet_1 = require("./accessTheInternet");
19
+ const domain_1 = require("./domain");
20
+ const exposePublicService_1 = require("./exposePublicService");
21
+ const network_1 = require("./network");
22
+ const utils_1 = require("./utils");
23
+ const vpc_1 = require("./vpc");
24
+ const supra_1 = require("./supra");
25
+ const stack_1 = require("./stack");
26
+ const getDefaultLogs = (serviceName, logGroup) => pulumi.all([logGroup.id]).apply(([logGroupId]) => ({
27
+ logDriver: "awslogs",
28
+ options: {
29
+ "awslogs-group": logGroupId,
30
+ "awslogs-region": "us-east-1",
31
+ "awslogs-stream-prefix": serviceName,
32
+ },
33
+ }));
34
+ exports.getDefaultLogs = getDefaultLogs;
35
+ const extraOpts = {
36
+ customTimeouts: {
37
+ create: "15m",
38
+ update: "15m",
39
+ delete: "15m",
40
+ },
41
+ };
42
+ const cachedClusterInstances = {};
43
+ function getClusterInstance(cluster) {
44
+ if (undefined === cluster) {
45
+ const defaultClusterName = `${domain_1.env}-main`;
46
+ cluster = defaultClusterName;
47
+ }
48
+ if (typeof cluster === "string") {
49
+ if (!cachedClusterInstances[cluster]) {
50
+ cachedClusterInstances[cluster] = new awsx.ecs.Cluster(cluster + "-ref", {
51
+ cluster: aws.ecs.Cluster.get(cluster + "-ref-2", cluster),
52
+ });
53
+ }
54
+ return cachedClusterInstances[cluster];
55
+ }
56
+ return cluster;
57
+ }
58
+ exports.getClusterInstance = getClusterInstance;
59
+ function getFargateExecutionRole(name, policyArnNamedMap) {
60
+ const assumeRolePolicy = awsx.ecs.TaskDefinition.defaultRoleAssumeRolePolicy();
61
+ const dependsOn = Object.values(policyArnNamedMap).filter(($) => $ instanceof pulumi.Resource);
62
+ const role = new aws.iam.Role(name, { assumeRolePolicy }, { dependsOn });
63
+ const policies = [];
64
+ awsx.ecs.TaskDefinition.defaultExecutionRolePolicyARNs().forEach((policyArn) => {
65
+ policies.push(new aws.iam.RolePolicyAttachment(`${name}-default-${(0, utils_1.sha256hash)(policyArn)}`, { role, policyArn }, { parent: role }));
66
+ });
67
+ Object.entries(policyArnNamedMap).forEach(([key, policyArn]) => {
68
+ if (policyArn instanceof aws.iam.Policy) {
69
+ policies.push(new aws.iam.RolePolicyAttachment(`${name}-${key}`, { role, policyArn: policyArn.arn }, { parent: role }));
70
+ }
71
+ else {
72
+ policies.push(new aws.iam.RolePolicyAttachment(`${name}-${key}`, { role, policyArn }, { parent: role }));
73
+ }
74
+ });
75
+ return { role, policies };
76
+ }
77
+ exports.getFargateExecutionRole = getFargateExecutionRole;
78
+ function getFargateTaskRole(name, policyArnNamedMap) {
79
+ const assumeRolePolicy = awsx.ecs.TaskDefinition.defaultRoleAssumeRolePolicy();
80
+ const dependsOn = Object.values(policyArnNamedMap).filter(($) => $ instanceof pulumi.Resource);
81
+ const role = new aws.iam.Role(name, { assumeRolePolicy }, { dependsOn });
82
+ const policies = [];
83
+ awsx.ecs.TaskDefinition.defaultTaskRolePolicyARNs().forEach((policyArn) => {
84
+ policies.push(new aws.iam.RolePolicyAttachment(`${name}-default-${(0, utils_1.sha256hash)(policyArn)}`, { role, policyArn }, { parent: role }));
85
+ });
86
+ Object.entries(policyArnNamedMap).forEach(([key, policyArn]) => {
87
+ if (policyArn instanceof aws.iam.Policy) {
88
+ policies.push(new aws.iam.RolePolicyAttachment(`${name}-${key}`, { role, policyArn: policyArn.arn }, { parent: role }));
89
+ }
90
+ else {
91
+ policies.push(new aws.iam.RolePolicyAttachment(`${name}-${key}`, { role, policyArn }, { parent: role }));
92
+ }
93
+ });
94
+ return { role, policies };
95
+ }
96
+ exports.getFargateTaskRole = getFargateTaskRole;
97
+ /**
98
+ *
99
+ * @param serviceName A name for this service. For example, "builder-api"
100
+ * @param dockerImage The docker image to run. "decentraland/builder-server" or "https://myregistry.com/org/imagename"
101
+ * @param dockerListeningPort The port where the HTTP API is exposed.
102
+ * @param environment Mapping of environment variables for the container
103
+ * @param hostname Domain where to serve this API
104
+ * @param options.securityGroups Additional Security Groups to add to the container. For example, the security group allowed to access a DB or an S3 bucket.
105
+ * @param options.cluster The cluster where to run this. If none is provided, the `defaultCluster` will be used ({@see infra/defaultCluster.ts})
106
+ * @param options.healthCheckPath
107
+ * @param options.policyArnNamedMap key-value named map of policies to attach to the default execution role for this task
108
+ */
109
+ function createFargateTask(serviceName, dockerImage, dockerListeningPort, environment, hostname, options) {
110
+ return __awaiter(this, void 0, void 0, function* () {
111
+ let { healthCheck, essential, dontExpose, securityGroups, cluster, memoryReservation, command, version, desiredCount, cpuReservation, extraPortMappings, extraALBMappings, executionRolePolicies, taskRolePolicies, ignoreServiceDiscovery, secrets, metrics, dontAssignPublicIp, dependsOn, volumes, deregistrationDelay, mountPoints, team, } = options;
112
+ if (undefined === essential) {
113
+ essential = true;
114
+ }
115
+ if (undefined === memoryReservation) {
116
+ memoryReservation = 512;
117
+ }
118
+ if (undefined === cpuReservation) {
119
+ cpuReservation = 256;
120
+ }
121
+ if (undefined === desiredCount) {
122
+ desiredCount = 1;
123
+ }
124
+ if (undefined === securityGroups) {
125
+ securityGroups = [];
126
+ }
127
+ if (undefined === version) {
128
+ version = (0, stack_1.getStackId)();
129
+ }
130
+ if (undefined === extraPortMappings) {
131
+ extraPortMappings = [];
132
+ }
133
+ if (undefined === extraALBMappings) {
134
+ extraALBMappings = [];
135
+ }
136
+ if (undefined === dependsOn) {
137
+ dependsOn = [];
138
+ }
139
+ if (undefined === mountPoints) {
140
+ dependsOn = [];
141
+ }
142
+ const { role: executionRole, policies: executionPolicies } = getFargateExecutionRole(`${serviceName}-${version}-execution`, executionRolePolicies || {});
143
+ dependsOn.push(...executionPolicies);
144
+ const { role: taskRole, policies } = getFargateTaskRole(`${serviceName}-${version}-task`, taskRolePolicies || {});
145
+ dependsOn.push(...policies);
146
+ let dockerLabels = {};
147
+ if (metrics && (metrics.port || dockerListeningPort)) {
148
+ dockerLabels.ECS_PROMETHEUS_EXPORTER_PORT =
149
+ "" + (metrics.port || dockerListeningPort);
150
+ dockerLabels.ECS_PROMETHEUS_METRICS_PATH = metrics.path || "/metrics";
151
+ if (metrics.jobName) {
152
+ dockerLabels.ECS_PROMETHEUS_JOB_NAME = metrics.jobName;
153
+ }
154
+ else {
155
+ dockerLabels.ECS_PROMETHEUS_JOB_NAME = serviceName;
156
+ }
157
+ }
158
+ // this port should be the internal port used for administrative purposes
159
+ let serviceDiscoveryPort = dockerListeningPort;
160
+ if (dockerLabels.ECS_PROMETHEUS_EXPORTER_PORT) {
161
+ const vpc = yield (0, vpc_1.getVpc)();
162
+ const ingress = [];
163
+ new Set(dockerLabels.ECS_PROMETHEUS_EXPORTER_PORT.split(/;/g).map(($) => parseInt($))).forEach((port) => {
164
+ // create a security group to enable metrics access by cwagent from inside the VPC
165
+ ingress.push({
166
+ fromPort: port,
167
+ toPort: port,
168
+ protocol: "tcp",
169
+ cidrBlocks: [vpc.vpc.cidrBlock],
170
+ });
171
+ if (!extraPortMappings.find(($) => $.hostPort != metrics.port) &&
172
+ (port != dockerListeningPort || dontExpose)) {
173
+ extraPortMappings.push({
174
+ containerPort: port,
175
+ hostPort: port,
176
+ protocol: "tcp",
177
+ });
178
+ }
179
+ serviceDiscoveryPort = port;
180
+ });
181
+ if (ingress.length) {
182
+ const sg = new aws.ec2.SecurityGroup(`${serviceName}-${version}-metrics-sg`, {
183
+ vpcId: vpc.id,
184
+ ingress,
185
+ });
186
+ securityGroups.push(sg.id);
187
+ }
188
+ }
189
+ if (dontExpose) {
190
+ const service = yield createInternalService({
191
+ serviceName,
192
+ cluster,
193
+ desiredCount,
194
+ assignPublicIp: !dontAssignPublicIp,
195
+ serviceDiscoveryPort,
196
+ ignoreServiceDiscovery,
197
+ securityGroups: [
198
+ ...securityGroups,
199
+ yield (0, accessTheInternet_1.accessTheInternetSecurityGroupId)(),
200
+ yield (0, acceptBastion_1.acceptBastionSecurityGroupId)(),
201
+ ],
202
+ containerInfo: {
203
+ secrets,
204
+ environment,
205
+ essential,
206
+ image: dockerImage,
207
+ command,
208
+ memoryReservation,
209
+ cpu: cpuReservation,
210
+ portMappings: extraPortMappings,
211
+ dockerLabels,
212
+ mountPoints,
213
+ },
214
+ dependsOn,
215
+ volumes,
216
+ team,
217
+ });
218
+ return {
219
+ service,
220
+ endpoint: "not exposed",
221
+ };
222
+ }
223
+ const exposed = yield (0, exposePublicService_1.exposePublicService)(`${serviceName}-${version}`, hostname, dockerListeningPort, healthCheck, undefined, options.extraExposedServiceOptions, deregistrationDelay);
224
+ const extraALBMappingsExposed = [];
225
+ for (let extraALBMapping of extraALBMappings) {
226
+ const exposedExtra = yield (0, exposePublicService_1.exposePublicService)(`${serviceName}-${extraALBMapping.dockerListeningPort}-${version}`, extraALBMapping.domain, extraALBMapping.dockerListeningPort, extraALBMapping.healthCheck, undefined, extraALBMapping.extraExposedServiceOptions);
227
+ extraALBMappingsExposed.push(exposedExtra.targetGroup);
228
+ }
229
+ const portMapping = exposed.targetGroup;
230
+ const service = yield createInternalService({
231
+ serviceName,
232
+ cluster,
233
+ desiredCount,
234
+ executionRole,
235
+ taskRole,
236
+ assignPublicIp: !dontAssignPublicIp,
237
+ ignoreServiceDiscovery,
238
+ securityGroups: [
239
+ ...securityGroups,
240
+ yield (0, accessTheInternet_1.accessTheInternetSecurityGroupId)(),
241
+ yield (0, acceptAlb_1.acceptAlbSecurityGroupId)(),
242
+ yield (0, acceptBastion_1.acceptBastionSecurityGroupId)(),
243
+ ],
244
+ serviceDiscoveryPort,
245
+ containerInfo: {
246
+ secrets,
247
+ environment,
248
+ portMappings: [
249
+ ...extraPortMappings,
250
+ ...extraALBMappingsExposed,
251
+ portMapping,
252
+ ],
253
+ essential,
254
+ image: dockerImage,
255
+ command,
256
+ memoryReservation,
257
+ cpu: cpuReservation,
258
+ dockerLabels,
259
+ mountPoints,
260
+ },
261
+ dependsOn,
262
+ volumes,
263
+ team,
264
+ });
265
+ return { endpoint: `https://${hostname}/`, service, exposed };
266
+ });
267
+ }
268
+ exports.createFargateTask = createFargateTask;
269
+ function createInternalService(config) {
270
+ return __awaiter(this, void 0, void 0, function* () {
271
+ let { serviceName, cluster, securityGroups, ignoreServiceDiscovery, serviceDiscoveryPort, desiredCount, executionRole, taskRole, containerInfo, assignPublicIp, dependsOn, volumes, team, } = config;
272
+ if (!desiredCount)
273
+ desiredCount = 1;
274
+ assignPublicIp = !!assignPublicIp;
275
+ let serviceRegistries;
276
+ if (!ignoreServiceDiscovery) {
277
+ const serviceDiscovery = new aws.servicediscovery.Service(serviceName, {
278
+ name: serviceName,
279
+ description: "service discovery for " + serviceName,
280
+ dnsConfig: {
281
+ dnsRecords: [
282
+ { type: "A", ttl: 10 },
283
+ { type: "SRV", ttl: 10 },
284
+ ],
285
+ namespaceId: (0, supra_1.getInternalServiceDiscoveryNamespaceId)(),
286
+ },
287
+ });
288
+ serviceRegistries = {
289
+ port: serviceDiscoveryPort,
290
+ registryArn: serviceDiscovery.arn,
291
+ };
292
+ }
293
+ const logGroup = new aws.cloudwatch.LogGroup((0, stack_1.getStackScopedName)(serviceName), {
294
+ name: (0, stack_1.getStackScopedName)(serviceName),
295
+ retentionInDays: 60,
296
+ tags: { ServiceName: serviceName, Team: team },
297
+ });
298
+ return new awsx.ecs.FargateService((0, stack_1.getStackScopedName)(serviceName), {
299
+ cluster: getClusterInstance(cluster),
300
+ tags: { ServiceName: serviceName, StackId: (0, stack_1.getStackId)() },
301
+ subnets: yield (0, network_1.getPrivateSubnetIds)(),
302
+ securityGroups: securityGroups,
303
+ serviceRegistries,
304
+ desiredCount,
305
+ enableEcsManagedTags: true,
306
+ assignPublicIp,
307
+ taskDefinitionArgs: {
308
+ executionRole,
309
+ taskRole,
310
+ tags: { ServiceName: serviceName, Team: team },
311
+ logGroup,
312
+ containers: {
313
+ [serviceName]: Object.assign({ logConfiguration: (0, exports.getDefaultLogs)(serviceName, logGroup) }, containerInfo),
314
+ },
315
+ volumes: volumes,
316
+ },
317
+ }, Object.assign(Object.assign({}, extraOpts), { dependsOn }));
318
+ });
319
+ }
320
+ exports.createInternalService = createInternalService;
321
+ //# sourceMappingURL=createFargateTask.js.map
@@ -0,0 +1,12 @@
1
+ import * as aws from "@pulumi/aws";
2
+ import * as docker from "@pulumi/docker";
3
+ import * as pulumi from "@pulumi/pulumi";
4
+ export declare function createImageFromContext(name: string, context: string, options?: Partial<docker.DockerBuild>, imageOpts?: pulumi.ComponentResourceOptions): {
5
+ ecr: aws.ecr.Repository;
6
+ registry: pulumi.Output<{
7
+ server: string;
8
+ username: string;
9
+ password: string;
10
+ }>;
11
+ image: docker.Image;
12
+ };
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createImageFromContext = void 0;
4
+ const aws = require("@pulumi/aws");
5
+ const docker = require("@pulumi/docker");
6
+ const getImageRegistryAndCredentials_1 = require("./getImageRegistryAndCredentials");
7
+ function createImageFromContext(name, context, options, imageOpts) {
8
+ const ecr = new aws.ecr.Repository(name);
9
+ const registry = (0, getImageRegistryAndCredentials_1.getImageRegistryAndCredentials)(ecr);
10
+ const image = new docker.Image(`${name}-image`, {
11
+ imageName: ecr.repositoryUrl,
12
+ build: Object.assign({ context, cacheFrom: true, env: {
13
+ DOCKER_BUILDKIT: "1",
14
+ } }, options),
15
+ registry: registry,
16
+ }, imageOpts);
17
+ return {
18
+ ecr,
19
+ registry,
20
+ image,
21
+ };
22
+ }
23
+ exports.createImageFromContext = createImageFromContext;
24
+ //# sourceMappingURL=createImageFromContext.js.map
package/domain.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ declare const env: string;
2
+ /** Internal TLD { prd=co stg=net dev=io }, managed by AWS */
3
+ declare let envTLD: string;
4
+ /** Public TLD { prd=org, stg=today dev=zone }, managed by Cloudflare */
5
+ declare let publicTLD: string;
6
+ export { env, envTLD, publicTLD };
7
+ /** Internal domain for deployments i.e. "decentraland.co", managed by AWS */
8
+ export declare const domain: string;
9
+ /** Public domain for deployments i.e. "decentraland.org", managed by Cloudflare */
10
+ export declare const publicDomain: string;
package/domain.js ADDED
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.publicDomain = exports.domain = exports.publicTLD = exports.envTLD = exports.env = void 0;
4
+ const env = process.env["ENVIRONMENT"];
5
+ exports.env = env;
6
+ if (env === undefined) {
7
+ throw new Error("Set the ENVIRONMENT environment before proceeding");
8
+ }
9
+ /** Internal TLD { prd=co stg=net dev=io }, managed by AWS */
10
+ let envTLD = "";
11
+ exports.envTLD = envTLD;
12
+ switch (env) {
13
+ case "biz":
14
+ exports.envTLD = envTLD = "systems";
15
+ break;
16
+ case "prd":
17
+ exports.envTLD = envTLD = "co";
18
+ break;
19
+ case "stg":
20
+ exports.envTLD = envTLD = "net";
21
+ break;
22
+ case "dev":
23
+ default:
24
+ exports.envTLD = envTLD = "io";
25
+ break;
26
+ }
27
+ /** Public TLD { prd=org, stg=today dev=zone }, managed by Cloudflare */
28
+ let publicTLD = "";
29
+ exports.publicTLD = publicTLD;
30
+ switch (env) {
31
+ case "biz":
32
+ exports.publicTLD = publicTLD = "systems";
33
+ break;
34
+ case "prd":
35
+ exports.publicTLD = publicTLD = "org";
36
+ break;
37
+ case "stg":
38
+ exports.publicTLD = publicTLD = "today";
39
+ break;
40
+ case "dev":
41
+ default:
42
+ exports.publicTLD = publicTLD = "zone";
43
+ break;
44
+ }
45
+ /** Internal domain for deployments i.e. "decentraland.co", managed by AWS */
46
+ exports.domain = `decentraland.${envTLD}`;
47
+ /** Public domain for deployments i.e. "decentraland.org", managed by Cloudflare */
48
+ exports.publicDomain = `decentraland.${publicTLD}`;
49
+ //# sourceMappingURL=domain.js.map
@@ -0,0 +1,26 @@
1
+ import * as pulumi from "@pulumi/pulumi";
2
+ import * as aws from "@pulumi/aws";
3
+ import * as awsx from "@pulumi/awsx";
4
+ import * as cf from "@pulumi/cloudflare";
5
+ import { ApplicationTargetGroupHealthCheck } from "@pulumi/awsx/lb";
6
+ export declare type ExtraExposedServiceOptions = {
7
+ createCloudflareProxiedSubdomain?: boolean;
8
+ skipInternalDomain?: boolean;
9
+ targetGroupConditions?: pulumi.Input<aws.types.input.alb.ListenerRuleCondition>[];
10
+ };
11
+ /**
12
+ * Publicly expose a service on a given domain (with SSL). This will create a
13
+ * Target Group and a Listener for your microservice. Additionally, it will
14
+ * create a Route53 mapping of the DNS that will point to the load balancer.
15
+ *
16
+ * @param name the name of your service.
17
+ * @param domain
18
+ * @param port
19
+ */
20
+ export declare function exposePublicService(name: string, domain: string, port: number, healthCheck?: Partial<ApplicationTargetGroupHealthCheck>, vpc?: awsx.ec2.Vpc, extraOptions?: ExtraExposedServiceOptions, deregistrationDelay?: pulumi.Input<number>): Promise<{
21
+ domain: string;
22
+ certificate: pulumi.Input<string>;
23
+ record: void | aws.route53.Record;
24
+ targetGroup: awsx.elasticloadbalancingv2.ApplicationTargetGroup;
25
+ cloudflareRecord: void | cf.Record;
26
+ }>;