I have a lambda running at an api endpoint serving...
# sst
j
I have a lambda running at an api endpoint serving images. How can I put a cloudfront cdn in front of this with sst? As far as I can tell there's no cloudfront construct
f
You can use the CDK’s CloudFront Distribution construct directly. (All CDK constructs work in SST)
The “From an HTTP endpoint” example might do the trick?
j
Ah perfect, didn't realise all cdk worked in sst, thanks for the heads up!
d
I just implemented a CDN in front of an s3 bucket this week. Here’s my code. I’m not sure it’s 100% right yet, so please let me know if you find anything.
import * as sst from "@serverless-stack/resources";
import * as s3 from "aws-cdk-lib/aws-s3";
import { Certificate } from "aws-cdk-lib/aws-certificatemanager";
import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
import * as route53 from "aws-cdk-lib/aws-route53";
import * as targets from "aws-cdk-lib/aws-route53-targets";
import * as origins from "aws-cdk-lib/aws-cloudfront-origins";
export default class BucketStack extends sst.Stack {
public bucket: any;
constructor(scope: <http://sst.App|sst.App>, id: string, props?: sst.StackProps) {
super(scope, id, props);
this.bucket = new sst.Bucket(this, process.env.S3_PUBLIC_BUCKET_NAME!, {
s3Bucket: {
bucketName: process.env.S3_PUBLIC_BUCKET_NAME!,
publicReadAccess: false,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
},
});
const certificate = Certificate.fromCertificateArn(
this,
"cert",
"arn:aws:acm:us-east-1:-XXXXX"
);
const distribution = new cloudfront.Distribution(
this,
``${process.env.CDN_DOMAIN!}-xxxxx-cdn`,`
{
defaultBehavior: {
origin: new origins.S3Origin(this.bucket.s3Bucket),
viewerProtocolPolicy:
cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
},
domainNames: [process.env.CDN_DOMAIN!],
certificate,
}
);
const zone = route53.HostedZone.fromHostedZoneAttributes(
this,
"shopcatsHostedZone",
{
hostedZoneId: "xxxx",
zoneName: "xxxx",
}
);
new route53.ARecord(this, "CDNARecord", {
zone,
target: route53.RecordTarget.fromAlias(
new targets.CloudFrontTarget(distribution)
),
});
new route53.AaaaRecord(this, "AliasRecord", {
zone,
target: route53.RecordTarget.fromAlias(
new targets.CloudFrontTarget(distribution)
),
});
new route53.ARecord(this, "SiteAliasRecord", {
recordName: process.env.CDN_DOMAIN!,
target: route53.RecordTarget.fromAlias(
new targets.CloudFrontTarget(distribution)
),
zone,
});
}
}
the cloudfront.Distribution is probably missing a good
responseHeadersPolicy
I’m not sure what to put in for that right now. a nice SST wrapper would be, well, nice. but this works for nwo.
oh i just realized you’re serving from a lambda, not s3. well, maybe this code isn’t so helpful…