cdk-serverless-agentic-api
Version:
CDK construct for serverless web applications with CloudFront, S3, Cognito, API Gateway, and Lambda
163 lines • 6.54 kB
JavaScript
;
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.createS3Bucket = createS3Bucket;
exports.createOriginAccessIdentity = createOriginAccessIdentity;
exports.configureBucketPolicy = configureBucketPolicy;
exports.createLoggingBucket = createLoggingBucket;
const s3 = __importStar(require("aws-cdk-lib/aws-s3"));
const iam = __importStar(require("aws-cdk-lib/aws-iam"));
const cloudfront = __importStar(require("aws-cdk-lib/aws-cloudfront"));
const aws_cdk_lib_1 = require("aws-cdk-lib");
/**
* Creates the S3 bucket for static website hosting
*
* @param scope The construct scope
* @param id The construct ID
* @param props Configuration properties
* @returns The created S3 bucket
*/
function createS3Bucket(scope, _id, // Prefix with underscore to indicate it's not used
props) {
return new s3.Bucket(scope, 'StaticWebsiteBucket', {
bucketName: props?.bucketName,
// Block all public access - access will be granted only to CloudFront
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
// Enable versioning for deployment rollbacks
versioned: true,
// Configure removal policy based on environment
removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
// Enable server access logging if logging is enabled
serverAccessLogsPrefix: props?.enableLogging !== false ? 'access-logs/' : undefined,
// Configure lifecycle rules for cost optimization
lifecycleRules: [
{
id: 'DeleteIncompleteMultipartUploads',
abortIncompleteMultipartUploadAfter: aws_cdk_lib_1.Duration.days(7),
enabled: true,
},
{
id: 'DeleteOldVersions',
noncurrentVersionExpiration: aws_cdk_lib_1.Duration.days(30),
enabled: true,
},
],
// Enable event notifications for monitoring
eventBridgeEnabled: true,
});
}
/**
* Creates CloudFront Origin Access Identity for secure S3 access
*
* @param scope The construct scope
* @param id The construct ID
* @returns The created Origin Access Identity
*/
function createOriginAccessIdentity(scope, id) {
return new cloudfront.OriginAccessIdentity(scope, 'OriginAccessIdentity', {
comment: `OAI for ${id} static website bucket`,
});
}
/**
* Configures the S3 bucket policy to allow CloudFront access
*
* @param bucket The S3 bucket
* @param originAccessIdentity The CloudFront Origin Access Identity
*/
function configureBucketPolicy(bucket, originAccessIdentity) {
// Grant CloudFront OAI read access to the bucket
bucket.addToResourcePolicy(new iam.PolicyStatement({
sid: 'AllowCloudFrontAccess',
effect: iam.Effect.ALLOW,
principals: [originAccessIdentity.grantPrincipal],
actions: ['s3:GetObject'],
resources: [bucket.arnForObjects('*')],
}));
// Grant CloudFront OAI list access to the bucket for error handling
bucket.addToResourcePolicy(new iam.PolicyStatement({
sid: 'AllowCloudFrontListBucket',
effect: iam.Effect.ALLOW,
principals: [originAccessIdentity.grantPrincipal],
actions: ['s3:ListBucket'],
resources: [bucket.bucketArn],
}));
}
/**
* Creates a dedicated S3 bucket for CloudFront access logs with ACLs enabled
*
* @param scope The construct scope
* @returns The created S3 bucket
*/
function createLoggingBucket(scope) {
// Create a dedicated logging bucket with ACLs explicitly enabled
const loggingBucket = new s3.Bucket(scope, 'LoggingBucket', {
objectOwnership: s3.ObjectOwnership.OBJECT_WRITER, // Enable ACLs for CloudFront logs
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
encryption: s3.BucketEncryption.S3_MANAGED,
enforceSSL: true,
removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
lifecycleRules: [
{
expiration: aws_cdk_lib_1.Duration.days(90),
transitions: [
{
storageClass: s3.StorageClass.INFREQUENT_ACCESS,
transitionAfter: aws_cdk_lib_1.Duration.days(30)
},
{
storageClass: s3.StorageClass.GLACIER,
transitionAfter: aws_cdk_lib_1.Duration.days(60)
}
]
}
]
});
// Grant CloudFront service principal permission to write logs via bucket policy
loggingBucket.addToResourcePolicy(new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
principals: [new iam.ServicePrincipal('delivery.logs.amazonaws.com')],
actions: ['s3:PutObject'],
resources: [loggingBucket.arnForObjects('*')]
}));
loggingBucket.addToResourcePolicy(new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
principals: [new iam.ServicePrincipal('cloudfront.amazonaws.com')],
actions: ['s3:GetBucketAcl'],
resources: [loggingBucket.bucketArn]
}));
return loggingBucket;
}
//# sourceMappingURL=s3.js.map