Why to redirect to ROOT?
Don't believe me, just type is www an anachronism
in Google search. Most likely you will get response similar to the following:
What's going on in AWS.
I recently migrated my domains from Godaddy to RT53, and the process was not as straight forward as one would hope.
Route 53 offers extensive options for referencing AWS resources at the domain level, enabling better integration and making the effort worthwhile.
Most of domain registries (like Godaddy) offer convenient user interface for allowing customers to forward domains. There is no W3C standard which regulates how DNS registry providers implement domain forwarding. So it's totally up to the individual providers how to implement the forwarding.
Unlike most of the domain registries providers, RT53 does not offer the domain forwarding option out of the box. If you read documentation, it will tell you that defining CNAME record in RT53 is all you have to do. Well, it just does not work that way (based on my experience, feel free to post in comments if I'm wrong -- always looking for learn something new). The only way I could make it work, was by adding simple Edge function, which intercepts all requests to my web app, and returns the 301 (Moved Permanently) response programmatically.
Things do not work in RT53 the same way as in ... Godaddy.
Just to prove my point, here is the CNAME
record I have in my hosted zone for https://wwww.wisaw.com
And, if you click the link above, it will not resolve to anything.
Let's see what is the easiest way to implement the alternative solution.
Wiring things up for the Edge function.
In your CDK stack, define the Edge function like this:
const redirectLambdaEdgeFunction =
// new lambda.Function( // trying to define it as an Lambda@Edge function
new cloudfront.experimental.EdgeFunction(
this,
`${deployEnv()}_redirectLambdaEdgeFunction`,
{
runtime: lambda.Runtime.NODEJS_22_X,
code: lambda.Code.fromAsset(
path.join(
__dirname,
"../lambda-fns/lambdas/redirectLambdaEdgeFunction",
),
),
// code: lambda.Code.fromAsset('lambda-fns/lambdas.zip'),
handler: "index.handler",
memorySize: 128,
timeout: cdk.Duration.seconds(5),
// insightsVersion,
logRetention,
},
)
Assuming you are hosting your single page app on S3
bucket with CloudFront
distro (read how to do it here: https://dev.to/dmitryame/serving-static-content-from-s3-bucket-195p ), add edgeLambdas
section to the defaultBehavior
of your CloudFront distribution
like this:
// Create the CloudFront distribution with S3 as an origin
const distribution = new cloudfront.Distribution(this, "wisaw-distro", {
priceClass: cloudfront.PriceClass.PRICE_CLASS_100,
defaultBehavior: {
origin: cloudfront_origins.S3BucketOrigin.withOriginAccessControl(webAppBucket),
compress: true,
cachePolicy: basicCachePolicy,
originRequestPolicy: allForwardPolicy,
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, // Add this line
edgeLambdas: [
{
eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
functionVersion: redirectLambdaEdgeFunction.currentVersion,
includeBody: true,
},
],
},
...
The Edge function implementation.
And here is the Edge
function implementation:
exports.handler = async (event) => {
const request = event.Records[0].cf.request;
// CloudFront headers are in format: { "host": [{"key": "Host", "value": "www.wisaw.com"}] }
const host = request.headers.host && request.headers.host[0].value;
if (host === 'www.wisaw.com') {
// Build the new URL, preserving query string if present
let redirectUrl = `https://wisaw.com${request.uri}`;
if (request.querystring) {
redirectUrl += `?${request.querystring}`;
}
return {
status: '301',
statusDescription: 'Moved Permanently',
headers: {
location: [{
key: 'Location',
value: redirectUrl
}]
}
};
}
return request;
};
It's pretty straight forward and self explanatory.
- Intercept all requests
- If the requested host matches
www.wisaw.com
-- prepare the response with the redirectUrl which strips prefixingwww
, and - return this response with status
301
After redeploying your CDK stack -- things are expected to just work. Well, not quite yet. Keep reading.
Still need a CNAME
You still need a CNAME record in RT53 in addition to the Lambda Edge function to make it work correctly. If you have one but not the other -- it will not work. So, you need both. But adding a CNAME is easy. Here is what I've got:
Final touches.
Just to make things perfect, you will also want to make sure all your http
request redirect to https
. The lambda function will already do it for you if you are requesting the www
subdomain. But what if you are hitting http://wisaw.com ? In the CloudFront
definition of your CDK
stack, there is one line of code which defines this behaviour:
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, // Add this line
And that's all. Thanks for reading.
The complete code for this post --> https://github.com/echowaves/WiSaw.cdk
The web app hosted on S3 bucked with properly defined redirects is https://wisaw.com
Happy Hacking.
Top comments (0)