@byaga/cdk-patterns 0.6.0 → 0.7.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/lib/index.d.ts +1 -0
- package/lib/index.js +3 -1
- package/package.json +4 -2
- package/src/ApiCertificate.ts +6 -6
- package/src/{IDeployStack.ts → DeployStack.ts} +4 -4
- package/src/Output.ts +11 -0
- package/src/Role.ts +5 -7
- package/src/StaticWebSite.ts +99 -0
- package/src/index.ts +4 -1
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.IDeployStack = exports.ApiCertificate = void 0;
|
3
|
+
exports.Role = exports.IDeployStack = exports.ApiCertificate = void 0;
|
4
4
|
var ApiCertificate_1 = require("./ApiCertificate");
|
5
5
|
Object.defineProperty(exports, "ApiCertificate", { enumerable: true, get: function () { return ApiCertificate_1.ApiCertificate; } });
|
6
6
|
var IDeployStack_1 = require("./IDeployStack");
|
7
7
|
Object.defineProperty(exports, "IDeployStack", { enumerable: true, get: function () { return IDeployStack_1.IDeployStack; } });
|
8
|
+
var Role_1 = require("./Role");
|
9
|
+
Object.defineProperty(exports, "Role", { enumerable: true, get: function () { return Role_1.Role; } });
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@byaga/cdk-patterns",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.7.0",
|
4
4
|
"description": "Collection of common patterns used when making AWS CloudFormation templates using CDK",
|
5
5
|
"main": "lib/index.js",
|
6
6
|
"types": "lib/index.d.ts",
|
@@ -15,9 +15,11 @@
|
|
15
15
|
"author": "VeryFineHat",
|
16
16
|
"license": "MIT",
|
17
17
|
"dependencies": {
|
18
|
+
"@types/fs-extra": "^11.0.2",
|
18
19
|
"aws-cdk": "^2.92.0",
|
19
20
|
"aws-cdk-lib": "^2.92.0",
|
20
|
-
"constructs": "^10.2.69"
|
21
|
+
"constructs": "^10.2.69",
|
22
|
+
"fs-extra": "^11.1.1"
|
21
23
|
},
|
22
24
|
"devDependencies": {
|
23
25
|
"@types/node": "^20.5.0",
|
package/src/ApiCertificate.ts
CHANGED
@@ -1,31 +1,31 @@
|
|
1
1
|
import {Certificate, CertificateValidation} from "aws-cdk-lib/aws-certificatemanager";
|
2
2
|
import {HostedZone, IHostedZone} from "aws-cdk-lib/aws-route53";
|
3
|
-
import {
|
4
|
-
import
|
3
|
+
import {Output} from "./Output";
|
4
|
+
import DeployStack from "./DeployStack";
|
5
5
|
import IDomainConfig from "./IDomainConfig";
|
6
6
|
|
7
7
|
export class ApiCertificate extends Certificate {
|
8
8
|
hostedZone: IHostedZone
|
9
9
|
domain: string
|
10
10
|
|
11
|
-
constructor(stack:
|
11
|
+
constructor(stack: DeployStack, id: string, domain: IDomainConfig) {
|
12
12
|
const certDomain = [domain.domainName]
|
13
13
|
if (domain.subdomain) certDomain.splice(0, 0, domain.subdomain)
|
14
14
|
const domainName = certDomain.join('.')
|
15
15
|
|
16
|
+
console.log('Getting Hosted Zone', domain.hostedZone.name)
|
16
17
|
const hostedZone: IHostedZone = HostedZone.fromHostedZoneAttributes(stack, stack.genId(id, 'hosted-zone'), {
|
17
18
|
hostedZoneId: domain.hostedZone.id,
|
18
19
|
zoneName: domain.hostedZone.name
|
19
20
|
})
|
21
|
+
console.log('Defining Certificate For', domainName)
|
20
22
|
super(stack, stack.genId(id), {
|
21
23
|
domainName,
|
22
24
|
validation: CertificateValidation.fromDns(hostedZone)
|
23
25
|
});
|
24
26
|
|
25
27
|
this.domain = domainName
|
26
|
-
new
|
27
|
-
value: this.certificateArn ,
|
28
|
-
exportName: stack.genName(id)})
|
28
|
+
new Output(stack, id, this.certificateArn)
|
29
29
|
this.hostedZone = hostedZone
|
30
30
|
}
|
31
31
|
}
|
@@ -2,17 +2,17 @@ import {Stack} from 'aws-cdk-lib';
|
|
2
2
|
import IStackArguments from './IStackArguments'
|
3
3
|
import {IConstruct} from "constructs";
|
4
4
|
|
5
|
-
export class
|
5
|
+
export class DeployStack extends Stack {
|
6
6
|
registry: { [t: string]: { [n: string]: any } } = {}
|
7
7
|
stage: string
|
8
8
|
name: string
|
9
9
|
|
10
10
|
genName(...name: string[]): string {
|
11
|
-
return
|
11
|
+
return DeployStack.genStackResourceName(this.name, this.stage, name.filter(n => !!n).join('-'))
|
12
12
|
}
|
13
13
|
|
14
14
|
genId(...name: string[]): string {
|
15
|
-
return
|
15
|
+
return DeployStack.genStackResourceId(this.name, this.stage, name.filter(n => !!n).join('-'))
|
16
16
|
}
|
17
17
|
|
18
18
|
static genStackResourceName(stackName: string, resource: string, stage = 'develop') {
|
@@ -53,4 +53,4 @@ export class IDeployStack extends Stack {
|
|
53
53
|
return instance;
|
54
54
|
}
|
55
55
|
}
|
56
|
-
export default
|
56
|
+
export default DeployStack
|
package/src/Output.ts
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
import {CfnOutput} from 'aws-cdk-lib/core';
|
2
|
+
import {DeployStack} from './DeployStack';
|
3
|
+
|
4
|
+
export class Output extends CfnOutput {
|
5
|
+
constructor(stack: DeployStack, name: string, value: string) {
|
6
|
+
super(stack, stack.genId(name, 'output'), {
|
7
|
+
value,
|
8
|
+
exportName: stack.genName(name)
|
9
|
+
})
|
10
|
+
}
|
11
|
+
}
|
package/src/Role.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import {FederatedPrincipal, IPrincipal, Role as CdkRole} from "aws-cdk-lib/aws-iam";
|
2
|
-
import {
|
3
|
-
import {
|
2
|
+
import {Duration} from "aws-cdk-lib";
|
3
|
+
import {Output} from './Output'
|
4
|
+
import {DeployStack} from "./DeployStack";
|
4
5
|
import {IManagedPolicy} from "aws-cdk-lib/aws-iam/lib/managed-policy";
|
5
6
|
import {PolicyDocument} from "aws-cdk-lib/aws-iam/lib/policy-document";
|
6
7
|
|
@@ -137,7 +138,7 @@ interface IRoleProps {
|
|
137
138
|
}
|
138
139
|
|
139
140
|
export class Role extends CdkRole {
|
140
|
-
constructor(stack:
|
141
|
+
constructor(stack: DeployStack, id: string, props: IRoleProps) {
|
141
142
|
console.log('Defining Role', stack.genId(id))
|
142
143
|
if (!props.assumedBy) {
|
143
144
|
props.assumedBy = new FederatedPrincipal(
|
@@ -159,9 +160,6 @@ export class Role extends CdkRole {
|
|
159
160
|
roleName: stack.genName(props.roleName || id),
|
160
161
|
assumedBy: props.assumedBy
|
161
162
|
})
|
162
|
-
new
|
163
|
-
value: this.roleArn,
|
164
|
-
exportName: stack.genName(id, 'arn')
|
165
|
-
})
|
163
|
+
new Output(stack, `${id}-arn`, this.roleArn)
|
166
164
|
}
|
167
165
|
}
|
@@ -0,0 +1,99 @@
|
|
1
|
+
import {RemovalPolicy} from "aws-cdk-lib/core";
|
2
|
+
import {Output} from './Output'
|
3
|
+
import {DeployStack} from "./DeployStack";
|
4
|
+
import {execSync} from "child_process";
|
5
|
+
import * as fs from 'fs-extra'
|
6
|
+
import * as path from 'path'
|
7
|
+
import {Bucket} from "aws-cdk-lib/aws-s3"
|
8
|
+
import {BucketDeployment, Source} from "aws-cdk-lib/aws-s3-deployment"
|
9
|
+
import ApiCertificate from "./ApiCertificate";
|
10
|
+
import {
|
11
|
+
CloudFrontAllowedMethods,
|
12
|
+
CloudFrontWebDistribution,
|
13
|
+
OriginAccessIdentity,
|
14
|
+
SSLMethod,
|
15
|
+
ViewerCertificate,
|
16
|
+
ViewerProtocolPolicy
|
17
|
+
} from "aws-cdk-lib/aws-cloudfront"
|
18
|
+
import IDomainConfig from "./IDomainConfig";
|
19
|
+
import {PolicyStatement} from "aws-cdk-lib/aws-iam";
|
20
|
+
import {ARecord, RecordTarget} from "aws-cdk-lib/aws-route53";
|
21
|
+
import {CloudFrontTarget} from "aws-cdk-lib/aws-route53-targets";
|
22
|
+
|
23
|
+
interface StaticWebSiteConfig {
|
24
|
+
srcDir?: string,
|
25
|
+
domain: IDomainConfig,
|
26
|
+
env: NodeJS.ProcessEnv
|
27
|
+
}
|
28
|
+
|
29
|
+
export class StaticWebSite {
|
30
|
+
constructor(stack: DeployStack, id: string, props: StaticWebSiteConfig) {
|
31
|
+
console.log('Deploying Static Web Site', id)
|
32
|
+
const srcDir = path.resolve("../src/", props.srcDir || '')
|
33
|
+
const buildDir = path.resolve("../dist/", props.srcDir || '')
|
34
|
+
|
35
|
+
console.log('Installing Prod Dependencies', id)
|
36
|
+
execSync('npm i --production --quiet', {
|
37
|
+
cwd: srcDir
|
38
|
+
})
|
39
|
+
console.log('Building UI Source', id)
|
40
|
+
execSync('npm run export', {
|
41
|
+
cwd: srcDir,
|
42
|
+
//env: props.env
|
43
|
+
})
|
44
|
+
fs.copySync(path.resolve(srcDir, "./out"), buildDir);
|
45
|
+
|
46
|
+
console.log('Creating HTTPS Certificate', id + '-certificate')
|
47
|
+
const certificate = new ApiCertificate(stack, id + '-certificate', props.domain);
|
48
|
+
console.log('Deploying Site Content Bucket', stack.genId(id, "content-bucket"))
|
49
|
+
const s3BucketSource = new Bucket(stack, stack.genId(id, "content-bucket"), {
|
50
|
+
bucketName: certificate.domain,
|
51
|
+
websiteIndexDocument: "index.html",
|
52
|
+
websiteErrorDocument: "error.html",
|
53
|
+
publicReadAccess: true,
|
54
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
55
|
+
autoDeleteObjects: true
|
56
|
+
});
|
57
|
+
new Output(stack, `${id}-content-bucket`, s3BucketSource.bucketName);
|
58
|
+
|
59
|
+
const cloudFrontPolicy = new PolicyStatement({
|
60
|
+
actions: ['s3:GetBucket*', 's3:GetObject*', 's3:List*'],
|
61
|
+
resources: [s3BucketSource.bucketArn, s3BucketSource.bucketArn + '/*'],
|
62
|
+
})
|
63
|
+
|
64
|
+
new BucketDeployment(stack, stack.genId(id, 'bucket-deployment'), {
|
65
|
+
sources: [Source.asset(buildDir)],
|
66
|
+
destinationBucket: s3BucketSource
|
67
|
+
})
|
68
|
+
const originAccessIdentity = new OriginAccessIdentity(stack, "WebsiteOAI");
|
69
|
+
cloudFrontPolicy.addArnPrincipal(originAccessIdentity.cloudFrontOriginAccessIdentityS3CanonicalUserId)
|
70
|
+
|
71
|
+
const distro = new CloudFrontWebDistribution(stack, stack.genId(id, 'cloudfront-web-distribution'), {
|
72
|
+
enabled: true,
|
73
|
+
//priceClass:
|
74
|
+
originConfigs: [{
|
75
|
+
s3OriginSource: {
|
76
|
+
s3BucketSource,
|
77
|
+
originAccessIdentity
|
78
|
+
},
|
79
|
+
behaviors: [{
|
80
|
+
allowedMethods: CloudFrontAllowedMethods.GET_HEAD_OPTIONS,
|
81
|
+
isDefaultBehavior: true
|
82
|
+
}]
|
83
|
+
}],
|
84
|
+
viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
85
|
+
viewerCertificate: ViewerCertificate.fromAcmCertificate(certificate, {
|
86
|
+
aliases: [certificate.domain],
|
87
|
+
sslMethod: SSLMethod.SNI
|
88
|
+
})
|
89
|
+
})
|
90
|
+
new Output(stack, `${id}-base-url`, "https://" + certificate.domain);
|
91
|
+
|
92
|
+
console.log('Setting Route53 A-Name Record', props.domain.domainName)
|
93
|
+
new ARecord(stack, stack.genId('alias'), {
|
94
|
+
zone: certificate.hostedZone,
|
95
|
+
recordName: certificate.domain,
|
96
|
+
target: RecordTarget.fromAlias(new CloudFrontTarget(distro))
|
97
|
+
})
|
98
|
+
}
|
99
|
+
}
|
package/src/index.ts
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
export {ApiCertificate} from "./ApiCertificate";
|
2
|
-
export {
|
2
|
+
export {DeployStack} from "./DeployStack";
|
3
3
|
export {IDomainConfig} from "./IDomainConfig";
|
4
4
|
export {IHostedZoneConfig} from "./IHostedZoneConfig";
|
5
5
|
export {IStackArguments} from "./IStackArguments";
|
6
|
+
export {Role} from "./Role";
|
7
|
+
export {StaticWebSite} from "./StaticWebSite";
|
8
|
+
export {Output} from "./Output";
|