@capraconsulting/webapp-deploy-lambda 1.1.1 → 1.2.3
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 +1 -3
- package/dist/webapp_deploy/main.py +49 -22
- package/dist/webapp_deploy/test.py +57 -5
- package/lib/index.d.ts +2 -50
- package/lib/index.js +6 -62
- package/lib/source.d.ts +58 -0
- package/lib/source.js +69 -0
- package/lib/webapp-deploy.d.ts +63 -0
- package/lib/webapp-deploy.js +78 -0
- package/package.json +32 -32
package/README.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# CDK Construct for deploying a webapp release
|
|
2
2
|
|
|
3
|
-
[](https://jenkins.capra.tv/job/cals-internal/job/webapp-deploy-lambda/job/master)
|
|
4
|
-
|
|
5
3
|
This project contains a CDK Construct for an AWS Lambda Function to handle
|
|
6
4
|
deployment of a bundled static web application to a S3 bucket
|
|
7
5
|
while preserving files from previous deployments within a time
|
|
@@ -36,7 +34,7 @@ This project approaches it differently by deleting old files.
|
|
|
36
34
|
A user that still uses an application deployed five days ago should not
|
|
37
35
|
be disrupted. To keep this promise we keep the newest deployment that
|
|
38
36
|
happened more than five days ago, and delete files from older ones that no
|
|
39
|
-
longer have any
|
|
37
|
+
longer have any reference to them.
|
|
40
38
|
|
|
41
39
|
## Triggering a deployment
|
|
42
40
|
|
|
@@ -6,6 +6,7 @@ import sys
|
|
|
6
6
|
import tarfile
|
|
7
7
|
import tempfile
|
|
8
8
|
import time
|
|
9
|
+
import zipfile
|
|
9
10
|
from contextlib import closing
|
|
10
11
|
|
|
11
12
|
from botocore.exceptions import ClientError
|
|
@@ -113,10 +114,55 @@ def upload(bucket, files):
|
|
|
113
114
|
s3_client.upload_file(local_path, bucket, s3_key, ExtraArgs=extra_args)
|
|
114
115
|
|
|
115
116
|
|
|
117
|
+
def extract(artifact_s3_url, source, dest, exclude_pattern):
|
|
118
|
+
pattern_compiled = (
|
|
119
|
+
re.compile(exclude_pattern) if exclude_pattern is not None else None
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
def handle_file(container_path, container_extract):
|
|
123
|
+
name = container_path.lstrip("./")
|
|
124
|
+
if pattern_compiled is not None and pattern_compiled.search(name):
|
|
125
|
+
logger.info("Skipping %s" % name)
|
|
126
|
+
else:
|
|
127
|
+
container_extract(container_path, path=dest + "/")
|
|
128
|
+
logger.info("Extracted %s" % name)
|
|
129
|
+
|
|
130
|
+
logger.info("Extracting archive")
|
|
131
|
+
|
|
132
|
+
if artifact_s3_url.endswith(".zip"):
|
|
133
|
+
logger.info("Found zip file")
|
|
134
|
+
with zipfile.ZipFile(source, "r") as zip:
|
|
135
|
+
for name in zip.namelist():
|
|
136
|
+
handle_file(name, zip.extract)
|
|
137
|
+
|
|
138
|
+
elif artifact_s3_url.endswith(".tgz"):
|
|
139
|
+
logger.info("Found tgz file")
|
|
140
|
+
with tarfile.open(source, "r:gz") as tar:
|
|
141
|
+
for tar_resource in tar:
|
|
142
|
+
if tar_resource.isfile():
|
|
143
|
+
handle_file(tar_resource.name, tar.extract)
|
|
144
|
+
|
|
145
|
+
else:
|
|
146
|
+
raise Exception(f"Unsupported extension: {artifact_s3_url}")
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def construct_all_files(temp_dir, s3_upload_key_base):
|
|
150
|
+
all_files = []
|
|
151
|
+
for root, dirs, files in os.walk(temp_dir):
|
|
152
|
+
for filename in files:
|
|
153
|
+
local_path = os.path.join(root, filename)
|
|
154
|
+
relpath = os.path.relpath(local_path, temp_dir)
|
|
155
|
+
s3_key = os.path.join(s3_upload_key_base, relpath)
|
|
156
|
+
|
|
157
|
+
all_files.append([relpath, local_path, s3_key])
|
|
158
|
+
|
|
159
|
+
return all_files
|
|
160
|
+
|
|
161
|
+
|
|
116
162
|
def deploy(artifact_s3_url, target_s3_url, exclude_pattern):
|
|
117
163
|
"""
|
|
118
164
|
Deploys items from the S3 artifact, which should point to a .tgz
|
|
119
|
-
file, to the target S3 bucket.
|
|
165
|
+
or .zip file, to the target S3 bucket.
|
|
120
166
|
|
|
121
167
|
Returns a list of DeployItem that were uploaded.
|
|
122
168
|
"""
|
|
@@ -126,30 +172,11 @@ def deploy(artifact_s3_url, target_s3_url, exclude_pattern):
|
|
|
126
172
|
|
|
127
173
|
temp_dir = tempfile.mkdtemp()
|
|
128
174
|
|
|
129
|
-
|
|
130
|
-
re.compile(exclude_pattern) if exclude_pattern is not None else None
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
logger.info("Extracting archive")
|
|
134
|
-
with tarfile.open(temp_file.name, "r:gz") as tar:
|
|
135
|
-
for tar_resource in tar:
|
|
136
|
-
if tar_resource.isfile():
|
|
137
|
-
name = tar_resource.name.lstrip("./")
|
|
138
|
-
if pattern_compiled is not None and pattern_compiled.search(name):
|
|
139
|
-
logger.info("Skipping %s" % name)
|
|
140
|
-
else:
|
|
141
|
-
tar.extract(tar_resource.name, path=temp_dir + "/")
|
|
142
|
-
logger.info("Extracted %s" % name)
|
|
175
|
+
extract(artifact_s3_url, temp_file.name, temp_dir, exclude_pattern)
|
|
143
176
|
|
|
144
177
|
s3_upload_bucket, s3_upload_key_base = parse_s3_url(target_s3_url)
|
|
145
178
|
|
|
146
|
-
all_files =
|
|
147
|
-
for root, dirs, files in os.walk(temp_dir):
|
|
148
|
-
for filename in files:
|
|
149
|
-
local_path = os.path.join(root, filename)
|
|
150
|
-
s3_key = os.path.join(s3_upload_key_base, filename)
|
|
151
|
-
|
|
152
|
-
all_files.append([filename, local_path, s3_key])
|
|
179
|
+
all_files = construct_all_files(temp_dir, s3_upload_key_base)
|
|
153
180
|
|
|
154
181
|
deploy_time = int(time.time())
|
|
155
182
|
|
|
@@ -1,9 +1,61 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
import tempfile
|
|
1
4
|
import unittest
|
|
5
|
+
from pathlib import Path
|
|
2
6
|
|
|
3
|
-
#
|
|
4
|
-
from webapp_deploy.main import handler # noqa: F401
|
|
7
|
+
from webapp_deploy.main import construct_all_files, extract # noqa: F401
|
|
5
8
|
|
|
6
9
|
|
|
7
|
-
class
|
|
8
|
-
def
|
|
9
|
-
|
|
10
|
+
class ExtractTest(unittest.TestCase):
|
|
11
|
+
def test_extract_zip(self):
|
|
12
|
+
temp_dir = tempfile.mkdtemp()
|
|
13
|
+
|
|
14
|
+
extract("s3://example/source.zip", "example-assets/source.zip", temp_dir, None)
|
|
15
|
+
|
|
16
|
+
self.assertListEqual(
|
|
17
|
+
sorted(os.listdir(temp_dir)), ["README.md", "index.js", "index.js.map"]
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
shutil.rmtree(temp_dir)
|
|
21
|
+
|
|
22
|
+
def test_extract_tgz(self):
|
|
23
|
+
temp_dir = tempfile.mkdtemp()
|
|
24
|
+
|
|
25
|
+
extract("s3://example/source.tgz", "example-assets/source.tgz", temp_dir, None)
|
|
26
|
+
|
|
27
|
+
self.assertListEqual(
|
|
28
|
+
sorted(os.listdir(temp_dir)), ["README.md", "index.js", "index.js.map"]
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
shutil.rmtree(temp_dir)
|
|
32
|
+
|
|
33
|
+
def test_extract_tgz_filter_pattern(self):
|
|
34
|
+
temp_dir = tempfile.mkdtemp()
|
|
35
|
+
|
|
36
|
+
extract(
|
|
37
|
+
"s3://example/source.tgz", "example-assets/source.tgz", temp_dir, "\\.map$"
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
self.assertListEqual(sorted(os.listdir(temp_dir)), ["README.md", "index.js"])
|
|
41
|
+
|
|
42
|
+
shutil.rmtree(temp_dir)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class Files(unittest.TestCase):
|
|
46
|
+
def test_construct_all_files(self):
|
|
47
|
+
temp_dir = tempfile.mkdtemp()
|
|
48
|
+
|
|
49
|
+
(Path(temp_dir) / "a.txt").write_text("hello")
|
|
50
|
+
Path.mkdir(Path(temp_dir) / "b")
|
|
51
|
+
(Path(temp_dir) / "b/c.txt").write_text("world")
|
|
52
|
+
|
|
53
|
+
self.assertListEqual(
|
|
54
|
+
construct_all_files(temp_dir, "web/"),
|
|
55
|
+
[
|
|
56
|
+
["a.txt", str(Path(temp_dir) / "a.txt"), "web/a.txt"],
|
|
57
|
+
["b/c.txt", str(Path(temp_dir) / "b/c.txt"), "web/b/c.txt"],
|
|
58
|
+
],
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
shutil.rmtree(temp_dir)
|
package/lib/index.d.ts
CHANGED
|
@@ -1,50 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import * as cdk from "@aws-cdk/core";
|
|
4
|
-
export interface WebappDeployProps {
|
|
5
|
-
/**
|
|
6
|
-
* S3 bucket where the artifacts to be deployed are stored.
|
|
7
|
-
*/
|
|
8
|
-
buildsBucket: s3.IBucket;
|
|
9
|
-
/**
|
|
10
|
-
* CloudFront Distribution ID to be invalidated after deploy.
|
|
11
|
-
*
|
|
12
|
-
* @default - none
|
|
13
|
-
*/
|
|
14
|
-
distributionId?: string;
|
|
15
|
-
/**
|
|
16
|
-
* Regex for patterns of files to be discarded during deployment.
|
|
17
|
-
*
|
|
18
|
-
* Example: `\.map$` will exclude `js/myapp-1b22c248f.js.map`.
|
|
19
|
-
*
|
|
20
|
-
* @default - none
|
|
21
|
-
*/
|
|
22
|
-
excludePattern?: string;
|
|
23
|
-
/**
|
|
24
|
-
* The time when a deployment is considered old and will be deleted
|
|
25
|
-
* unless it is the newest old deployment.
|
|
26
|
-
*
|
|
27
|
-
* @default - 5 days
|
|
28
|
-
*/
|
|
29
|
-
pruneDeploymentsOlderThan?: cdk.Duration;
|
|
30
|
-
/**
|
|
31
|
-
* Name of the lambda function to be created.
|
|
32
|
-
*
|
|
33
|
-
* @default cdk.PhysicalName.GENERATE_IF_NEEDED
|
|
34
|
-
*/
|
|
35
|
-
functionName?: string;
|
|
36
|
-
/**
|
|
37
|
-
* Name of S3 bucket where the contents of the artifacts will be deployed.
|
|
38
|
-
* The files will be deployed under the key "web", which is then expected
|
|
39
|
-
* to be the origin for the CloudFront distribution
|
|
40
|
-
*/
|
|
41
|
-
webBucket: s3.IBucket;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Resource to deploy a webapp from a build artifact into an existing
|
|
45
|
-
* S3 Bucket and CloudFront Distribution.
|
|
46
|
-
*/
|
|
47
|
-
export declare class WebappDeploy extends cdk.Construct {
|
|
48
|
-
readonly deployFn: lambda.Function;
|
|
49
|
-
constructor(scope: cdk.Construct, id: string, props: WebappDeployProps);
|
|
50
|
-
}
|
|
1
|
+
export { ISource, Source, SourceConfig } from "./source";
|
|
2
|
+
export { WebappDeploy, WebappDeployProps } from "./webapp-deploy";
|
package/lib/index.js
CHANGED
|
@@ -1,64 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WebappDeploy = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* Resource to deploy a webapp from a build artifact into an existing
|
|
10
|
-
* S3 Bucket and CloudFront Distribution.
|
|
11
|
-
*/
|
|
12
|
-
class WebappDeploy extends cdk.Construct {
|
|
13
|
-
constructor(scope, id, props) {
|
|
14
|
-
var _a, _b;
|
|
15
|
-
super(scope, id);
|
|
16
|
-
const environment = {
|
|
17
|
-
DEPLOY_LOG_BUCKET_URL: `s3://${props.webBucket.bucketName}/deployments.log`,
|
|
18
|
-
EXPIRE_SECONDS: ((_a = props.pruneDeploymentsOlderThan) !== null && _a !== void 0 ? _a : cdk.Duration.days(5))
|
|
19
|
-
.toSeconds()
|
|
20
|
-
.toString(),
|
|
21
|
-
TARGET_BUCKET_URL: `s3://${props.webBucket.bucketName}/web`,
|
|
22
|
-
};
|
|
23
|
-
if (props.distributionId != null) {
|
|
24
|
-
environment.CF_DISTRIBUTION_ID = props.distributionId;
|
|
25
|
-
}
|
|
26
|
-
if (props.excludePattern != null) {
|
|
27
|
-
environment.EXCLUDE_PATTERN = props.excludePattern;
|
|
28
|
-
}
|
|
29
|
-
this.deployFn = new lambda.Function(this, "Resource", {
|
|
30
|
-
code: lambda.Code.fromAsset(path.join(__dirname, "../dist")),
|
|
31
|
-
environment,
|
|
32
|
-
functionName: (_b = props.functionName) !== null && _b !== void 0 ? _b : cdk.PhysicalName.GENERATE_IF_NEEDED,
|
|
33
|
-
handler: "webapp_deploy.main.handler",
|
|
34
|
-
reservedConcurrentExecutions: 1,
|
|
35
|
-
runtime: lambda.Runtime.PYTHON_3_7,
|
|
36
|
-
timeout: cdk.Duration.minutes(2),
|
|
37
|
-
initialPolicy: [
|
|
38
|
-
new iam.PolicyStatement({
|
|
39
|
-
actions: ["s3:HeadObject", "s3:GetObject"],
|
|
40
|
-
resources: [props.buildsBucket.arnForObjects("*")],
|
|
41
|
-
}),
|
|
42
|
-
new iam.PolicyStatement({
|
|
43
|
-
actions: ["s3:PutObject", "s3:DeleteObject"],
|
|
44
|
-
resources: [props.webBucket.arnForObjects("web/*")],
|
|
45
|
-
}),
|
|
46
|
-
new iam.PolicyStatement({
|
|
47
|
-
actions: ["s3:GetObject", "s3:PutObject"],
|
|
48
|
-
resources: [props.webBucket.arnForObjects("deployments.log")],
|
|
49
|
-
}),
|
|
50
|
-
new iam.PolicyStatement({
|
|
51
|
-
actions: ["s3:List*"],
|
|
52
|
-
resources: [props.webBucket.bucketArn],
|
|
53
|
-
}),
|
|
54
|
-
new iam.PolicyStatement({
|
|
55
|
-
actions: ["cloudfront:CreateInvalidation"],
|
|
56
|
-
// Cannot be restricted
|
|
57
|
-
resources: ["*"],
|
|
58
|
-
}),
|
|
59
|
-
],
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
exports.WebappDeploy = WebappDeploy;
|
|
64
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsd0NBQXVDO0FBQ3ZDLDhDQUE2QztBQUU3QyxxQ0FBb0M7QUFDcEMsNkJBQTRCO0FBMEM1Qjs7O0dBR0c7QUFDSCxNQUFhLFlBQWEsU0FBUSxHQUFHLENBQUMsU0FBUztJQUc3QyxZQUFZLEtBQW9CLEVBQUUsRUFBVSxFQUFFLEtBQXdCOztRQUNwRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBRWhCLE1BQU0sV0FBVyxHQUEyQjtZQUMxQyxxQkFBcUIsRUFBRSxRQUFRLEtBQUssQ0FBQyxTQUFTLENBQUMsVUFBVSxrQkFBa0I7WUFDM0UsY0FBYyxFQUFFLE9BQUMsS0FBSyxDQUFDLHlCQUF5QixtQ0FBSSxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDdEUsU0FBUyxFQUFFO2lCQUNYLFFBQVEsRUFBRTtZQUNiLGlCQUFpQixFQUFFLFFBQVEsS0FBSyxDQUFDLFNBQVMsQ0FBQyxVQUFVLE1BQU07U0FDNUQsQ0FBQTtRQUVELElBQUksS0FBSyxDQUFDLGNBQWMsSUFBSSxJQUFJLEVBQUU7WUFDaEMsV0FBVyxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxjQUFjLENBQUE7U0FDdEQ7UUFFRCxJQUFJLEtBQUssQ0FBQyxjQUFjLElBQUksSUFBSSxFQUFFO1lBQ2hDLFdBQVcsQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDLGNBQWMsQ0FBQTtTQUNuRDtRQUVELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDcEQsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQzVELFdBQVc7WUFDWCxZQUFZLFFBQUUsS0FBSyxDQUFDLFlBQVksbUNBQUksR0FBRyxDQUFDLFlBQVksQ0FBQyxrQkFBa0I7WUFDdkUsT0FBTyxFQUFFLDRCQUE0QjtZQUNyQyw0QkFBNEIsRUFBRSxDQUFDO1lBQy9CLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVU7WUFDbEMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNoQyxhQUFhLEVBQUU7Z0JBQ2IsSUFBSSxHQUFHLENBQUMsZUFBZSxDQUFDO29CQUN0QixPQUFPLEVBQUUsQ0FBQyxlQUFlLEVBQUUsY0FBYyxDQUFDO29CQUMxQyxTQUFTLEVBQUUsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztpQkFDbkQsQ0FBQztnQkFDRixJQUFJLEdBQUcsQ0FBQyxlQUFlLENBQUM7b0JBQ3RCLE9BQU8sRUFBRSxDQUFDLGNBQWMsRUFBRSxpQkFBaUIsQ0FBQztvQkFDNUMsU0FBUyxFQUFFLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7aUJBQ3BELENBQUM7Z0JBQ0YsSUFBSSxHQUFHLENBQUMsZUFBZSxDQUFDO29CQUN0QixPQUFPLEVBQUUsQ0FBQyxjQUFjLEVBQUUsY0FBYyxDQUFDO29CQUN6QyxTQUFTLEVBQUUsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO2lCQUM5RCxDQUFDO2dCQUNGLElBQUksR0FBRyxDQUFDLGVBQWUsQ0FBQztvQkFDdEIsT0FBTyxFQUFFLENBQUMsVUFBVSxDQUFDO29CQUNyQixTQUFTLEVBQUUsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQztpQkFDdkMsQ0FBQztnQkFDRixJQUFJLEdBQUcsQ0FBQyxlQUFlLENBQUM7b0JBQ3RCLE9BQU8sRUFBRSxDQUFDLCtCQUErQixDQUFDO29CQUMxQyx1QkFBdUI7b0JBQ3ZCLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxDQUFBO0lBQ0osQ0FBQztDQUNGO0FBdkRELG9DQXVEQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGlhbSBmcm9tIFwiQGF3cy1jZGsvYXdzLWlhbVwiXG5pbXBvcnQgKiBhcyBsYW1iZGEgZnJvbSBcIkBhd3MtY2RrL2F3cy1sYW1iZGFcIlxuaW1wb3J0ICogYXMgczMgZnJvbSBcIkBhd3MtY2RrL2F3cy1zM1wiXG5pbXBvcnQgKiBhcyBjZGsgZnJvbSBcIkBhd3MtY2RrL2NvcmVcIlxuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiXG5cbmV4cG9ydCBpbnRlcmZhY2UgV2ViYXBwRGVwbG95UHJvcHMge1xuICAvKipcbiAgICogUzMgYnVja2V0IHdoZXJlIHRoZSBhcnRpZmFjdHMgdG8gYmUgZGVwbG95ZWQgYXJlIHN0b3JlZC5cbiAgICovXG4gIGJ1aWxkc0J1Y2tldDogczMuSUJ1Y2tldFxuICAvKipcbiAgICogQ2xvdWRGcm9udCBEaXN0cmlidXRpb24gSUQgdG8gYmUgaW52YWxpZGF0ZWQgYWZ0ZXIgZGVwbG95LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vbmVcbiAgICovXG4gIGRpc3RyaWJ1dGlvbklkPzogc3RyaW5nXG4gIC8qKlxuICAgKiBSZWdleCBmb3IgcGF0dGVybnMgb2YgZmlsZXMgdG8gYmUgZGlzY2FyZGVkIGR1cmluZyBkZXBsb3ltZW50LlxuICAgKlxuICAgKiBFeGFtcGxlOiBgXFwubWFwJGAgd2lsbCBleGNsdWRlIGBqcy9teWFwcC0xYjIyYzI0OGYuanMubWFwYC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICBleGNsdWRlUGF0dGVybj86IHN0cmluZ1xuICAvKipcbiAgICogVGhlIHRpbWUgd2hlbiBhIGRlcGxveW1lbnQgaXMgY29uc2lkZXJlZCBvbGQgYW5kIHdpbGwgYmUgZGVsZXRlZFxuICAgKiB1bmxlc3MgaXQgaXMgdGhlIG5ld2VzdCBvbGQgZGVwbG95bWVudC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSA1IGRheXNcbiAgICovXG4gIHBydW5lRGVwbG95bWVudHNPbGRlclRoYW4/OiBjZGsuRHVyYXRpb25cbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIGxhbWJkYSBmdW5jdGlvbiB0byBiZSBjcmVhdGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBjZGsuUGh5c2ljYWxOYW1lLkdFTkVSQVRFX0lGX05FRURFRFxuICAgKi9cbiAgZnVuY3Rpb25OYW1lPzogc3RyaW5nXG4gIC8qKlxuICAgKiBOYW1lIG9mIFMzIGJ1Y2tldCB3aGVyZSB0aGUgY29udGVudHMgb2YgdGhlIGFydGlmYWN0cyB3aWxsIGJlIGRlcGxveWVkLlxuICAgKiBUaGUgZmlsZXMgd2lsbCBiZSBkZXBsb3llZCB1bmRlciB0aGUga2V5IFwid2ViXCIsIHdoaWNoIGlzIHRoZW4gZXhwZWN0ZWRcbiAgICogdG8gYmUgdGhlIG9yaWdpbiBmb3IgdGhlIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uXG4gICAqL1xuICB3ZWJCdWNrZXQ6IHMzLklCdWNrZXRcbn1cblxuLyoqXG4gKiBSZXNvdXJjZSB0byBkZXBsb3kgYSB3ZWJhcHAgZnJvbSBhIGJ1aWxkIGFydGlmYWN0IGludG8gYW4gZXhpc3RpbmdcbiAqIFMzIEJ1Y2tldCBhbmQgQ2xvdWRGcm9udCBEaXN0cmlidXRpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBXZWJhcHBEZXBsb3kgZXh0ZW5kcyBjZGsuQ29uc3RydWN0IHtcbiAgcmVhZG9ubHkgZGVwbG95Rm46IGxhbWJkYS5GdW5jdGlvblxuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogV2ViYXBwRGVwbG95UHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpXG5cbiAgICBjb25zdCBlbnZpcm9ubWVudDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgIERFUExPWV9MT0dfQlVDS0VUX1VSTDogYHMzOi8vJHtwcm9wcy53ZWJCdWNrZXQuYnVja2V0TmFtZX0vZGVwbG95bWVudHMubG9nYCxcbiAgICAgIEVYUElSRV9TRUNPTkRTOiAocHJvcHMucHJ1bmVEZXBsb3ltZW50c09sZGVyVGhhbiA/PyBjZGsuRHVyYXRpb24uZGF5cyg1KSlcbiAgICAgICAgLnRvU2Vjb25kcygpXG4gICAgICAgIC50b1N0cmluZygpLFxuICAgICAgVEFSR0VUX0JVQ0tFVF9VUkw6IGBzMzovLyR7cHJvcHMud2ViQnVja2V0LmJ1Y2tldE5hbWV9L3dlYmAsXG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmRpc3RyaWJ1dGlvbklkICE9IG51bGwpIHtcbiAgICAgIGVudmlyb25tZW50LkNGX0RJU1RSSUJVVElPTl9JRCA9IHByb3BzLmRpc3RyaWJ1dGlvbklkXG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmV4Y2x1ZGVQYXR0ZXJuICE9IG51bGwpIHtcbiAgICAgIGVudmlyb25tZW50LkVYQ0xVREVfUEFUVEVSTiA9IHByb3BzLmV4Y2x1ZGVQYXR0ZXJuXG4gICAgfVxuXG4gICAgdGhpcy5kZXBsb3lGbiA9IG5ldyBsYW1iZGEuRnVuY3Rpb24odGhpcywgXCJSZXNvdXJjZVwiLCB7XG4gICAgICBjb2RlOiBsYW1iZGEuQ29kZS5mcm9tQXNzZXQocGF0aC5qb2luKF9fZGlybmFtZSwgXCIuLi9kaXN0XCIpKSxcbiAgICAgIGVudmlyb25tZW50LFxuICAgICAgZnVuY3Rpb25OYW1lOiBwcm9wcy5mdW5jdGlvbk5hbWUgPz8gY2RrLlBoeXNpY2FsTmFtZS5HRU5FUkFURV9JRl9ORUVERUQsXG4gICAgICBoYW5kbGVyOiBcIndlYmFwcF9kZXBsb3kubWFpbi5oYW5kbGVyXCIsXG4gICAgICByZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zOiAxLFxuICAgICAgcnVudGltZTogbGFtYmRhLlJ1bnRpbWUuUFlUSE9OXzNfNyxcbiAgICAgIHRpbWVvdXQ6IGNkay5EdXJhdGlvbi5taW51dGVzKDIpLFxuICAgICAgaW5pdGlhbFBvbGljeTogW1xuICAgICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgYWN0aW9uczogW1wiczM6SGVhZE9iamVjdFwiLCBcInMzOkdldE9iamVjdFwiXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFtwcm9wcy5idWlsZHNCdWNrZXQuYXJuRm9yT2JqZWN0cyhcIipcIildLFxuICAgICAgICB9KSxcbiAgICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGFjdGlvbnM6IFtcInMzOlB1dE9iamVjdFwiLCBcInMzOkRlbGV0ZU9iamVjdFwiXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFtwcm9wcy53ZWJCdWNrZXQuYXJuRm9yT2JqZWN0cyhcIndlYi8qXCIpXSxcbiAgICAgICAgfSksXG4gICAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbXCJzMzpHZXRPYmplY3RcIiwgXCJzMzpQdXRPYmplY3RcIl0sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbcHJvcHMud2ViQnVja2V0LmFybkZvck9iamVjdHMoXCJkZXBsb3ltZW50cy5sb2dcIildLFxuICAgICAgICB9KSxcbiAgICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGFjdGlvbnM6IFtcInMzOkxpc3QqXCJdLFxuICAgICAgICAgIHJlc291cmNlczogW3Byb3BzLndlYkJ1Y2tldC5idWNrZXRBcm5dLFxuICAgICAgICB9KSxcbiAgICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGFjdGlvbnM6IFtcImNsb3VkZnJvbnQ6Q3JlYXRlSW52YWxpZGF0aW9uXCJdLFxuICAgICAgICAgIC8vIENhbm5vdCBiZSByZXN0cmljdGVkXG4gICAgICAgICAgcmVzb3VyY2VzOiBbXCIqXCJdLFxuICAgICAgICB9KSxcbiAgICAgIF0sXG4gICAgfSlcbiAgfVxufVxuIl19
|
|
3
|
+
exports.WebappDeploy = exports.Source = void 0;
|
|
4
|
+
var source_1 = require("./source");
|
|
5
|
+
Object.defineProperty(exports, "Source", { enumerable: true, get: function () { return source_1.Source; } });
|
|
6
|
+
var webapp_deploy_1 = require("./webapp-deploy");
|
|
7
|
+
Object.defineProperty(exports, "WebappDeploy", { enumerable: true, get: function () { return webapp_deploy_1.WebappDeploy; } });
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQXdEO0FBQXRDLGdHQUFBLE1BQU0sT0FBQTtBQUN4QixpREFBaUU7QUFBeEQsNkdBQUEsWUFBWSxPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHsgSVNvdXJjZSwgU291cmNlLCBTb3VyY2VDb25maWcgfSBmcm9tIFwiLi9zb3VyY2VcIlxuZXhwb3J0IHsgV2ViYXBwRGVwbG95LCBXZWJhcHBEZXBsb3lQcm9wcyB9IGZyb20gXCIuL3dlYmFwcC1kZXBsb3lcIlxuIl19
|
package/lib/source.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as iam from "@aws-cdk/aws-iam";
|
|
2
|
+
import * as s3 from "@aws-cdk/aws-s3";
|
|
3
|
+
import * as s3Assets from "@aws-cdk/aws-s3-assets";
|
|
4
|
+
import * as cdk from "@aws-cdk/core";
|
|
5
|
+
export interface SourceConfig {
|
|
6
|
+
/**
|
|
7
|
+
* The source bucket to deploy from.
|
|
8
|
+
*/
|
|
9
|
+
readonly bucket: s3.IBucket;
|
|
10
|
+
/**
|
|
11
|
+
* An S3 object key in the source bucket that points to a zip file.
|
|
12
|
+
*/
|
|
13
|
+
readonly zipObjectKey: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Bind context for ISources
|
|
17
|
+
*/
|
|
18
|
+
export interface SourceContext {
|
|
19
|
+
/**
|
|
20
|
+
* The role for the handler
|
|
21
|
+
*
|
|
22
|
+
* @default - no policy is modified
|
|
23
|
+
*/
|
|
24
|
+
readonly handlerRole?: iam.IRole;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Represents a source for bucket deployments.
|
|
28
|
+
*/
|
|
29
|
+
export interface ISource {
|
|
30
|
+
/**
|
|
31
|
+
* Binds the source to a bucket deployment.
|
|
32
|
+
*/
|
|
33
|
+
bind(scope: cdk.Construct, context?: SourceContext): SourceConfig;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Specifies bucket deployment source.
|
|
37
|
+
*
|
|
38
|
+
* Usage:
|
|
39
|
+
*
|
|
40
|
+
* Source.bucket(bucket, key)
|
|
41
|
+
* Source.asset('/local/path/to/directory')
|
|
42
|
+
* Source.asset('/local/path/to/a/file.zip')
|
|
43
|
+
*
|
|
44
|
+
*/
|
|
45
|
+
export declare class Source {
|
|
46
|
+
/**
|
|
47
|
+
* Uses a .zip file stored in an S3 bucket as the source for the destination bucket contents.
|
|
48
|
+
* @param bucket The S3 Bucket
|
|
49
|
+
* @param zipObjectKey The S3 object key of the zip file with contents
|
|
50
|
+
*/
|
|
51
|
+
static bucket(bucket: s3.IBucket, zipObjectKey: string): ISource;
|
|
52
|
+
/**
|
|
53
|
+
* Uses a local asset as the deployment source.
|
|
54
|
+
* @param path The path to a local .zip file or a directory
|
|
55
|
+
*/
|
|
56
|
+
static asset(path: string, options?: s3Assets.AssetOptions): ISource;
|
|
57
|
+
private constructor();
|
|
58
|
+
}
|
package/lib/source.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Source = void 0;
|
|
4
|
+
const s3Assets = require("@aws-cdk/aws-s3-assets");
|
|
5
|
+
/**
|
|
6
|
+
* Specifies bucket deployment source.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
*
|
|
10
|
+
* Source.bucket(bucket, key)
|
|
11
|
+
* Source.asset('/local/path/to/directory')
|
|
12
|
+
* Source.asset('/local/path/to/a/file.zip')
|
|
13
|
+
*
|
|
14
|
+
*/
|
|
15
|
+
class Source {
|
|
16
|
+
/**
|
|
17
|
+
* Uses a .zip file stored in an S3 bucket as the source for the destination bucket contents.
|
|
18
|
+
* @param bucket The S3 Bucket
|
|
19
|
+
* @param zipObjectKey The S3 object key of the zip file with contents
|
|
20
|
+
*/
|
|
21
|
+
static bucket(bucket, zipObjectKey) {
|
|
22
|
+
return {
|
|
23
|
+
bind: (_, context) => {
|
|
24
|
+
if (!context) {
|
|
25
|
+
throw new Error("To use a Source.bucket(), context must be provided");
|
|
26
|
+
}
|
|
27
|
+
if (context.handlerRole) {
|
|
28
|
+
bucket.grantRead(context.handlerRole);
|
|
29
|
+
}
|
|
30
|
+
return { bucket, zipObjectKey };
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Uses a local asset as the deployment source.
|
|
36
|
+
* @param path The path to a local .zip file or a directory
|
|
37
|
+
*/
|
|
38
|
+
static asset(path, options) {
|
|
39
|
+
return {
|
|
40
|
+
bind(scope, context) {
|
|
41
|
+
if (!context) {
|
|
42
|
+
throw new Error("To use a Source.asset(), context must be provided");
|
|
43
|
+
}
|
|
44
|
+
let id = 1;
|
|
45
|
+
while (scope.node.tryFindChild(`Asset${id}`)) {
|
|
46
|
+
id++;
|
|
47
|
+
}
|
|
48
|
+
const asset = new s3Assets.Asset(scope, `Asset${id}`, {
|
|
49
|
+
path,
|
|
50
|
+
...options,
|
|
51
|
+
});
|
|
52
|
+
if (!asset.isZipArchive) {
|
|
53
|
+
throw new Error("Asset path must be either a .zip file or a directory");
|
|
54
|
+
}
|
|
55
|
+
if (context.handlerRole) {
|
|
56
|
+
asset.grantRead(context.handlerRole);
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
bucket: asset.bucket,
|
|
60
|
+
zipObjectKey: asset.s3ObjectKey,
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
66
|
+
constructor() { }
|
|
67
|
+
}
|
|
68
|
+
exports.Source = Source;
|
|
69
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic291cmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3NvdXJjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxtREFBa0Q7QUF1Q2xEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQWEsTUFBTTtJQUNqQjs7OztPQUlHO0lBQ0ksTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFrQixFQUFFLFlBQW9CO1FBQzNELE9BQU87WUFDTCxJQUFJLEVBQUUsQ0FBQyxDQUFnQixFQUFFLE9BQXVCLEVBQUUsRUFBRTtnQkFDbEQsSUFBSSxDQUFDLE9BQU8sRUFBRTtvQkFDWixNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUE7aUJBQ3RFO2dCQUVELElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRTtvQkFDdkIsTUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUE7aUJBQ3RDO2dCQUVELE9BQU8sRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLENBQUE7WUFDakMsQ0FBQztTQUNGLENBQUE7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFZLEVBQUUsT0FBK0I7UUFDL0QsT0FBTztZQUNMLElBQUksQ0FBQyxLQUFvQixFQUFFLE9BQXVCO2dCQUNoRCxJQUFJLENBQUMsT0FBTyxFQUFFO29CQUNaLE1BQU0sSUFBSSxLQUFLLENBQUMsbURBQW1ELENBQUMsQ0FBQTtpQkFDckU7Z0JBRUQsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFBO2dCQUNWLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxFQUFFO29CQUM1QyxFQUFFLEVBQUUsQ0FBQTtpQkFDTDtnQkFDRCxNQUFNLEtBQUssR0FBRyxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUU7b0JBQ3BELElBQUk7b0JBQ0osR0FBRyxPQUFPO2lCQUNYLENBQUMsQ0FBQTtnQkFDRixJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRTtvQkFDdkIsTUFBTSxJQUFJLEtBQUssQ0FDYixzREFBc0QsQ0FDdkQsQ0FBQTtpQkFDRjtnQkFFRCxJQUFJLE9BQU8sQ0FBQyxXQUFXLEVBQUU7b0JBQ3ZCLEtBQUssQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFBO2lCQUNyQztnQkFFRCxPQUFPO29CQUNMLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtvQkFDcEIsWUFBWSxFQUFFLEtBQUssQ0FBQyxXQUFXO2lCQUNoQyxDQUFBO1lBQ0gsQ0FBQztTQUNGLENBQUE7SUFDSCxDQUFDO0lBRUQsZ0VBQWdFO0lBQ2hFLGdCQUF1QixDQUFDO0NBQ3pCO0FBN0RELHdCQTZEQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGlhbSBmcm9tIFwiQGF3cy1jZGsvYXdzLWlhbVwiXG5pbXBvcnQgKiBhcyBzMyBmcm9tIFwiQGF3cy1jZGsvYXdzLXMzXCJcbmltcG9ydCAqIGFzIHMzQXNzZXRzIGZyb20gXCJAYXdzLWNkay9hd3MtczMtYXNzZXRzXCJcbmltcG9ydCAqIGFzIGNkayBmcm9tIFwiQGF3cy1jZGsvY29yZVwiXG5cbi8vIFRoaXMgaXMgbW9zdGx5IGJhc2VkIG9uIGF3cy1zMy1kZXBsb3ltZW50IGZyb20gYXdzLWNkay5cblxuZXhwb3J0IGludGVyZmFjZSBTb3VyY2VDb25maWcge1xuICAvKipcbiAgICogVGhlIHNvdXJjZSBidWNrZXQgdG8gZGVwbG95IGZyb20uXG4gICAqL1xuICByZWFkb25seSBidWNrZXQ6IHMzLklCdWNrZXRcblxuICAvKipcbiAgICogQW4gUzMgb2JqZWN0IGtleSBpbiB0aGUgc291cmNlIGJ1Y2tldCB0aGF0IHBvaW50cyB0byBhIHppcCBmaWxlLlxuICAgKi9cbiAgcmVhZG9ubHkgemlwT2JqZWN0S2V5OiBzdHJpbmdcbn1cblxuLyoqXG4gKiBCaW5kIGNvbnRleHQgZm9yIElTb3VyY2VzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU291cmNlQ29udGV4dCB7XG4gIC8qKlxuICAgKiBUaGUgcm9sZSBmb3IgdGhlIGhhbmRsZXJcbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBwb2xpY3kgaXMgbW9kaWZpZWRcbiAgICovXG4gIHJlYWRvbmx5IGhhbmRsZXJSb2xlPzogaWFtLklSb2xlXG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHNvdXJjZSBmb3IgYnVja2V0IGRlcGxveW1lbnRzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIElTb3VyY2Uge1xuICAvKipcbiAgICogQmluZHMgdGhlIHNvdXJjZSB0byBhIGJ1Y2tldCBkZXBsb3ltZW50LlxuICAgKi9cbiAgYmluZChzY29wZTogY2RrLkNvbnN0cnVjdCwgY29udGV4dD86IFNvdXJjZUNvbnRleHQpOiBTb3VyY2VDb25maWdcbn1cblxuLyoqXG4gKiBTcGVjaWZpZXMgYnVja2V0IGRlcGxveW1lbnQgc291cmNlLlxuICpcbiAqIFVzYWdlOlxuICpcbiAqICAgICBTb3VyY2UuYnVja2V0KGJ1Y2tldCwga2V5KVxuICogICAgIFNvdXJjZS5hc3NldCgnL2xvY2FsL3BhdGgvdG8vZGlyZWN0b3J5JylcbiAqICAgICBTb3VyY2UuYXNzZXQoJy9sb2NhbC9wYXRoL3RvL2EvZmlsZS56aXAnKVxuICpcbiAqL1xuZXhwb3J0IGNsYXNzIFNvdXJjZSB7XG4gIC8qKlxuICAgKiBVc2VzIGEgLnppcCBmaWxlIHN0b3JlZCBpbiBhbiBTMyBidWNrZXQgYXMgdGhlIHNvdXJjZSBmb3IgdGhlIGRlc3RpbmF0aW9uIGJ1Y2tldCBjb250ZW50cy5cbiAgICogQHBhcmFtIGJ1Y2tldCBUaGUgUzMgQnVja2V0XG4gICAqIEBwYXJhbSB6aXBPYmplY3RLZXkgVGhlIFMzIG9iamVjdCBrZXkgb2YgdGhlIHppcCBmaWxlIHdpdGggY29udGVudHNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYnVja2V0KGJ1Y2tldDogczMuSUJ1Y2tldCwgemlwT2JqZWN0S2V5OiBzdHJpbmcpOiBJU291cmNlIHtcbiAgICByZXR1cm4ge1xuICAgICAgYmluZDogKF86IGNkay5Db25zdHJ1Y3QsIGNvbnRleHQ/OiBTb3VyY2VDb250ZXh0KSA9PiB7XG4gICAgICAgIGlmICghY29udGV4dCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRvIHVzZSBhIFNvdXJjZS5idWNrZXQoKSwgY29udGV4dCBtdXN0IGJlIHByb3ZpZGVkXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29udGV4dC5oYW5kbGVyUm9sZSkge1xuICAgICAgICAgIGJ1Y2tldC5ncmFudFJlYWQoY29udGV4dC5oYW5kbGVyUm9sZSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IGJ1Y2tldCwgemlwT2JqZWN0S2V5IH1cbiAgICAgIH0sXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVzZXMgYSBsb2NhbCBhc3NldCBhcyB0aGUgZGVwbG95bWVudCBzb3VyY2UuXG4gICAqIEBwYXJhbSBwYXRoIFRoZSBwYXRoIHRvIGEgbG9jYWwgLnppcCBmaWxlIG9yIGEgZGlyZWN0b3J5XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFzc2V0KHBhdGg6IHN0cmluZywgb3B0aW9ucz86IHMzQXNzZXRzLkFzc2V0T3B0aW9ucyk6IElTb3VyY2Uge1xuICAgIHJldHVybiB7XG4gICAgICBiaW5kKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBjb250ZXh0PzogU291cmNlQ29udGV4dCk6IFNvdXJjZUNvbmZpZyB7XG4gICAgICAgIGlmICghY29udGV4dCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRvIHVzZSBhIFNvdXJjZS5hc3NldCgpLCBjb250ZXh0IG11c3QgYmUgcHJvdmlkZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBpZCA9IDFcbiAgICAgICAgd2hpbGUgKHNjb3BlLm5vZGUudHJ5RmluZENoaWxkKGBBc3NldCR7aWR9YCkpIHtcbiAgICAgICAgICBpZCsrXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXNzZXQgPSBuZXcgczNBc3NldHMuQXNzZXQoc2NvcGUsIGBBc3NldCR7aWR9YCwge1xuICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgfSlcbiAgICAgICAgaWYgKCFhc3NldC5pc1ppcEFyY2hpdmUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBcIkFzc2V0IHBhdGggbXVzdCBiZSBlaXRoZXIgYSAuemlwIGZpbGUgb3IgYSBkaXJlY3RvcnlcIixcbiAgICAgICAgICApXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29udGV4dC5oYW5kbGVyUm9sZSkge1xuICAgICAgICAgIGFzc2V0LmdyYW50UmVhZChjb250ZXh0LmhhbmRsZXJSb2xlKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBidWNrZXQ6IGFzc2V0LmJ1Y2tldCxcbiAgICAgICAgICB6aXBPYmplY3RLZXk6IGFzc2V0LnMzT2JqZWN0S2V5LFxuICAgICAgICB9XG4gICAgICB9LFxuICAgIH1cbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktZnVuY3Rpb25cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG59XG4iXX0=
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as cloudfront from "@aws-cdk/aws-cloudfront";
|
|
2
|
+
import * as lambda from "@aws-cdk/aws-lambda";
|
|
3
|
+
import * as s3 from "@aws-cdk/aws-s3";
|
|
4
|
+
import * as cdk from "@aws-cdk/core";
|
|
5
|
+
import { ISource } from "./source";
|
|
6
|
+
export interface WebappDeployProps {
|
|
7
|
+
/**
|
|
8
|
+
* Optional S3 bucket that can be used for deployment from outside CDK.
|
|
9
|
+
*
|
|
10
|
+
* If specified a policy is added so the deploy function can read from
|
|
11
|
+
* the bucket.
|
|
12
|
+
*
|
|
13
|
+
* @default - none
|
|
14
|
+
*/
|
|
15
|
+
buildsBucket?: s3.IBucket;
|
|
16
|
+
/**
|
|
17
|
+
* CloudFront Distribution to be invalidated after deploy.
|
|
18
|
+
*
|
|
19
|
+
* @default - none
|
|
20
|
+
*/
|
|
21
|
+
distribution?: cloudfront.IDistribution;
|
|
22
|
+
/**
|
|
23
|
+
* Regex for patterns of files to be discarded during deployment.
|
|
24
|
+
*
|
|
25
|
+
* Example: `\.map$` will exclude `js/myapp-1b22c248f.js.map`.
|
|
26
|
+
*
|
|
27
|
+
* @default - none
|
|
28
|
+
*/
|
|
29
|
+
excludePattern?: string;
|
|
30
|
+
/**
|
|
31
|
+
* The time when a deployment is considered old and will be deleted
|
|
32
|
+
* unless it is the newest old deployment.
|
|
33
|
+
*
|
|
34
|
+
* @default - 5 days
|
|
35
|
+
*/
|
|
36
|
+
pruneDeploymentsOlderThan?: cdk.Duration;
|
|
37
|
+
/**
|
|
38
|
+
* Name of the lambda function to be created.
|
|
39
|
+
*
|
|
40
|
+
* @default cdk.PhysicalName.GENERATE_IF_NEEDED
|
|
41
|
+
*/
|
|
42
|
+
functionName?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Name of S3 bucket where the contents of the artifacts will be deployed.
|
|
45
|
+
* The files will be deployed under the key "web", which is then expected
|
|
46
|
+
* to be the origin for the CloudFront distribution
|
|
47
|
+
*/
|
|
48
|
+
webBucket: s3.IBucket;
|
|
49
|
+
/**
|
|
50
|
+
* Specific artifact to be deployed to the bucket during CDK deployment.
|
|
51
|
+
*
|
|
52
|
+
* @default - none
|
|
53
|
+
*/
|
|
54
|
+
source?: ISource;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Resource to deploy a webapp from a build artifact into an existing
|
|
58
|
+
* S3 Bucket and CloudFront Distribution.
|
|
59
|
+
*/
|
|
60
|
+
export declare class WebappDeploy extends cdk.Construct {
|
|
61
|
+
readonly deployFn: lambda.Function;
|
|
62
|
+
constructor(scope: cdk.Construct, id: string, props: WebappDeployProps);
|
|
63
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebappDeploy = void 0;
|
|
4
|
+
const iam = require("@aws-cdk/aws-iam");
|
|
5
|
+
const lambda = require("@aws-cdk/aws-lambda");
|
|
6
|
+
const cdk = require("@aws-cdk/core");
|
|
7
|
+
const custom_resources_1 = require("@aws-cdk/custom-resources");
|
|
8
|
+
const path = require("path");
|
|
9
|
+
/**
|
|
10
|
+
* Resource to deploy a webapp from a build artifact into an existing
|
|
11
|
+
* S3 Bucket and CloudFront Distribution.
|
|
12
|
+
*/
|
|
13
|
+
class WebappDeploy extends cdk.Construct {
|
|
14
|
+
constructor(scope, id, props) {
|
|
15
|
+
var _a, _b;
|
|
16
|
+
super(scope, id);
|
|
17
|
+
const environment = {
|
|
18
|
+
DEPLOY_LOG_BUCKET_URL: `s3://${props.webBucket.bucketName}/deployments.log`,
|
|
19
|
+
EXPIRE_SECONDS: ((_a = props.pruneDeploymentsOlderThan) !== null && _a !== void 0 ? _a : cdk.Duration.days(5))
|
|
20
|
+
.toSeconds()
|
|
21
|
+
.toString(),
|
|
22
|
+
TARGET_BUCKET_URL: `s3://${props.webBucket.bucketName}/web`,
|
|
23
|
+
};
|
|
24
|
+
if (props.distribution != null) {
|
|
25
|
+
environment.CF_DISTRIBUTION_ID = props.distribution.distributionId;
|
|
26
|
+
}
|
|
27
|
+
if (props.excludePattern != null) {
|
|
28
|
+
environment.EXCLUDE_PATTERN = props.excludePattern;
|
|
29
|
+
}
|
|
30
|
+
this.deployFn = new lambda.Function(this, "Resource", {
|
|
31
|
+
code: lambda.Code.fromAsset(path.join(__dirname, "../dist")),
|
|
32
|
+
environment,
|
|
33
|
+
functionName: (_b = props.functionName) !== null && _b !== void 0 ? _b : cdk.PhysicalName.GENERATE_IF_NEEDED,
|
|
34
|
+
handler: "webapp_deploy.main.handler",
|
|
35
|
+
reservedConcurrentExecutions: 1,
|
|
36
|
+
runtime: lambda.Runtime.PYTHON_3_8,
|
|
37
|
+
timeout: cdk.Duration.minutes(2),
|
|
38
|
+
initialPolicy: [
|
|
39
|
+
new iam.PolicyStatement({
|
|
40
|
+
actions: ["cloudfront:CreateInvalidation"],
|
|
41
|
+
// Cannot be restricted
|
|
42
|
+
resources: ["*"],
|
|
43
|
+
}),
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
props.webBucket.grantReadWrite(this.deployFn);
|
|
47
|
+
if (props.buildsBucket) {
|
|
48
|
+
props.buildsBucket.grantRead(this.deployFn);
|
|
49
|
+
}
|
|
50
|
+
if (props.source) {
|
|
51
|
+
const source = props.source.bind(this, {
|
|
52
|
+
handlerRole: this.deployFn.role,
|
|
53
|
+
});
|
|
54
|
+
new custom_resources_1.AwsCustomResource(this, "CustomResource", {
|
|
55
|
+
onUpdate: {
|
|
56
|
+
service: "Lambda",
|
|
57
|
+
action: "invoke",
|
|
58
|
+
physicalResourceId: custom_resources_1.PhysicalResourceId.of("webapp-deploy"),
|
|
59
|
+
parameters: {
|
|
60
|
+
FunctionName: this.deployFn.functionName,
|
|
61
|
+
Payload: cdk.Stack.of(scope).toJsonString({
|
|
62
|
+
artifactS3Url: `s3://${source.bucket.bucketName}/${source.zipObjectKey}`,
|
|
63
|
+
}),
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
policy: custom_resources_1.AwsCustomResourcePolicy.fromStatements([
|
|
67
|
+
new iam.PolicyStatement({
|
|
68
|
+
actions: ["lambda:InvokeFunction"],
|
|
69
|
+
resources: [this.deployFn.functionArn],
|
|
70
|
+
}),
|
|
71
|
+
]),
|
|
72
|
+
installLatestAwsSdk: false,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.WebappDeploy = WebappDeploy;
|
|
78
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViYXBwLWRlcGxveS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy93ZWJhcHAtZGVwbG95LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHdDQUF1QztBQUN2Qyw4Q0FBNkM7QUFFN0MscUNBQW9DO0FBQ3BDLGdFQUlrQztBQUNsQyw2QkFBNEI7QUFzRDVCOzs7R0FHRztBQUNILE1BQWEsWUFBYSxTQUFRLEdBQUcsQ0FBQyxTQUFTO0lBRzdDLFlBQVksS0FBb0IsRUFBRSxFQUFVLEVBQUUsS0FBd0I7O1FBQ3BFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFFaEIsTUFBTSxXQUFXLEdBQTJCO1lBQzFDLHFCQUFxQixFQUFFLFFBQVEsS0FBSyxDQUFDLFNBQVMsQ0FBQyxVQUFVLGtCQUFrQjtZQUMzRSxjQUFjLEVBQUUsQ0FBQyxNQUFBLEtBQUssQ0FBQyx5QkFBeUIsbUNBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQ3RFLFNBQVMsRUFBRTtpQkFDWCxRQUFRLEVBQUU7WUFDYixpQkFBaUIsRUFBRSxRQUFRLEtBQUssQ0FBQyxTQUFTLENBQUMsVUFBVSxNQUFNO1NBQzVELENBQUE7UUFFRCxJQUFJLEtBQUssQ0FBQyxZQUFZLElBQUksSUFBSSxFQUFFO1lBQzlCLFdBQVcsQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQTtTQUNuRTtRQUVELElBQUksS0FBSyxDQUFDLGNBQWMsSUFBSSxJQUFJLEVBQUU7WUFDaEMsV0FBVyxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFBO1NBQ25EO1FBRUQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRTtZQUNwRCxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDNUQsV0FBVztZQUNYLFlBQVksRUFBRSxNQUFBLEtBQUssQ0FBQyxZQUFZLG1DQUFJLEdBQUcsQ0FBQyxZQUFZLENBQUMsa0JBQWtCO1lBQ3ZFLE9BQU8sRUFBRSw0QkFBNEI7WUFDckMsNEJBQTRCLEVBQUUsQ0FBQztZQUMvQixPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVO1lBQ2xDLE9BQU8sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDaEMsYUFBYSxFQUFFO2dCQUNiLElBQUksR0FBRyxDQUFDLGVBQWUsQ0FBQztvQkFDdEIsT0FBTyxFQUFFLENBQUMsK0JBQStCLENBQUM7b0JBQzFDLHVCQUF1QjtvQkFDdkIsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO2lCQUNqQixDQUFDO2FBQ0g7U0FDRixDQUFDLENBQUE7UUFFRixLQUFLLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7UUFFN0MsSUFBSSxLQUFLLENBQUMsWUFBWSxFQUFFO1lBQ3RCLEtBQUssQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQTtTQUM1QztRQUVELElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtZQUNoQixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7Z0JBQ3JDLFdBQVcsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUs7YUFDakMsQ0FBQyxDQUFBO1lBRUYsSUFBSSxvQ0FBaUIsQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBQzVDLFFBQVEsRUFBRTtvQkFDUixPQUFPLEVBQUUsUUFBUTtvQkFDakIsTUFBTSxFQUFFLFFBQVE7b0JBQ2hCLGtCQUFrQixFQUFFLHFDQUFrQixDQUFDLEVBQUUsQ0FBQyxlQUFlLENBQUM7b0JBQzFELFVBQVUsRUFBRTt3QkFDVixZQUFZLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZO3dCQUN4QyxPQUFPLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsWUFBWSxDQUFDOzRCQUN4QyxhQUFhLEVBQUUsUUFBUSxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBSSxNQUFNLENBQUMsWUFBWSxFQUFFO3lCQUN6RSxDQUFDO3FCQUNIO2lCQUNGO2dCQUNELE1BQU0sRUFBRSwwQ0FBdUIsQ0FBQyxjQUFjLENBQUM7b0JBQzdDLElBQUksR0FBRyxDQUFDLGVBQWUsQ0FBQzt3QkFDdEIsT0FBTyxFQUFFLENBQUMsdUJBQXVCLENBQUM7d0JBQ2xDLFNBQVMsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDO3FCQUN2QyxDQUFDO2lCQUNILENBQUM7Z0JBQ0YsbUJBQW1CLEVBQUUsS0FBSzthQUMzQixDQUFDLENBQUE7U0FDSDtJQUNILENBQUM7Q0FDRjtBQXhFRCxvQ0F3RUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjbG91ZGZyb250IGZyb20gXCJAYXdzLWNkay9hd3MtY2xvdWRmcm9udFwiXG5pbXBvcnQgKiBhcyBpYW0gZnJvbSBcIkBhd3MtY2RrL2F3cy1pYW1cIlxuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gXCJAYXdzLWNkay9hd3MtbGFtYmRhXCJcbmltcG9ydCAqIGFzIHMzIGZyb20gXCJAYXdzLWNkay9hd3MtczNcIlxuaW1wb3J0ICogYXMgY2RrIGZyb20gXCJAYXdzLWNkay9jb3JlXCJcbmltcG9ydCB7XG4gIEF3c0N1c3RvbVJlc291cmNlLFxuICBBd3NDdXN0b21SZXNvdXJjZVBvbGljeSxcbiAgUGh5c2ljYWxSZXNvdXJjZUlkLFxufSBmcm9tIFwiQGF3cy1jZGsvY3VzdG9tLXJlc291cmNlc1wiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCJcbmltcG9ydCB7IElTb3VyY2UgfSBmcm9tIFwiLi9zb3VyY2VcIlxuXG5leHBvcnQgaW50ZXJmYWNlIFdlYmFwcERlcGxveVByb3BzIHtcbiAgLyoqXG4gICAqIE9wdGlvbmFsIFMzIGJ1Y2tldCB0aGF0IGNhbiBiZSB1c2VkIGZvciBkZXBsb3ltZW50IGZyb20gb3V0c2lkZSBDREsuXG4gICAqXG4gICAqIElmIHNwZWNpZmllZCBhIHBvbGljeSBpcyBhZGRlZCBzbyB0aGUgZGVwbG95IGZ1bmN0aW9uIGNhbiByZWFkIGZyb21cbiAgICogdGhlIGJ1Y2tldC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICBidWlsZHNCdWNrZXQ/OiBzMy5JQnVja2V0XG4gIC8qKlxuICAgKiBDbG91ZEZyb250IERpc3RyaWJ1dGlvbiB0byBiZSBpbnZhbGlkYXRlZCBhZnRlciBkZXBsb3kuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm9uZVxuICAgKi9cbiAgZGlzdHJpYnV0aW9uPzogY2xvdWRmcm9udC5JRGlzdHJpYnV0aW9uXG4gIC8qKlxuICAgKiBSZWdleCBmb3IgcGF0dGVybnMgb2YgZmlsZXMgdG8gYmUgZGlzY2FyZGVkIGR1cmluZyBkZXBsb3ltZW50LlxuICAgKlxuICAgKiBFeGFtcGxlOiBgXFwubWFwJGAgd2lsbCBleGNsdWRlIGBqcy9teWFwcC0xYjIyYzI0OGYuanMubWFwYC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICBleGNsdWRlUGF0dGVybj86IHN0cmluZ1xuICAvKipcbiAgICogVGhlIHRpbWUgd2hlbiBhIGRlcGxveW1lbnQgaXMgY29uc2lkZXJlZCBvbGQgYW5kIHdpbGwgYmUgZGVsZXRlZFxuICAgKiB1bmxlc3MgaXQgaXMgdGhlIG5ld2VzdCBvbGQgZGVwbG95bWVudC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSA1IGRheXNcbiAgICovXG4gIHBydW5lRGVwbG95bWVudHNPbGRlclRoYW4/OiBjZGsuRHVyYXRpb25cbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIGxhbWJkYSBmdW5jdGlvbiB0byBiZSBjcmVhdGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBjZGsuUGh5c2ljYWxOYW1lLkdFTkVSQVRFX0lGX05FRURFRFxuICAgKi9cbiAgZnVuY3Rpb25OYW1lPzogc3RyaW5nXG4gIC8qKlxuICAgKiBOYW1lIG9mIFMzIGJ1Y2tldCB3aGVyZSB0aGUgY29udGVudHMgb2YgdGhlIGFydGlmYWN0cyB3aWxsIGJlIGRlcGxveWVkLlxuICAgKiBUaGUgZmlsZXMgd2lsbCBiZSBkZXBsb3llZCB1bmRlciB0aGUga2V5IFwid2ViXCIsIHdoaWNoIGlzIHRoZW4gZXhwZWN0ZWRcbiAgICogdG8gYmUgdGhlIG9yaWdpbiBmb3IgdGhlIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uXG4gICAqL1xuICB3ZWJCdWNrZXQ6IHMzLklCdWNrZXRcbiAgLyoqXG4gICAqIFNwZWNpZmljIGFydGlmYWN0IHRvIGJlIGRlcGxveWVkIHRvIHRoZSBidWNrZXQgZHVyaW5nIENESyBkZXBsb3ltZW50LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vbmVcbiAgICovXG4gIHNvdXJjZT86IElTb3VyY2Vcbn1cblxuLyoqXG4gKiBSZXNvdXJjZSB0byBkZXBsb3kgYSB3ZWJhcHAgZnJvbSBhIGJ1aWxkIGFydGlmYWN0IGludG8gYW4gZXhpc3RpbmdcbiAqIFMzIEJ1Y2tldCBhbmQgQ2xvdWRGcm9udCBEaXN0cmlidXRpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBXZWJhcHBEZXBsb3kgZXh0ZW5kcyBjZGsuQ29uc3RydWN0IHtcbiAgcmVhZG9ubHkgZGVwbG95Rm46IGxhbWJkYS5GdW5jdGlvblxuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogV2ViYXBwRGVwbG95UHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpXG5cbiAgICBjb25zdCBlbnZpcm9ubWVudDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgIERFUExPWV9MT0dfQlVDS0VUX1VSTDogYHMzOi8vJHtwcm9wcy53ZWJCdWNrZXQuYnVja2V0TmFtZX0vZGVwbG95bWVudHMubG9nYCxcbiAgICAgIEVYUElSRV9TRUNPTkRTOiAocHJvcHMucHJ1bmVEZXBsb3ltZW50c09sZGVyVGhhbiA/PyBjZGsuRHVyYXRpb24uZGF5cyg1KSlcbiAgICAgICAgLnRvU2Vjb25kcygpXG4gICAgICAgIC50b1N0cmluZygpLFxuICAgICAgVEFSR0VUX0JVQ0tFVF9VUkw6IGBzMzovLyR7cHJvcHMud2ViQnVja2V0LmJ1Y2tldE5hbWV9L3dlYmAsXG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmRpc3RyaWJ1dGlvbiAhPSBudWxsKSB7XG4gICAgICBlbnZpcm9ubWVudC5DRl9ESVNUUklCVVRJT05fSUQgPSBwcm9wcy5kaXN0cmlidXRpb24uZGlzdHJpYnV0aW9uSWRcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuZXhjbHVkZVBhdHRlcm4gIT0gbnVsbCkge1xuICAgICAgZW52aXJvbm1lbnQuRVhDTFVERV9QQVRURVJOID0gcHJvcHMuZXhjbHVkZVBhdHRlcm5cbiAgICB9XG5cbiAgICB0aGlzLmRlcGxveUZuID0gbmV3IGxhbWJkYS5GdW5jdGlvbih0aGlzLCBcIlJlc291cmNlXCIsIHtcbiAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChwYXRoLmpvaW4oX19kaXJuYW1lLCBcIi4uL2Rpc3RcIikpLFxuICAgICAgZW52aXJvbm1lbnQsXG4gICAgICBmdW5jdGlvbk5hbWU6IHByb3BzLmZ1bmN0aW9uTmFtZSA/PyBjZGsuUGh5c2ljYWxOYW1lLkdFTkVSQVRFX0lGX05FRURFRCxcbiAgICAgIGhhbmRsZXI6IFwid2ViYXBwX2RlcGxveS5tYWluLmhhbmRsZXJcIixcbiAgICAgIHJlc2VydmVkQ29uY3VycmVudEV4ZWN1dGlvbnM6IDEsXG4gICAgICBydW50aW1lOiBsYW1iZGEuUnVudGltZS5QWVRIT05fM184LFxuICAgICAgdGltZW91dDogY2RrLkR1cmF0aW9uLm1pbnV0ZXMoMiksXG4gICAgICBpbml0aWFsUG9saWN5OiBbXG4gICAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbXCJjbG91ZGZyb250OkNyZWF0ZUludmFsaWRhdGlvblwiXSxcbiAgICAgICAgICAvLyBDYW5ub3QgYmUgcmVzdHJpY3RlZFxuICAgICAgICAgIHJlc291cmNlczogW1wiKlwiXSxcbiAgICAgICAgfSksXG4gICAgICBdLFxuICAgIH0pXG5cbiAgICBwcm9wcy53ZWJCdWNrZXQuZ3JhbnRSZWFkV3JpdGUodGhpcy5kZXBsb3lGbilcblxuICAgIGlmIChwcm9wcy5idWlsZHNCdWNrZXQpIHtcbiAgICAgIHByb3BzLmJ1aWxkc0J1Y2tldC5ncmFudFJlYWQodGhpcy5kZXBsb3lGbilcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuc291cmNlKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBwcm9wcy5zb3VyY2UuYmluZCh0aGlzLCB7XG4gICAgICAgIGhhbmRsZXJSb2xlOiB0aGlzLmRlcGxveUZuLnJvbGUhLFxuICAgICAgfSlcblxuICAgICAgbmV3IEF3c0N1c3RvbVJlc291cmNlKHRoaXMsIFwiQ3VzdG9tUmVzb3VyY2VcIiwge1xuICAgICAgICBvblVwZGF0ZToge1xuICAgICAgICAgIHNlcnZpY2U6IFwiTGFtYmRhXCIsXG4gICAgICAgICAgYWN0aW9uOiBcImludm9rZVwiLFxuICAgICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZDogUGh5c2ljYWxSZXNvdXJjZUlkLm9mKFwid2ViYXBwLWRlcGxveVwiKSxcbiAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICBGdW5jdGlvbk5hbWU6IHRoaXMuZGVwbG95Rm4uZnVuY3Rpb25OYW1lLFxuICAgICAgICAgICAgUGF5bG9hZDogY2RrLlN0YWNrLm9mKHNjb3BlKS50b0pzb25TdHJpbmcoe1xuICAgICAgICAgICAgICBhcnRpZmFjdFMzVXJsOiBgczM6Ly8ke3NvdXJjZS5idWNrZXQuYnVja2V0TmFtZX0vJHtzb3VyY2UuemlwT2JqZWN0S2V5fWAsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBwb2xpY3k6IEF3c0N1c3RvbVJlc291cmNlUG9saWN5LmZyb21TdGF0ZW1lbnRzKFtcbiAgICAgICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXCJsYW1iZGE6SW52b2tlRnVuY3Rpb25cIl0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFt0aGlzLmRlcGxveUZuLmZ1bmN0aW9uQXJuXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSksXG4gICAgICAgIGluc3RhbGxMYXRlc3RBd3NTZGs6IGZhbHNlLFxuICAgICAgfSlcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capraconsulting/webapp-deploy-lambda",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "CDK construct for deploying a webapp release to S3 and CloudFront",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"test": "jest",
|
|
13
13
|
"lint": "eslint .",
|
|
14
14
|
"lint:fix": "eslint --fix .",
|
|
15
|
-
"prepare": "npm run build",
|
|
15
|
+
"prepare": "npm run build && husky install",
|
|
16
16
|
"semantic-release": "semantic-release"
|
|
17
17
|
},
|
|
18
18
|
"keywords": [
|
|
@@ -33,40 +33,40 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@aws-cdk/assert": "1.
|
|
37
|
-
"@aws-cdk/aws-
|
|
38
|
-
"@aws-cdk/aws-
|
|
39
|
-
"@aws-cdk/aws-
|
|
40
|
-
"@aws-cdk/
|
|
41
|
-
"@
|
|
42
|
-
"@
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
47
|
-
"@
|
|
48
|
-
"eslint": "
|
|
49
|
-
"eslint
|
|
50
|
-
"eslint
|
|
51
|
-
"eslint-
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"hooks": {
|
|
63
|
-
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
|
|
64
|
-
}
|
|
36
|
+
"@aws-cdk/assert": "1.135.0",
|
|
37
|
+
"@aws-cdk/aws-cloudfront": "1.135.0",
|
|
38
|
+
"@aws-cdk/aws-iam": "1.135.0",
|
|
39
|
+
"@aws-cdk/aws-lambda": "1.135.0",
|
|
40
|
+
"@aws-cdk/aws-s3": "1.135.0",
|
|
41
|
+
"@aws-cdk/aws-s3-assets": "1.135.0",
|
|
42
|
+
"@aws-cdk/core": "1.135.0",
|
|
43
|
+
"@aws-cdk/custom-resources": "1.135.0",
|
|
44
|
+
"@commitlint/cli": "13.2.1",
|
|
45
|
+
"@commitlint/config-conventional": "13.2.0",
|
|
46
|
+
"@types/jest": "27.0.3",
|
|
47
|
+
"@types/node": "16.11.12",
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "4.33.0",
|
|
49
|
+
"@typescript-eslint/parser": "4.33.0",
|
|
50
|
+
"eslint": "7.32.0",
|
|
51
|
+
"eslint-config-prettier": "8.3.0",
|
|
52
|
+
"eslint-plugin-deprecation": "1.2.1",
|
|
53
|
+
"eslint-plugin-prettier": "4.0.0",
|
|
54
|
+
"husky": "7.0.4",
|
|
55
|
+
"jest": "27.4.3",
|
|
56
|
+
"jest-cdk-snapshot": "1.4.2",
|
|
57
|
+
"prettier": "2.5.1",
|
|
58
|
+
"semantic-release": "18.0.1",
|
|
59
|
+
"ts-jest": "27.0.7",
|
|
60
|
+
"ts-node": "10.4.0",
|
|
61
|
+
"typescript": "4.5.3"
|
|
65
62
|
},
|
|
66
63
|
"peerDependencies": {
|
|
64
|
+
"@aws-cdk/aws-cloudfront": "^1.45.0",
|
|
67
65
|
"@aws-cdk/aws-iam": "^1.45.0",
|
|
68
66
|
"@aws-cdk/aws-lambda": "^1.45.0",
|
|
69
67
|
"@aws-cdk/aws-s3": "^1.45.0",
|
|
70
|
-
"@aws-cdk/
|
|
68
|
+
"@aws-cdk/aws-s3-assets": "^1.45.0",
|
|
69
|
+
"@aws-cdk/core": "^1.45.0",
|
|
70
|
+
"@aws-cdk/custom-resources": "^1.45.0"
|
|
71
71
|
}
|
|
72
72
|
}
|