Create your www.example.com
bucket and set it up for hosting a static website. Apply your policy (pasted here for completion):
{
"Version":"2012-10-17",
"Statement": [{
"Sid": "Allow Public Access to All Objects",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::www.example.com/*"
}
]
}
The Resource
property is updated with the current bucket.
Once that's in place, deploy your website to this bucket. Update your Route 53 records to point www.example.com
to this bucket. You should then test www.example.com
to ensure it's working. If not, fix it. Only when it's working should you continue.
Once the www.example.com
is working, then you would modify your example.com
bucket to simply redirect to www.example.com
. No need to modify your Route 53 records since it's already pointing to your example.com
bucket.
Once this is done, your browser should hit example.com
and then be redirected to www.example.com
.
When you're all done, you can delete all the objects from your example.com
bucket since they're not being accessed anymore. You can also remove any custom permissions/policies on that bucket.
You have to create a SSL certificate using the Certificate Manager. For an edge endpoint, create it in eu-east-1, for regional and private endpoints, create it in the region you are deploying the API gateway in (or the lambda). Read more here. I will refer to the ARN as CertificateArn
You have to configure a AWS::ApiGateway::DomainName
:
"MyDomainName": {
"Type": "AWS::ApiGateway::DomainName",
"Properties": {
"DomainName": {"Ref: "DomainName"},
"CertificateArn": "arn:aws:acm:us-east-1:111122223333:certificate/fb1b9770-a305-495d-aefb-27e5e101ff3"
}
}
This enables the Domain for the API Gateway. Next, you need to expose the API (i.e. your RestAPI), in a specific deployment stage. In your template, your have no deployment stages. Take a look a AWS::ApiGateway::Stage
. A minimal example would look like this:
"Prod": {
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"StageName": "Prod",
"Description": "Prod Stage",
"RestApiId": {
"Ref": "APIGateway"
},
"DeploymentId": {
"Ref": "APITDeploymentTest"
},
}
However, you most likely want some additional configuration in that. I suggest you take a look at the MethodSettings
property.
At last, deploy a basepath mapping resource: AWS::ApiGateway::BasePathMapping
. I suggest you map the basepath to the stage you created like this:
"ProdDomainBasePath": {
"Type" : "AWS::ApiGateway::BasePathMapping",
"Properties" : {
"DomainName" : {"Ref: "DomainName"},
"RestApiId" : {"Ref": "APIGateway"},
"Stage" : "Prod"
}
}
If you change an AWS::ApiGateway::Stage
resource, you have to force an update on the corresponding AWS::ApiGateway::Deployment
resource - this usually means renaming the AWS::ApiGateway::Deployment
resource, to keep that in mind. Otherwise, it wont be deployed.
That should do it.
Best Answer
You will have to perform the redirect in your lambda function.
I’m sure the actual hostname used in the URL is passed to the Lambda, perhaps as
event.headers.Host
. So in your Lambda you’ll have to do something like this python-like code:However if I were you I would point the non-www hostname to a different API gateway with a single Lambda dedicated to performing the redirect to www. Then in your actual worker lambdas you won’t have to worry about the redirects.
Hope that helps :)