UNPKG

@capraconsulting/webapp-deploy-lambda

Version:

CDK construct for deploying a webapp release to S3 and CloudFront

66 lines 11.2 kB
import * as constructs from "constructs"; import * as iam from "aws-cdk-lib/aws-iam"; import * as lambda from "aws-cdk-lib/aws-lambda"; import * as cdk from "aws-cdk-lib"; import { Provider } from "aws-cdk-lib/custom-resources"; import * as path from "path"; import { fileURLToPath } from "url"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); /** * Resource to deploy a webapp from a build artifact into an existing * S3 Bucket and CloudFront Distribution. */ export class WebappDeploy extends constructs.Construct { deployFn; constructor(scope, id, props) { super(scope, id); const environment = { DEPLOY_LOG_BUCKET_URL: `s3://${props.webBucket.bucketName}/deployments.log`, EXPIRE_SECONDS: (props.pruneDeploymentsOlderThan ?? cdk.Duration.days(5)) .toSeconds() .toString(), TARGET_BUCKET_URL: `s3://${props.webBucket.bucketName}/web`, }; if (props.distribution != null) { environment.CF_DISTRIBUTION_ID = props.distribution.distributionId; } if (props.excludePattern != null) { environment.EXCLUDE_PATTERN = props.excludePattern; } this.deployFn = new lambda.Function(this, "WebappDeployResource", { code: lambda.Code.fromAsset(path.join(__dirname, "../dist")), environment, functionName: props.functionName ?? cdk.PhysicalName.GENERATE_IF_NEEDED, handler: "webapp_deploy.main.handler", reservedConcurrentExecutions: 1, runtime: lambda.Runtime.PYTHON_3_12, timeout: cdk.Duration.minutes(2), initialPolicy: [ new iam.PolicyStatement({ actions: ["cloudfront:CreateInvalidation"], // Cannot be restricted resources: ["*"], }), ], }); const provider = new Provider(this, "Provider", { onEventHandler: this.deployFn, }); props.webBucket.grantReadWrite(this.deployFn); if (props.buildsBucket) { props.buildsBucket.grantRead(this.deployFn); } if (props.source) { const source = props.source.bind(this, { handlerRole: this.deployFn.role, }); new cdk.CustomResource(this, "CustomResource", { serviceToken: provider.serviceToken, properties: { artifactS3Url: `s3://${source.bucket.bucketName}/${source.zipObjectKey}`, }, }); } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViYXBwLWRlcGxveS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy93ZWJhcHAtZGVwbG95LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxVQUFVLE1BQU0sWUFBWSxDQUFBO0FBRXhDLE9BQU8sS0FBSyxHQUFHLE1BQU0scUJBQXFCLENBQUE7QUFDMUMsT0FBTyxLQUFLLE1BQU0sTUFBTSx3QkFBd0IsQ0FBQTtBQUVoRCxPQUFPLEtBQUssR0FBRyxNQUFNLGFBQWEsQ0FBQTtBQUNsQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sOEJBQThCLENBQUE7QUFDdkQsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUE7QUFFNUIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLEtBQUssQ0FBQTtBQUVuQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7QUFxRDlEOzs7R0FHRztBQUNILE1BQU0sT0FBTyxZQUFhLFNBQVEsVUFBVSxDQUFDLFNBQVM7SUFDM0MsUUFBUSxDQUFpQjtJQUVsQyxZQUNFLEtBQTJCLEVBQzNCLEVBQVUsRUFDVixLQUF3QjtRQUV4QixLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBRWhCLE1BQU0sV0FBVyxHQUEyQjtZQUMxQyxxQkFBcUIsRUFBRSxRQUFRLEtBQUssQ0FBQyxTQUFTLENBQUMsVUFBVSxrQkFBa0I7WUFDM0UsY0FBYyxFQUFFLENBQUMsS0FBSyxDQUFDLHlCQUF5QixJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUN0RSxTQUFTLEVBQUU7aUJBQ1gsUUFBUSxFQUFFO1lBQ2IsaUJBQWlCLEVBQUUsUUFBUSxLQUFLLENBQUMsU0FBUyxDQUFDLFVBQVUsTUFBTTtTQUM1RCxDQUFBO1FBRUQsSUFBSSxLQUFLLENBQUMsWUFBWSxJQUFJLElBQUksRUFBRSxDQUFDO1lBQy9CLFdBQVcsQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQTtRQUNwRSxDQUFDO1FBRUQsSUFBSSxLQUFLLENBQUMsY0FBYyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ2pDLFdBQVcsQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDLGNBQWMsQ0FBQTtRQUNwRCxDQUFDO1FBRUQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLHNCQUFzQixFQUFFO1lBQ2hFLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUM1RCxXQUFXO1lBQ1gsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZLElBQUksR0FBRyxDQUFDLFlBQVksQ0FBQyxrQkFBa0I7WUFDdkUsT0FBTyxFQUFFLDRCQUE0QjtZQUNyQyw0QkFBNEIsRUFBRSxDQUFDO1lBQy9CLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVc7WUFDbkMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNoQyxhQUFhLEVBQUU7Z0JBQ2IsSUFBSSxHQUFHLENBQUMsZUFBZSxDQUFDO29CQUN0QixPQUFPLEVBQUUsQ0FBQywrQkFBK0IsQ0FBQztvQkFDMUMsdUJBQXVCO29CQUN2QixTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsQ0FBQTtRQUVGLE1BQU0sUUFBUSxHQUFHLElBQUksUUFBUSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDOUMsY0FBYyxFQUFFLElBQUksQ0FBQyxRQUFRO1NBQzlCLENBQUMsQ0FBQTtRQUVGLEtBQUssQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUU3QyxJQUFJLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN2QixLQUFLLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDN0MsQ0FBQztRQUVELElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2pCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtnQkFDckMsV0FBVyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSzthQUNqQyxDQUFDLENBQUE7WUFDRixJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLGdCQUFnQixFQUFFO2dCQUM3QyxZQUFZLEVBQUUsUUFBUSxDQUFDLFlBQVk7Z0JBQ25DLFVBQVUsRUFBRTtvQkFDVixhQUFhLEVBQUUsUUFBUSxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBSSxNQUFNLENBQUMsWUFBWSxFQUFFO2lCQUN6RTthQUNGLENBQUMsQ0FBQTtRQUNKLENBQUM7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjb25zdHJ1Y3RzIGZyb20gXCJjb25zdHJ1Y3RzXCJcbmltcG9ydCAqIGFzIGNsb3VkZnJvbnQgZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZGZyb250XCJcbmltcG9ydCAqIGFzIGlhbSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWlhbVwiXG5pbXBvcnQgKiBhcyBsYW1iZGEgZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGFcIlxuaW1wb3J0ICogYXMgczMgZnJvbSBcImF3cy1jZGstbGliL2F3cy1zM1wiXG5pbXBvcnQgKiBhcyBjZGsgZnJvbSBcImF3cy1jZGstbGliXCJcbmltcG9ydCB7IFByb3ZpZGVyIH0gZnJvbSBcImF3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXNcIlxuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiXG5pbXBvcnQgeyBJU291cmNlIH0gZnJvbSBcIi4vc291cmNlXCJcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tIFwidXJsXCJcblxuY29uc3QgX19kaXJuYW1lID0gcGF0aC5kaXJuYW1lKGZpbGVVUkxUb1BhdGgoaW1wb3J0Lm1ldGEudXJsKSlcblxuZXhwb3J0IGludGVyZmFjZSBXZWJhcHBEZXBsb3lQcm9wcyB7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBTMyBidWNrZXQgdGhhdCBjYW4gYmUgdXNlZCBmb3IgZGVwbG95bWVudCBmcm9tIG91dHNpZGUgQ0RLLlxuICAgKlxuICAgKiBJZiBzcGVjaWZpZWQgYSBwb2xpY3kgaXMgYWRkZWQgc28gdGhlIGRlcGxveSBmdW5jdGlvbiBjYW4gcmVhZCBmcm9tXG4gICAqIHRoZSBidWNrZXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm9uZVxuICAgKi9cbiAgYnVpbGRzQnVja2V0PzogczMuSUJ1Y2tldFxuICAvKipcbiAgICogQ2xvdWRGcm9udCBEaXN0cmlidXRpb24gdG8gYmUgaW52YWxpZGF0ZWQgYWZ0ZXIgZGVwbG95LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vbmVcbiAgICovXG4gIGRpc3RyaWJ1dGlvbj86IGNsb3VkZnJvbnQuSURpc3RyaWJ1dGlvblxuICAvKipcbiAgICogUmVnZXggZm9yIHBhdHRlcm5zIG9mIGZpbGVzIHRvIGJlIGRpc2NhcmRlZCBkdXJpbmcgZGVwbG95bWVudC5cbiAgICpcbiAgICogRXhhbXBsZTogYFxcLm1hcCRgIHdpbGwgZXhjbHVkZSBganMvbXlhcHAtMWIyMmMyNDhmLmpzLm1hcGAuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm9uZVxuICAgKi9cbiAgZXhjbHVkZVBhdHRlcm4/OiBzdHJpbmdcbiAgLyoqXG4gICAqIFRoZSB0aW1lIHdoZW4gYSBkZXBsb3ltZW50IGlzIGNvbnNpZGVyZWQgb2xkIGFuZCB3aWxsIGJlIGRlbGV0ZWRcbiAgICogdW5sZXNzIGl0IGlzIHRoZSBuZXdlc3Qgb2xkIGRlcGxveW1lbnQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gNSBkYXlzXG4gICAqL1xuICBwcnVuZURlcGxveW1lbnRzT2xkZXJUaGFuPzogY2RrLkR1cmF0aW9uXG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSBsYW1iZGEgZnVuY3Rpb24gdG8gYmUgY3JlYXRlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgY2RrLlBoeXNpY2FsTmFtZS5HRU5FUkFURV9JRl9ORUVERURcbiAgICovXG4gIGZ1bmN0aW9uTmFtZT86IHN0cmluZ1xuICAvKipcbiAgICogTmFtZSBvZiBTMyBidWNrZXQgd2hlcmUgdGhlIGNvbnRlbnRzIG9mIHRoZSBhcnRpZmFjdHMgd2lsbCBiZSBkZXBsb3llZC5cbiAgICogVGhlIGZpbGVzIHdpbGwgYmUgZGVwbG95ZWQgdW5kZXIgdGhlIGtleSBcIndlYlwiLCB3aGljaCBpcyB0aGVuIGV4cGVjdGVkXG4gICAqIHRvIGJlIHRoZSBvcmlnaW4gZm9yIHRoZSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvblxuICAgKi9cbiAgd2ViQnVja2V0OiBzMy5JQnVja2V0XG4gIC8qKlxuICAgKiBTcGVjaWZpYyBhcnRpZmFjdCB0byBiZSBkZXBsb3llZCB0byB0aGUgYnVja2V0IGR1cmluZyBDREsgZGVwbG95bWVudC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICBzb3VyY2U/OiBJU291cmNlXG59XG5cbi8qKlxuICogUmVzb3VyY2UgdG8gZGVwbG95IGEgd2ViYXBwIGZyb20gYSBidWlsZCBhcnRpZmFjdCBpbnRvIGFuIGV4aXN0aW5nXG4gKiBTMyBCdWNrZXQgYW5kIENsb3VkRnJvbnQgRGlzdHJpYnV0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgV2ViYXBwRGVwbG95IGV4dGVuZHMgY29uc3RydWN0cy5Db25zdHJ1Y3Qge1xuICByZWFkb25seSBkZXBsb3lGbjogbGFtYmRhLkZ1bmN0aW9uXG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IFdlYmFwcERlcGxveVByb3BzLFxuICApIHtcbiAgICBzdXBlcihzY29wZSwgaWQpXG5cbiAgICBjb25zdCBlbnZpcm9ubWVudDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgIERFUExPWV9MT0dfQlVDS0VUX1VSTDogYHMzOi8vJHtwcm9wcy53ZWJCdWNrZXQuYnVja2V0TmFtZX0vZGVwbG95bWVudHMubG9nYCxcbiAgICAgIEVYUElSRV9TRUNPTkRTOiAocHJvcHMucHJ1bmVEZXBsb3ltZW50c09sZGVyVGhhbiA/PyBjZGsuRHVyYXRpb24uZGF5cyg1KSlcbiAgICAgICAgLnRvU2Vjb25kcygpXG4gICAgICAgIC50b1N0cmluZygpLFxuICAgICAgVEFSR0VUX0JVQ0tFVF9VUkw6IGBzMzovLyR7cHJvcHMud2ViQnVja2V0LmJ1Y2tldE5hbWV9L3dlYmAsXG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmRpc3RyaWJ1dGlvbiAhPSBudWxsKSB7XG4gICAgICBlbnZpcm9ubWVudC5DRl9ESVNUUklCVVRJT05fSUQgPSBwcm9wcy5kaXN0cmlidXRpb24uZGlzdHJpYnV0aW9uSWRcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuZXhjbHVkZVBhdHRlcm4gIT0gbnVsbCkge1xuICAgICAgZW52aXJvbm1lbnQuRVhDTFVERV9QQVRURVJOID0gcHJvcHMuZXhjbHVkZVBhdHRlcm5cbiAgICB9XG5cbiAgICB0aGlzLmRlcGxveUZuID0gbmV3IGxhbWJkYS5GdW5jdGlvbih0aGlzLCBcIldlYmFwcERlcGxveVJlc291cmNlXCIsIHtcbiAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChwYXRoLmpvaW4oX19kaXJuYW1lLCBcIi4uL2Rpc3RcIikpLFxuICAgICAgZW52aXJvbm1lbnQsXG4gICAgICBmdW5jdGlvbk5hbWU6IHByb3BzLmZ1bmN0aW9uTmFtZSA/PyBjZGsuUGh5c2ljYWxOYW1lLkdFTkVSQVRFX0lGX05FRURFRCxcbiAgICAgIGhhbmRsZXI6IFwid2ViYXBwX2RlcGxveS5tYWluLmhhbmRsZXJcIixcbiAgICAgIHJlc2VydmVkQ29uY3VycmVudEV4ZWN1dGlvbnM6IDEsXG4gICAgICBydW50aW1lOiBsYW1iZGEuUnVudGltZS5QWVRIT05fM18xMixcbiAgICAgIHRpbWVvdXQ6IGNkay5EdXJhdGlvbi5taW51dGVzKDIpLFxuICAgICAgaW5pdGlhbFBvbGljeTogW1xuICAgICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgYWN0aW9uczogW1wiY2xvdWRmcm9udDpDcmVhdGVJbnZhbGlkYXRpb25cIl0sXG4gICAgICAgICAgLy8gQ2Fubm90IGJlIHJlc3RyaWN0ZWRcbiAgICAgICAgICByZXNvdXJjZXM6IFtcIipcIl0sXG4gICAgICAgIH0pLFxuICAgICAgXSxcbiAgICB9KVxuXG4gICAgY29uc3QgcHJvdmlkZXIgPSBuZXcgUHJvdmlkZXIodGhpcywgXCJQcm92aWRlclwiLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogdGhpcy5kZXBsb3lGbixcbiAgICB9KVxuXG4gICAgcHJvcHMud2ViQnVja2V0LmdyYW50UmVhZFdyaXRlKHRoaXMuZGVwbG95Rm4pXG5cbiAgICBpZiAocHJvcHMuYnVpbGRzQnVja2V0KSB7XG4gICAgICBwcm9wcy5idWlsZHNCdWNrZXQuZ3JhbnRSZWFkKHRoaXMuZGVwbG95Rm4pXG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnNvdXJjZSkge1xuICAgICAgY29uc3Qgc291cmNlID0gcHJvcHMuc291cmNlLmJpbmQodGhpcywge1xuICAgICAgICBoYW5kbGVyUm9sZTogdGhpcy5kZXBsb3lGbi5yb2xlISxcbiAgICAgIH0pXG4gICAgICBuZXcgY2RrLkN1c3RvbVJlc291cmNlKHRoaXMsIFwiQ3VzdG9tUmVzb3VyY2VcIiwge1xuICAgICAgICBzZXJ2aWNlVG9rZW46IHByb3ZpZGVyLnNlcnZpY2VUb2tlbixcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIGFydGlmYWN0UzNVcmw6IGBzMzovLyR7c291cmNlLmJ1Y2tldC5idWNrZXROYW1lfS8ke3NvdXJjZS56aXBPYmplY3RLZXl9YCxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgfVxuICB9XG59XG4iXX0=