2026-09-06 12:30:13 +00:00
|
|
|
import * as cdk from 'aws-cdk-lib';
|
|
|
|
|
import { Construct } from 'constructs';
|
|
|
|
|
import * as s3 from 'aws-cdk-lib/aws-s3';
|
|
|
|
|
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
|
|
|
|
|
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
|
|
|
|
|
import * as route53 from 'aws-cdk-lib/aws-route53';
|
|
|
|
|
import * as targets from 'aws-cdk-lib/aws-route53-targets';
|
|
|
|
|
import * as acm from 'aws-cdk-lib/aws-certificatemanager';
|
|
|
|
|
|
|
|
|
|
export class BetaSupplierSiteStack extends cdk.Stack {
|
|
|
|
|
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
|
|
|
|
|
super(scope, id, props);
|
|
|
|
|
|
|
|
|
|
// 1. Create S3 Bucket for Website hosting
|
|
|
|
|
const websiteBucket = new s3.Bucket(this, 'BetaSupplierSiteBucket', {
|
|
|
|
|
bucketName: `betasuppliersite-${this.account}-${this.region}`,
|
|
|
|
|
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
|
|
|
autoDeleteObjects: true,
|
|
|
|
|
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, // Secure by default, OAI will be used
|
|
|
|
|
encryption: s3.BucketEncryption.S3_MANAGED,
|
|
|
|
|
});
|
|
|
|
|
|
2026-09-09 16:22:33 +00:00
|
|
|
const ec2Origin = new origins.HttpOrigin('api.tradhox.com', {
|
2026-09-06 12:30:13 +00:00
|
|
|
protocolPolicy: cloudfront.OriginProtocolPolicy.HTTP_ONLY,
|
|
|
|
|
httpPort: 8080,
|
|
|
|
|
});
|
|
|
|
|
|
2026-09-09 16:22:33 +00:00
|
|
|
// Look up the tradhox.com hosted zone
|
|
|
|
|
const zone = route53.HostedZone.fromLookup(this, 'TradhoxZone', {
|
|
|
|
|
domainName: 'tradhox.com',
|
2026-09-06 12:30:13 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Create a certificate in us-east-1 for CloudFront
|
|
|
|
|
const certificate = new acm.DnsValidatedCertificate(this, 'SiteCertificate', {
|
2026-09-09 16:22:33 +00:00
|
|
|
domainName: 'betapartners.tradhox.com',
|
2026-09-06 12:30:13 +00:00
|
|
|
hostedZone: zone,
|
|
|
|
|
region: 'us-east-1', // CloudFront requires certificates to be in us-east-1
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 2. Create CloudFront Distribution
|
|
|
|
|
// origins.S3BucketOrigin.withOriginAccessControl will automatically create an Origin Access Control (OAC)
|
|
|
|
|
// and update the S3 bucket policy to allow access only from this CloudFront distribution.
|
|
|
|
|
const distribution = new cloudfront.Distribution(this, 'BetaSupplierSiteDistribution', {
|
2026-09-09 16:22:33 +00:00
|
|
|
domainNames: ['betapartners.tradhox.com'],
|
2026-09-06 12:30:13 +00:00
|
|
|
certificate: certificate,
|
|
|
|
|
defaultRootObject: 'index.html',
|
|
|
|
|
defaultBehavior: {
|
|
|
|
|
origin: origins.S3BucketOrigin.withOriginAccessControl(websiteBucket),
|
|
|
|
|
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
|
|
|
allowedMethods: cloudfront.AllowedMethods.ALLOW_GET_HEAD,
|
|
|
|
|
cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD,
|
|
|
|
|
cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
|
|
|
|
|
},
|
|
|
|
|
additionalBehaviors: {
|
|
|
|
|
'/api/*': {
|
|
|
|
|
origin: ec2Origin,
|
|
|
|
|
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
|
|
|
allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
|
|
|
|
|
cachePolicy: cloudfront.CachePolicy.CACHING_DISABLED,
|
|
|
|
|
originRequestPolicy: cloudfront.OriginRequestPolicy.ALL_VIEWER,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
errorResponses: [
|
|
|
|
|
{
|
|
|
|
|
httpStatus: 404,
|
|
|
|
|
responseHttpStatus: 200, // Return 200 for SPAs
|
|
|
|
|
responsePagePath: '/index.html',
|
|
|
|
|
ttl: cdk.Duration.seconds(0),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
httpStatus: 403,
|
|
|
|
|
responseHttpStatus: 200, // Return 200 for SPAs
|
|
|
|
|
responsePagePath: '/index.html',
|
|
|
|
|
ttl: cdk.Duration.seconds(0),
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Outputs
|
|
|
|
|
new cdk.CfnOutput(this, 'BetaSupplierSiteBucketName', {
|
|
|
|
|
value: websiteBucket.bucketName,
|
|
|
|
|
description: 'The name of the S3 bucket for the betasupplier site',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
new cdk.CfnOutput(this, 'BetaSupplierSiteCloudFrontDomainName', {
|
|
|
|
|
value: distribution.distributionDomainName,
|
|
|
|
|
description: 'The domain name of the CloudFront distribution for betasupplier site',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 3. Create Route53 A Record to point to the CloudFront Distribution
|
|
|
|
|
new route53.ARecord(this, 'SiteAliasRecord', {
|
2026-09-09 16:22:33 +00:00
|
|
|
recordName: 'betapartners.tradhox.com',
|
2026-09-06 12:30:13 +00:00
|
|
|
target: route53.RecordTarget.fromAlias(new targets.CloudFrontTarget(distribution)),
|
|
|
|
|
zone
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|