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.
- package/README.md +6 -0
- package/StaticWebsite.d.ts +24 -0
- package/StaticWebsite.js +3 -0
- package/acceptAlb.d.ts +4 -0
- package/acceptAlb.js +27 -0
- package/acceptBastion.d.ts +4 -0
- package/acceptBastion.js +27 -0
- package/acceptDb.d.ts +4 -0
- package/acceptDb.js +27 -0
- package/accessTheInternet.d.ts +6 -0
- package/accessTheInternet.js +38 -0
- package/alb.d.ts +14 -0
- package/alb.js +34 -0
- package/buildStatic.d.ts +15 -0
- package/buildStatic.js +169 -0
- package/certificate.d.ts +2 -0
- package/certificate.js +42 -0
- package/cloudflare.d.ts +24 -0
- package/cloudflare.js +72 -0
- package/cloudwatchLogs.d.ts +2 -0
- package/cloudwatchLogs.js +34 -0
- package/createBucketWithUser.d.ts +11 -0
- package/createBucketWithUser.js +59 -0
- package/createFargateTask.d.ts +100 -0
- package/createFargateTask.js +321 -0
- package/createImageFromContext.d.ts +12 -0
- package/createImageFromContext.js +24 -0
- package/domain.d.ts +10 -0
- package/domain.js +49 -0
- package/exposePublicService.d.ts +26 -0
- package/exposePublicService.js +105 -0
- package/getAmi.d.ts +7 -0
- package/getAmi.js +35 -0
- package/getDomainAndSubdomain.d.ts +4 -0
- package/getDomainAndSubdomain.js +22 -0
- package/getImageRegistryAndCredentials.d.ts +6 -0
- package/getImageRegistryAndCredentials.js +33 -0
- package/getSecurityGroup.d.ts +6 -0
- package/getSecurityGroup.js +51 -0
- package/lambda.d.ts +19 -0
- package/lambda.js +149 -0
- package/network.d.ts +3 -0
- package/network.js +17 -0
- package/package.json +37 -0
- package/secrets.d.ts +3 -0
- package/secrets.js +12 -0
- package/setupDatabasePermissions.d.ts +2 -0
- package/setupDatabasePermissions.js +18 -0
- package/stack.d.ts +3 -0
- package/stack.js +22 -0
- package/supra.d.ts +7 -0
- package/supra.js +41 -0
- package/utils.d.ts +1 -0
- package/utils.js +11 -0
- package/values.d.ts +11 -0
- package/values.js +51 -0
- package/vpc.d.ts +3 -0
- package/vpc.js +28 -0
- package/withCache.d.ts +1 -0
- package/withCache.js +14 -0
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare type StaticWebsite = {
|
|
2
|
+
domain: string;
|
|
3
|
+
certificateArn?: string;
|
|
4
|
+
additionalDomains?: string[];
|
|
5
|
+
defaultPath?: string;
|
|
6
|
+
corsRules?: {
|
|
7
|
+
allowedHeaders: string[];
|
|
8
|
+
allowedMethods: string[];
|
|
9
|
+
allowedOrigins: string[];
|
|
10
|
+
exposeHeaders: string[];
|
|
11
|
+
maxAgeSeconds: number;
|
|
12
|
+
}[];
|
|
13
|
+
cloudflareDomain?: {
|
|
14
|
+
proxied?: boolean;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Unprotect buckets before safe deletion, leave always in false until
|
|
18
|
+
* deletion of buckets is required.
|
|
19
|
+
*
|
|
20
|
+
* Default: false
|
|
21
|
+
*/
|
|
22
|
+
unprotect?: boolean;
|
|
23
|
+
priceClass?: "PriceClass_All" | "PriceClass_200" | "PriceClass_100";
|
|
24
|
+
};
|
package/StaticWebsite.js
ADDED
package/acceptAlb.d.ts
ADDED
package/acceptAlb.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
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.acceptAlbSecurityGroupId = exports.acceptAlbSecurityGroup = void 0;
|
|
13
|
+
const awsx = require("@pulumi/awsx");
|
|
14
|
+
const values_1 = require("./values");
|
|
15
|
+
const withCache_1 = require("./withCache");
|
|
16
|
+
exports.acceptAlbSecurityGroup = (0, withCache_1.default)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
|
+
const config = yield (0, values_1.getEnvConfiguration)();
|
|
18
|
+
return awsx.ec2.SecurityGroup.fromExistingId(`accept-alb-sg-reference`, config.acceptAlb);
|
|
19
|
+
}));
|
|
20
|
+
function acceptAlbSecurityGroupId() {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
return (yield (0, exports.acceptAlbSecurityGroup)()).id;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
exports.acceptAlbSecurityGroupId = acceptAlbSecurityGroupId;
|
|
26
|
+
exports.default = exports.acceptAlbSecurityGroup;
|
|
27
|
+
//# sourceMappingURL=acceptAlb.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import * as awsx from "@pulumi/awsx";
|
|
2
|
+
export declare const acceptBastionSecurityGroup: () => Promise<awsx.ec2.SecurityGroup>;
|
|
3
|
+
export declare function acceptBastionSecurityGroupId(): Promise<import("@pulumi/pulumi").Output<string>>;
|
|
4
|
+
export default acceptBastionSecurityGroup;
|
package/acceptBastion.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
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.acceptBastionSecurityGroupId = exports.acceptBastionSecurityGroup = void 0;
|
|
13
|
+
const awsx = require("@pulumi/awsx");
|
|
14
|
+
const values_1 = require("./values");
|
|
15
|
+
const withCache_1 = require("./withCache");
|
|
16
|
+
exports.acceptBastionSecurityGroup = (0, withCache_1.default)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
|
+
const config = yield (0, values_1.getEnvConfiguration)();
|
|
18
|
+
return awsx.ec2.SecurityGroup.fromExistingId(`accept-bastion-sg-reference`, config.acceptBastion);
|
|
19
|
+
}));
|
|
20
|
+
function acceptBastionSecurityGroupId() {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
return (yield (0, exports.acceptBastionSecurityGroup)()).id;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
exports.acceptBastionSecurityGroupId = acceptBastionSecurityGroupId;
|
|
26
|
+
exports.default = exports.acceptBastionSecurityGroup;
|
|
27
|
+
//# sourceMappingURL=acceptBastion.js.map
|
package/acceptDb.d.ts
ADDED
package/acceptDb.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
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.acceptDbSecurityGroupId = exports.acceptDbSecurityGroup = void 0;
|
|
13
|
+
const awsx = require("@pulumi/awsx");
|
|
14
|
+
const values_1 = require("./values");
|
|
15
|
+
const withCache_1 = require("./withCache");
|
|
16
|
+
exports.acceptDbSecurityGroup = (0, withCache_1.default)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
|
+
const config = yield (0, values_1.getEnvConfiguration)();
|
|
18
|
+
return awsx.ec2.SecurityGroup.fromExistingId(`accept-db-sg-reference`, config.dbSecurity);
|
|
19
|
+
}));
|
|
20
|
+
function acceptDbSecurityGroupId() {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
return (yield (0, exports.acceptDbSecurityGroup)()).id;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
exports.acceptDbSecurityGroupId = acceptDbSecurityGroupId;
|
|
26
|
+
exports.default = exports.acceptDbSecurityGroup;
|
|
27
|
+
//# sourceMappingURL=acceptDb.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as awsx from "@pulumi/awsx";
|
|
2
|
+
export declare const accessCloudflareSecurityGroup: () => Promise<awsx.ec2.SecurityGroup>;
|
|
3
|
+
export declare const accessTheInternetSecurityGroup: () => Promise<awsx.ec2.SecurityGroup>;
|
|
4
|
+
export declare function accessTheInternetSecurityGroupId(): Promise<import("@pulumi/pulumi").Output<string>>;
|
|
5
|
+
export default accessTheInternetSecurityGroup;
|
|
6
|
+
export declare function accessFromCloudflareSecurityGroup(): Promise<import("@pulumi/pulumi").Output<string>>;
|
|
@@ -0,0 +1,38 @@
|
|
|
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.accessFromCloudflareSecurityGroup = exports.accessTheInternetSecurityGroupId = exports.accessTheInternetSecurityGroup = exports.accessCloudflareSecurityGroup = void 0;
|
|
13
|
+
const awsx = require("@pulumi/awsx");
|
|
14
|
+
const supra_1 = require("./supra");
|
|
15
|
+
const values_1 = require("./values");
|
|
16
|
+
const withCache_1 = require("./withCache");
|
|
17
|
+
exports.accessCloudflareSecurityGroup = (0, withCache_1.default)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
|
+
const config = yield (0, values_1.getEnvConfiguration)(); // ?
|
|
19
|
+
return awsx.ec2.SecurityGroup.fromExistingId(`accept-cloudflare-web-sg-reference`, supra_1.supra.getOutputValue(`cloudflareAcceptWeb`));
|
|
20
|
+
}));
|
|
21
|
+
exports.accessTheInternetSecurityGroup = (0, withCache_1.default)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
+
const config = yield (0, values_1.getEnvConfiguration)(); // ?
|
|
23
|
+
return awsx.ec2.SecurityGroup.fromExistingId(`access-the-internet-sg-reference`, supra_1.supra.getOutputValue(`accessTheInternet`));
|
|
24
|
+
}));
|
|
25
|
+
function accessTheInternetSecurityGroupId() {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
return (yield (0, exports.accessTheInternetSecurityGroup)()).id;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
exports.accessTheInternetSecurityGroupId = accessTheInternetSecurityGroupId;
|
|
31
|
+
exports.default = exports.accessTheInternetSecurityGroup;
|
|
32
|
+
function accessFromCloudflareSecurityGroup() {
|
|
33
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
return (yield (0, exports.accessCloudflareSecurityGroup)()).id;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
exports.accessFromCloudflareSecurityGroup = accessFromCloudflareSecurityGroup;
|
|
38
|
+
//# sourceMappingURL=accessTheInternet.js.map
|
package/alb.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as aws from "@pulumi/aws";
|
|
2
|
+
import * as awsx from "@pulumi/awsx";
|
|
3
|
+
export declare type ElbValues = {
|
|
4
|
+
dns: string;
|
|
5
|
+
elbArn: string;
|
|
6
|
+
elbUrn: string;
|
|
7
|
+
listenerArn: string;
|
|
8
|
+
logs: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const getAlb: () => Promise<{
|
|
11
|
+
dns: string;
|
|
12
|
+
alb: awsx.elasticloadbalancingv2.ApplicationLoadBalancer;
|
|
13
|
+
listener: aws.lb.GetListenerResult;
|
|
14
|
+
}>;
|
package/alb.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
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.getAlb = void 0;
|
|
13
|
+
const aws = require("@pulumi/aws");
|
|
14
|
+
const awsx = require("@pulumi/awsx");
|
|
15
|
+
const domain_1 = require("./domain");
|
|
16
|
+
const supra_1 = require("./supra");
|
|
17
|
+
const withCache_1 = require("./withCache");
|
|
18
|
+
const cache = {
|
|
19
|
+
elbArn: null,
|
|
20
|
+
listenerArn: null,
|
|
21
|
+
elb: null,
|
|
22
|
+
alb: null,
|
|
23
|
+
dns: undefined,
|
|
24
|
+
listener: null
|
|
25
|
+
};
|
|
26
|
+
exports.getAlb = (0, withCache_1.default)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
|
+
const dns = yield supra_1.supra.getOutputValue("dns");
|
|
28
|
+
const loadBalancer = yield supra_1.supra.getOutputValue("albInstance");
|
|
29
|
+
const elbValues = yield supra_1.supra.getOutputValue("elbValues");
|
|
30
|
+
const alb = new awsx.lb.ApplicationLoadBalancer(`${domain_1.env}-alb-all`, { loadBalancer });
|
|
31
|
+
const listener = yield aws.lb.getListener({ arn: elbValues.listenerArn });
|
|
32
|
+
return { dns, alb, listener };
|
|
33
|
+
}));
|
|
34
|
+
//# sourceMappingURL=alb.js.map
|
package/buildStatic.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as pulumi from "@pulumi/pulumi";
|
|
2
|
+
import { StaticWebsite } from "./StaticWebsite";
|
|
3
|
+
export declare function buildStatic(staticSite: StaticWebsite): {
|
|
4
|
+
cloudfrontDistribution: pulumi.Output<string>;
|
|
5
|
+
cloudfrontHostedZoneId: pulumi.Output<string>;
|
|
6
|
+
logsBucket: {
|
|
7
|
+
bucket: pulumi.Output<string>;
|
|
8
|
+
arn: pulumi.Output<string>;
|
|
9
|
+
};
|
|
10
|
+
contentBucketUri: pulumi.Output<string>;
|
|
11
|
+
contentBucket: pulumi.Output<string>;
|
|
12
|
+
contentBucketWebsiteEndpoint: pulumi.Output<string>;
|
|
13
|
+
cloudFrontDomain: pulumi.Output<string>;
|
|
14
|
+
targetDomainEndpoint: string;
|
|
15
|
+
};
|
package/buildStatic.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildStatic = void 0;
|
|
4
|
+
const aws = require("@pulumi/aws");
|
|
5
|
+
const pulumi = require("@pulumi/pulumi");
|
|
6
|
+
const certificate_1 = require("./certificate");
|
|
7
|
+
const cloudflare_1 = require("./cloudflare");
|
|
8
|
+
const domain_1 = require("./domain");
|
|
9
|
+
const getDomainAndSubdomain_1 = require("./getDomainAndSubdomain");
|
|
10
|
+
function buildStatic(staticSite) {
|
|
11
|
+
var _a;
|
|
12
|
+
const protect = !staticSite.unprotect;
|
|
13
|
+
// Load the Pulumi program configuration. These act as the "parameters" to the Pulumi program,
|
|
14
|
+
// so that different Pulumi Stacks can be brought up using the same code.
|
|
15
|
+
const tenMinutes = 60 * 10;
|
|
16
|
+
const aYear = 60 * 60 * 24 * 365;
|
|
17
|
+
const certificateArn = staticSite.certificateArn || (0, certificate_1.getCertificateFor)(staticSite.domain);
|
|
18
|
+
const config = {
|
|
19
|
+
targetDomain: staticSite.domain,
|
|
20
|
+
certificateArn,
|
|
21
|
+
additionalDomains: staticSite.additionalDomains ? staticSite.additionalDomains : [],
|
|
22
|
+
};
|
|
23
|
+
const slug = staticSite.domain.replace(/\./g, "-") + "-";
|
|
24
|
+
// contentBucket is the S3 bucket that the website's contents will be stored in.
|
|
25
|
+
const bucketInfo = {
|
|
26
|
+
acl: "public-read",
|
|
27
|
+
// Configure S3 to serve bucket contents as a website. This way S3 will automatically convert
|
|
28
|
+
// requests for "foo/" to "foo/index.html".
|
|
29
|
+
website: {
|
|
30
|
+
indexDocument: "index.html",
|
|
31
|
+
errorDocument: (_a = staticSite.defaultPath) !== null && _a !== void 0 ? _a : "404.html",
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
if (staticSite.corsRules !== undefined) {
|
|
35
|
+
Object.assign(bucketInfo, { corsRules: staticSite.corsRules });
|
|
36
|
+
}
|
|
37
|
+
const contentBucket = new aws.s3.Bucket(slug + "contentBucket", bucketInfo, {
|
|
38
|
+
protect,
|
|
39
|
+
});
|
|
40
|
+
// logsBucket is an S3 bucket that will contain the CDN's request logs.
|
|
41
|
+
const logsBucket = new aws.s3.Bucket(slug + "logs", {
|
|
42
|
+
acl: "private",
|
|
43
|
+
}, {
|
|
44
|
+
protect,
|
|
45
|
+
});
|
|
46
|
+
const distributionArgs = {
|
|
47
|
+
enabled: true,
|
|
48
|
+
// Alternate aliases the CloudFront distribution can be reached at, in addition to https://xxxx.cloudfront.net.
|
|
49
|
+
// Required if you want to access the distribution via config.targetDomain as well.
|
|
50
|
+
aliases: [config.targetDomain, ...config.additionalDomains],
|
|
51
|
+
// We only specify one origin for this distribution, the S3 content bucket.
|
|
52
|
+
origins: [
|
|
53
|
+
{
|
|
54
|
+
originId: contentBucket.arn,
|
|
55
|
+
domainName: contentBucket.websiteEndpoint,
|
|
56
|
+
customOriginConfig: {
|
|
57
|
+
// Amazon S3 doesn't support HTTPS connections when using an S3 bucket configured as a website endpoint.
|
|
58
|
+
// https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesOriginProtocolPolicy
|
|
59
|
+
originProtocolPolicy: "http-only",
|
|
60
|
+
httpPort: 80,
|
|
61
|
+
httpsPort: 443,
|
|
62
|
+
originSslProtocols: ["TLSv1.2"],
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
defaultRootObject: "index.html",
|
|
67
|
+
// A CloudFront distribution can configure different cache behaviors based on the request path.
|
|
68
|
+
// Here we just specify a single, default cache behavior which is just read-only requests to S3.
|
|
69
|
+
defaultCacheBehavior: {
|
|
70
|
+
targetOriginId: contentBucket.arn,
|
|
71
|
+
viewerProtocolPolicy: "redirect-to-https",
|
|
72
|
+
allowedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
73
|
+
cachedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
74
|
+
forwardedValues: {
|
|
75
|
+
cookies: { forward: "none" },
|
|
76
|
+
// https://aws.amazon.com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/
|
|
77
|
+
headers: ["Access-Control-Request-Headers", "Access-Control-Request-Method", "Origin", "ETag"],
|
|
78
|
+
queryString: false,
|
|
79
|
+
},
|
|
80
|
+
minTtl: 0,
|
|
81
|
+
defaultTtl: tenMinutes,
|
|
82
|
+
maxTtl: aYear,
|
|
83
|
+
compress: true,
|
|
84
|
+
},
|
|
85
|
+
// "All" is the most broad distribution, and also the most expensive.
|
|
86
|
+
// "100" is the least broad, and also the least expensive.
|
|
87
|
+
priceClass: staticSite.priceClass || "PriceClass_100",
|
|
88
|
+
// You can customize error responses. When CloudFront recieves an error from the origin (e.g. S3 or some other
|
|
89
|
+
// web service) it can return a different error code, and return the response for a different resource.
|
|
90
|
+
customErrorResponses: [{ errorCode: 404, responseCode: 404, responsePagePath: "/404.html" }],
|
|
91
|
+
restrictions: {
|
|
92
|
+
geoRestriction: {
|
|
93
|
+
restrictionType: "none",
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
viewerCertificate: {
|
|
97
|
+
acmCertificateArn: certificateArn,
|
|
98
|
+
sslSupportMethod: "sni-only",
|
|
99
|
+
},
|
|
100
|
+
loggingConfig: {
|
|
101
|
+
bucket: logsBucket.bucketDomainName,
|
|
102
|
+
includeCookies: false,
|
|
103
|
+
prefix: `${config.targetDomain}/`,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
const cdn = new aws.cloudfront.Distribution(slug + "cdn", distributionArgs);
|
|
107
|
+
// Creates a new Route53 DNS record pointing the domain to the CloudFront distribution.
|
|
108
|
+
function createAliasRecord(targetDomain, distribution) {
|
|
109
|
+
const domainParts = (0, getDomainAndSubdomain_1.getDomainAndSubdomain)(targetDomain);
|
|
110
|
+
const hostedZoneId = aws.route53
|
|
111
|
+
.getZone({ name: domainParts.parentDomain }, { async: true })
|
|
112
|
+
.then((zone) => zone.zoneId);
|
|
113
|
+
return new aws.route53.Record(targetDomain, {
|
|
114
|
+
name: domainParts.subdomain,
|
|
115
|
+
zoneId: hostedZoneId,
|
|
116
|
+
type: "A",
|
|
117
|
+
aliases: [
|
|
118
|
+
{
|
|
119
|
+
name: distribution.domainName,
|
|
120
|
+
zoneId: distribution.hostedZoneId,
|
|
121
|
+
evaluateTargetHealth: true,
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const cloudflare = staticSite.cloudflareDomain;
|
|
127
|
+
const domainParts = (0, getDomainAndSubdomain_1.getDomainAndSubdomain)(config.targetDomain);
|
|
128
|
+
if (domainParts.parentDomain.replace(/\.$/, '') == domain_1.publicDomain) {
|
|
129
|
+
if (cloudflare && cloudflare.proxied) {
|
|
130
|
+
(0, cloudflare_1.setRecord)({
|
|
131
|
+
proxied: true,
|
|
132
|
+
recordName: domainParts.subdomain,
|
|
133
|
+
type: "CNAME",
|
|
134
|
+
value: cdn.domainName,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
(0, cloudflare_1.setRecord)({
|
|
139
|
+
proxied: false,
|
|
140
|
+
ttl: 120,
|
|
141
|
+
recordName: domainParts.subdomain,
|
|
142
|
+
type: "CNAME",
|
|
143
|
+
value: cdn.domainName,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const aRecord = createAliasRecord(config.targetDomain, cdn);
|
|
148
|
+
// Export properties from this stack. This prints them at the end of `pulumi up` and
|
|
149
|
+
// makes them easier to access from the pulumi.com.
|
|
150
|
+
const contentBucketUri = pulumi.interpolate `s3://${contentBucket.bucket}`;
|
|
151
|
+
const contentBucketWebsiteEndpoint = contentBucket.websiteEndpoint;
|
|
152
|
+
const cloudFrontDomain = cdn.domainName;
|
|
153
|
+
const targetDomainEndpoint = `https://${config.targetDomain}/`;
|
|
154
|
+
return {
|
|
155
|
+
cloudfrontDistribution: cdn.id,
|
|
156
|
+
cloudfrontHostedZoneId: cdn.hostedZoneId,
|
|
157
|
+
logsBucket: {
|
|
158
|
+
bucket: logsBucket.bucket,
|
|
159
|
+
arn: logsBucket.arn,
|
|
160
|
+
},
|
|
161
|
+
contentBucketUri,
|
|
162
|
+
contentBucket: contentBucket.bucket,
|
|
163
|
+
contentBucketWebsiteEndpoint,
|
|
164
|
+
cloudFrontDomain,
|
|
165
|
+
targetDomainEndpoint,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
exports.buildStatic = buildStatic;
|
|
169
|
+
//# sourceMappingURL=buildStatic.js.map
|
package/certificate.d.ts
ADDED
package/certificate.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCertificateFor = void 0;
|
|
4
|
+
const getDomainAndSubdomain_1 = require("./getDomainAndSubdomain");
|
|
5
|
+
const CERTIFICATE_ARNS = {
|
|
6
|
+
// Development
|
|
7
|
+
"decentraland.io": "arn:aws:acm:us-east-1:564327678575:certificate/0e9bc16e-6a3c-4e2d-a93c-314bdab51261",
|
|
8
|
+
"decentraland.zone": "arn:aws:acm:us-east-1:564327678575:certificate/8123afb1-a8b5-415f-996e-37b099cc3baa",
|
|
9
|
+
// Staging
|
|
10
|
+
"decentraland.net": "arn:aws:acm:us-east-1:000333518097:certificate/3f48065d-dfb4-4488-88e3-3bd5fe9bd69d",
|
|
11
|
+
"decentraland.today": "arn:aws:acm:us-east-1:000333518097:certificate/a7c45839-cf2d-452d-b161-97925361e0fe",
|
|
12
|
+
// Pre-production (redirect .org here)
|
|
13
|
+
"decentraland.co": "arn:aws:acm:us-east-1:619079673649:certificate/f767fa77-369a-4559-b5a0-545e1b823c57",
|
|
14
|
+
// Not used
|
|
15
|
+
"decentraland.network": "arn:aws:acm:us-east-1:493726167017:certificate/e4438720-6069-40b1-9736-05f0e4740171",
|
|
16
|
+
// Business
|
|
17
|
+
"decentraland.systems": "arn:aws:acm:us-east-1:110762453957:certificate/eaef9c69-e8e5-4705-b3aa-a04a4bc41501",
|
|
18
|
+
// Business
|
|
19
|
+
"dcl.tools": "arn:aws:acm:us-east-1:493726167017:certificate/c1ae3e9a-7cd2-4561-915e-3c09ae7c0bd6",
|
|
20
|
+
// Production
|
|
21
|
+
"dcl.gg": "arn:aws:acm:us-east-1:619079673649:certificate/657dd8ab-4251-471d-99ce-cc6a7ef87b77",
|
|
22
|
+
// Production
|
|
23
|
+
"mana.network": "arn:aws:acm:us-east-1:493726167017:certificate/2cac1242-fe97-45d6-b80e-9405923bd84d",
|
|
24
|
+
// Production
|
|
25
|
+
"decentraland.org": "arn:aws:acm:us-east-1:619079673649:certificate/64b31250-8656-4bf3-ad74-dc5def47476d",
|
|
26
|
+
};
|
|
27
|
+
function getCertificateFor(domain, arn) {
|
|
28
|
+
if (arn) {
|
|
29
|
+
return arn;
|
|
30
|
+
}
|
|
31
|
+
const domainParts = (0, getDomainAndSubdomain_1.getDomainAndSubdomain)(domain);
|
|
32
|
+
const parent = domainParts.parentDomain.endsWith(".")
|
|
33
|
+
? domainParts.parentDomain.slice(0, domainParts.parentDomain.length - 1)
|
|
34
|
+
: domainParts.parentDomain;
|
|
35
|
+
const result = CERTIFICATE_ARNS[parent];
|
|
36
|
+
if (!result) {
|
|
37
|
+
throw new Error(`No certificate found for ${parent}`);
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
exports.getCertificateFor = getCertificateFor;
|
|
42
|
+
//# sourceMappingURL=certificate.js.map
|
package/cloudflare.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as pulumi from "@pulumi/pulumi";
|
|
2
|
+
import * as cloudflare from "@pulumi/cloudflare";
|
|
3
|
+
export declare type DeployWorkerConfig = {
|
|
4
|
+
jsWorkerFileName: string;
|
|
5
|
+
routes: pulumi.Input<string>[];
|
|
6
|
+
env?: Record<string, pulumi.Input<string>>;
|
|
7
|
+
overrides?: cloudflare.WorkerScriptArgs;
|
|
8
|
+
};
|
|
9
|
+
export declare type SetRecordConfig = {
|
|
10
|
+
recordName: string;
|
|
11
|
+
type: "CNAME" | "A" | "TXT";
|
|
12
|
+
value: pulumi.Input<string>;
|
|
13
|
+
} & ({
|
|
14
|
+
ttl: number;
|
|
15
|
+
proxied: false;
|
|
16
|
+
} | {
|
|
17
|
+
proxied: true;
|
|
18
|
+
});
|
|
19
|
+
export declare function getZoneId(): Promise<string>;
|
|
20
|
+
export declare function deployWorker(workerName: string, config: DeployWorkerConfig): Promise<{
|
|
21
|
+
[x: string]: pulumi.Output<string> | cloudflare.WorkerScript;
|
|
22
|
+
worker: cloudflare.WorkerScript;
|
|
23
|
+
}>;
|
|
24
|
+
export declare function setRecord(config: SetRecordConfig): Promise<cloudflare.Record>;
|
package/cloudflare.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
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.setRecord = exports.deployWorker = exports.getZoneId = void 0;
|
|
13
|
+
const pulumi = require("@pulumi/pulumi");
|
|
14
|
+
const cloudflare = require("@pulumi/cloudflare");
|
|
15
|
+
const domain_1 = require("./domain");
|
|
16
|
+
const fs_1 = require("fs");
|
|
17
|
+
function getZoneId() {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
const res = yield cloudflare.getZones({ filter: { name: domain_1.publicDomain } });
|
|
20
|
+
if (res.zones.length == 0)
|
|
21
|
+
throw new Error(`Zone ${domain_1.publicDomain} not found`);
|
|
22
|
+
return res.zones[0].id;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
exports.getZoneId = getZoneId;
|
|
26
|
+
function deployWorker(workerName, config) {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
// get file contents
|
|
29
|
+
const content = (0, fs_1.readFileSync)(config.jsWorkerFileName).toString();
|
|
30
|
+
// build array of global variables for the workers
|
|
31
|
+
const plainTextBindings = [];
|
|
32
|
+
Object.entries(config.env || {}).forEach(([name, text]) => {
|
|
33
|
+
plainTextBindings.push({ name, text });
|
|
34
|
+
});
|
|
35
|
+
// create the worker
|
|
36
|
+
const worker = new cloudflare.WorkerScript(`${workerName}-${domain_1.publicTLD}`, Object.assign({ name: `${workerName}-${domain_1.publicTLD}`, content,
|
|
37
|
+
plainTextBindings }, (config.overrides || {})));
|
|
38
|
+
const ret = { [workerName + "-" + domain_1.publicTLD]: worker.id, worker };
|
|
39
|
+
// create the routes
|
|
40
|
+
let count = 0;
|
|
41
|
+
for (let pattern of config.routes) {
|
|
42
|
+
const contentRoute = new cloudflare.WorkerRoute(`${workerName}-route-${count}`, {
|
|
43
|
+
pattern,
|
|
44
|
+
scriptName: worker.name,
|
|
45
|
+
zoneId: getZoneId(),
|
|
46
|
+
}, { aliases: [pulumi.interpolate `${workerName}-route-${pattern}`] });
|
|
47
|
+
count++;
|
|
48
|
+
ret[workerName + "-" + domain_1.publicTLD + "-route"] = contentRoute.id;
|
|
49
|
+
}
|
|
50
|
+
return ret;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
exports.deployWorker = deployWorker;
|
|
54
|
+
function setRecord(config) {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
if (!config.proxied && config.ttl < 120) {
|
|
57
|
+
throw new Error("Min TTL is 120");
|
|
58
|
+
}
|
|
59
|
+
// create the record
|
|
60
|
+
const record = new cloudflare.Record(`${config.recordName}-${config.type}-${domain_1.publicTLD}`, {
|
|
61
|
+
type: config.type,
|
|
62
|
+
name: config.recordName,
|
|
63
|
+
value: config.value,
|
|
64
|
+
ttl: config.proxied ? 1 : config.ttl,
|
|
65
|
+
zoneId: getZoneId(),
|
|
66
|
+
proxied: config.proxied,
|
|
67
|
+
});
|
|
68
|
+
return record;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
exports.setRecord = setRecord;
|
|
72
|
+
//# sourceMappingURL=cloudflare.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cloudwatchSetup = exports.ec2BasicCloudwatchProfileName = void 0;
|
|
4
|
+
exports.ec2BasicCloudwatchProfileName = 'EC2CloudwatchBasicProfile';
|
|
5
|
+
const cloudwatchSetup = (logGroupName, filePath = '/var/log/syslog') => {
|
|
6
|
+
return `wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
|
|
7
|
+
dpkg -i -E ./amazon-cloudwatch-agent.deb
|
|
8
|
+
rm amazon-cloudwatch-agent.deb
|
|
9
|
+
|
|
10
|
+
cat << EOF > /opt/aws/amazon-cloudwatch-agent/bin/config.json
|
|
11
|
+
{
|
|
12
|
+
"agent": {
|
|
13
|
+
"run_as_user": "root"
|
|
14
|
+
},
|
|
15
|
+
"logs": {
|
|
16
|
+
"logs_collected": {
|
|
17
|
+
"files": {
|
|
18
|
+
"collect_list": [
|
|
19
|
+
{
|
|
20
|
+
"file_path": "${filePath}",
|
|
21
|
+
"log_group_name": "${logGroupName}",
|
|
22
|
+
"log_stream_name": "{instance_id}"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
EOF
|
|
30
|
+
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json -s
|
|
31
|
+
`;
|
|
32
|
+
};
|
|
33
|
+
exports.cloudwatchSetup = cloudwatchSetup;
|
|
34
|
+
//# sourceMappingURL=cloudwatchLogs.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as aws from "@pulumi/aws";
|
|
2
|
+
import { BucketArgs } from "@pulumi/aws/s3/bucket";
|
|
3
|
+
import * as pulumi from "@pulumi/pulumi";
|
|
4
|
+
export declare function createBucketWithUser(name: string, bucketArgs?: BucketArgs): {
|
|
5
|
+
role: aws.iam.Role;
|
|
6
|
+
user: pulumi.Output<string>;
|
|
7
|
+
bucket: pulumi.Output<string>;
|
|
8
|
+
bucketPolicyId: pulumi.Output<string>;
|
|
9
|
+
accessKeyId: pulumi.Output<string>;
|
|
10
|
+
secretAccessKey: pulumi.Output<string>;
|
|
11
|
+
};
|