UNPKG

cdk-serverless-agentic-api

Version:

CDK construct for serverless web applications with CloudFront, S3, Cognito, API Gateway, and Lambda

223 lines 10 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.createCloudFrontDistribution = createCloudFrontDistribution; exports.createResponseHeadersPolicy = createResponseHeadersPolicy; exports.createApiResponseHeadersPolicy = createApiResponseHeadersPolicy; const cloudfront = __importStar(require("aws-cdk-lib/aws-cloudfront")); const origins = __importStar(require("aws-cdk-lib/aws-cloudfront-origins")); const acm = __importStar(require("aws-cdk-lib/aws-certificatemanager")); const aws_cdk_lib_1 = require("aws-cdk-lib"); const error_handling_1 = require("./error-handling"); /** * Creates the CloudFront distribution with S3 and API Gateway origins * * @param scope The construct scope * @param id The construct ID * @param bucket The S3 bucket for static content * @param originAccessIdentity The CloudFront Origin Access Identity * @param api The API Gateway REST API * @param props Configuration properties * @param loggingBucket The S3 bucket for CloudFront access logs * @returns The created CloudFront distribution */ function createCloudFrontDistribution(scope, id, bucket, originAccessIdentity, api, props, loggingBucket) { // Create S3 origin for static content const s3Origin = origins.S3BucketOrigin.withOriginAccessIdentity(bucket, { originAccessIdentity: originAccessIdentity, originPath: '', }); // Create API Gateway origin for /api/* paths const apiOrigin = new origins.HttpOrigin(`${api.restApiId}.execute-api.${process.env.AWS_REGION || 'us-east-1'}.amazonaws.com`, { originPath: '', }); // Configure SSL certificate if custom domain is provided const certificate = props?.certificateArn ? acm.Certificate.fromCertificateArn(scope, 'Certificate', props.certificateArn) : undefined; // Create CloudFront distribution const distribution = new cloudfront.Distribution(scope, 'Distribution', { comment: `CloudFront distribution for ${id} serverless web application`, // Configure default behavior for static content (S3) defaultBehavior: { origin: s3Origin, viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, allowedMethods: cloudfront.AllowedMethods.ALLOW_GET_HEAD_OPTIONS, cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD_OPTIONS, compress: true, cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED, originRequestPolicy: cloudfront.OriginRequestPolicy.CORS_S3_ORIGIN, responseHeadersPolicy: createResponseHeadersPolicy(scope, id), }, // Configure additional behaviors for API Gateway additionalBehaviors: { '/api/*': { origin: apiOrigin, viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL, cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD, compress: true, cachePolicy: cloudfront.CachePolicy.CACHING_DISABLED, originRequestPolicy: cloudfront.OriginRequestPolicy.ALL_VIEWER_EXCEPT_HOST_HEADER, responseHeadersPolicy: createApiResponseHeadersPolicy(scope, id), }, }, // Configure custom domain if provided ...(props?.domainName && certificate && { domainNames: [props.domainName], certificate: certificate, }), // Configure default root object defaultRootObject: 'index.html', // Configure custom error responses using error handling utilities errorResponses: (0, error_handling_1.createErrorPages)(scope, bucket, id), // No geographic restrictions by default // Configure price class for cost optimization priceClass: cloudfront.PriceClass.PRICE_CLASS_100, // Enable IPv6 enableIpv6: true, // Configure logging if enabled ...(props?.enableLogging !== false && loggingBucket && { enableLogging: true, logBucket: loggingBucket, logFilePrefix: 'cloudfront-logs/', logIncludesCookies: false, }), // Configure HTTP version httpVersion: cloudfront.HttpVersion.HTTP2_AND_3, // Configure minimum TLS version minimumProtocolVersion: cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021, // Configure web ACL if needed (placeholder for future enhancement) webAclId: undefined, }); return distribution; } /** * Creates a response headers policy for static content with security headers * * @param scope The construct scope * @param id The construct ID * @returns The created response headers policy */ function createResponseHeadersPolicy(scope, id) { return new cloudfront.ResponseHeadersPolicy(scope, 'StaticContentResponseHeadersPolicy', { responseHeadersPolicyName: `${id}-static-headers`, comment: 'Security headers for static content', // Configure security headers securityHeadersBehavior: { contentTypeOptions: { override: true, }, frameOptions: { frameOption: cloudfront.HeadersFrameOption.DENY, override: true, }, referrerPolicy: { referrerPolicy: cloudfront.HeadersReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN, override: true, }, strictTransportSecurity: { accessControlMaxAge: aws_cdk_lib_1.Duration.seconds(31536000), // 1 year includeSubdomains: true, preload: true, override: true, }, contentSecurityPolicy: { contentSecurityPolicy: "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:; media-src 'self'; object-src 'none'; child-src 'none'; worker-src 'none'; frame-ancestors 'none'; form-action 'self'; base-uri 'self';", override: true, }, }, // Configure CORS headers for static content corsBehavior: { accessControlAllowCredentials: false, accessControlAllowHeaders: [ 'Content-Type', 'X-Amz-Date', 'Authorization', 'X-Api-Key', 'X-Amz-Security-Token', 'X-Amz-User-Agent', 'X-Requested-With', ], accessControlAllowMethods: ['GET', 'HEAD', 'OPTIONS'], accessControlAllowOrigins: ['*'], accessControlMaxAge: aws_cdk_lib_1.Duration.seconds(86400), // 24 hours originOverride: true, }, }); } /** * Creates a response headers policy for API Gateway with appropriate CORS settings * * @param scope The construct scope * @param id The construct ID * @returns The created response headers policy */ function createApiResponseHeadersPolicy(scope, id) { return new cloudfront.ResponseHeadersPolicy(scope, 'ApiResponseHeadersPolicy', { responseHeadersPolicyName: `${id}-api-headers`, comment: 'Headers for API Gateway responses', // Configure minimal security headers for API responses securityHeadersBehavior: { contentTypeOptions: { override: false, // Let API Gateway control this }, strictTransportSecurity: { accessControlMaxAge: aws_cdk_lib_1.Duration.seconds(31536000), // 1 year includeSubdomains: true, preload: true, override: false, // Let API Gateway control this }, }, // Configure CORS headers for API responses corsBehavior: { accessControlAllowCredentials: true, accessControlAllowHeaders: [ 'Content-Type', 'X-Amz-Date', 'Authorization', 'X-Api-Key', 'X-Amz-Security-Token', 'X-Amz-User-Agent', 'X-Requested-With', ], accessControlAllowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'], accessControlAllowOrigins: ['*'], // Will be restricted when custom domain is configured accessControlMaxAge: aws_cdk_lib_1.Duration.seconds(3600), // 1 hour originOverride: false, // Let API Gateway control CORS }, }); } //# sourceMappingURL=cloudfront.js.map