DEV Community

Cover image for Serverless Containers with Next.js, AWS Fargate, and AWS Amplify : apex ('naked') domain
hexfloor
hexfloor

Posted on • Updated on

Serverless Containers with Next.js, AWS Fargate, and AWS Amplify : apex ('naked') domain

UPDATE : you may wish to consider to switch to the continuous deployment with the out of the box SSR support

Getting Started

You are about to finish the awesome tutorial by Nader Dabit and you are having an issue with apex ('naked') domain. Me too! That is why we are here :)

To make things real I've got a free domain at freenom as you must have a valid domain in order to complete the tutorial.

So here is my domain : nextjsonfargate.tk.
You may take a look at an article describing challenges with apex domains and why you should be using www over apex. The situation is the following : I have just completed the tutorial, the website is available at www.nextjsonfargate.tk
Alt Text
and I wish to add a redirect from an apex domain nextjsonfargate.tk to www.
Alt Text

Read it all through as optimal solution differs for a new project (tweak it in cloud formation) and an ad-hoc asap fix for a running project.

Route53

Route53
The error above tells us to check DNS config, so here it is :
Alt Text

Let's add an A record from apex domain to www :
Alt Text

And here is the config after the change :
Alt Text

Let's try, when accessing via https :
Alt Text

it looks like we need to tweak the certificate, and see how it works for http :
Alt Text

Alright! This is something ;)
Let's jump to Certificate config.

Certificate

ACM
No surprise we are having an ERR_SSL_PROTOCOL_ERROR :
Alt Text

Let's check the details :

Alt Text

The certificate is being used by Elastic Load Balancer and Cloud Front.
Let's create a new certificate for both apex and all subdomains :
Alt Text
Following the validation :

Alt Text
Alright, let's add the new certificate to the Elastic Load Balancer Listeners and Cloud Front Distribution :

Elastic Load Balancer

EC2 -> Load balancers
Here I check on my ELB, navigate to tab Listeners and click on edit rules :
Alt Text

Let's add a new rule before: to redirect from apex to www. I could have modified the existing rule instead = that would result in availability of the website on both urls, I wish it to be constantly redirected to www :

Alt Text

And here is the configuration :
Alt Text

Alt Text

After adding the certificate and changing the default :
Alt Text

Cloud Front

Cloud Front :

I'm changing the certificate and adding the apex domain to Alternate Domain Names :

Alt Text

Intermediate results

Alright, we are set : it works :)
Both http and https :
Alt Text

As a proof of concept I'll tweak the load balancer rules :
Alt Text
Alt Text

We thus have intermediate results : in order to make it work ad-hoc I have done the following :

  • added a new alias in Route 53 hosted zone from apex domain to www
  • created a new certificate with both apex domain and all sub-domains included
  • added certificate to elastic load balancer listener
  • added rule for apex domain in elastic load balancer listener rules
  • added certificate to cloud front distribution
  • added apex domain to cloud front distribution alternate domain names

When you pull and try to publish it works with few warnings :

UPDATE_FAILED               Distribution                                                           AWS::CloudFront::Distribution Fri Apr 30 2021 19:46:12 GMT+0200 (Central European Summer Time) Resource handler returned message: "Invalid request provided: The request failed because it didn't meet the preconditions in one or more request-header fields. (Service: CloudFront, Status Code: 412, Request ID: 7ed28dc9-f634-416d-99fd-9c57486763e2, Extended Request ID: null)" (RequestToken: c0c59ec1-0ef7-ed42-d13c-8be0f51e7220, HandlerErrorCode: InvalidRequest)
UPDATE_ROLLBACK_IN_PROGRESS amplify-nextonfargate-dev-195353-hostingElasticContainer-1D105I0FYAIAR AWS::CloudFormation::Stack    Fri Apr 30 2021 19:46:14 GMT+0200 (Central European Summer Time) The following resource(s) failed to update: [Distribution].                                                                                                                                                                                                                                                                                                                 
⠹ Updating resources in the cloud. This may take a few minutes...

UPDATE_FAILED               hostingElasticContainer          AWS::CloudFormation::Stack Fri Apr 30 2021 19:46:19 GMT+0200 (Central European Summer Time) Embedded stack arn:aws:cloudformation:us-east-1:<account>:stack/amplify-nextonfargate-dev-195353-hostingElasticContainer-1D105I0FYAIAR/e7835650-a989-11eb-9592-0e4dccb471bf was not successfully updated. Currently in UPDATE_ROLLBACK_IN_PROGRESS with reason: The following resource(s) failed to update: [Distribution]. 
UPDATE_ROLLBACK_IN_PROGRESS amplify-nextonfargate-dev-195353 AWS::CloudFormation::Stack Fri Apr 30 2021 19:46:19 GMT+0200 (Central European Summer Time) The following resource(s) failed to update: [hostingElasticContainer].    
Enter fullscreen mode Exit fullscreen mode

The jedi way is to configure all of the above in the cloud formation!
Well, I've removed hosting and started from scratch, tweaked the cloud formation stack and tried to push : it got overridden and all my tweaks were gone.
Let's see if I manage to digest the my tweaks to cloud formation...

Alright, it actually works better if I leave the previous certificate in the load balancer listener list, then on each publish I need to change the certificate in Cloud Front and that's it.

That's really good, as we have both enhanced user experience and deployment experience, a bit of maintenance overhead.

Until I find a way to digest an apex domain to a certificate in cloud formation or a certificate to the stack...
Let's enjoy this Frankenstein solution!

Credits

If I have saved you from deadlines burnout you may express your gratitude here : https://www.buymeacoffee.com/hexfloor

Top comments (0)