Custom Domain Names, CloudFront, & SSL
Mapping your Lambda application to a custom domain name can help you access it without the API Gateway stage path prefix. This in turn helps Rails leverage paths and cookies. Depending on your applications setup (HTTP API, REST API, or an Application Load Balancer) creating a Custom Domain Name involves a few manual steps.
- SSL/TLS Certificate with ACM
- API Gateway Custom Domain Names (Everyone)
- Route53 for Public API Gateway (HTTP or REST)
- Route53 for Private API Gateway (ALB Only or REST with ALB)
- Optional CloudFront Distribution
But why ClickOps vs code? When doing major changes, like runtime upgrades, it is common to create a new stack and switch API Gateway's mapping to the new function. If this mapping were done in a CloudFormation stack, there would be no way to move to a new stack without deleting the old.
SSL/TLS Certificate with ACM
We are going to use AWS Certificate Manager to secure your HTTPS traffic under your custom domain. Again, this assumes your domain is setup in Route53 since you will need to validate the certificate and AWS makes that super easy with DNS.
- AWS Console -> Certificate Manager
- Click "Request a certificate" button.
- Select "Request a public certificate", and "Request a certificate" button.
- Domain name. Ex:
*.example.com
- Click "Next"
- Select "DNS validation", and "Review".
- Click "Confirm and request" button.
- Click the tiny disclosure triangle beside your domain name.
- Click the "Create record in Route 53" button then "Create" again in modal.
- Click "Continue"
Verification will take about 3 minutes. From the Certificate Manager dashboard, you can wait and/or hit the 🔄 button and the Status will change from "Pending validation" to "Issued".
API Gateway Custom Domain Names (Everyone)
No mater if you have HTTP API, REST API Public, or REST API Private with an ALB; you will need to specify a Custom Domain Name in API Gateway. The only exception would be if you are using an Application Load Balancer without REST API. Here are the ClickOps steps to setup an API Gateway Custom Domain Name:
- AWS Console -> API Gateway
- Click "Custom domain names" in the left panel.
- Click "Create" button
- Enter domain name. Ex:
myapp.example.com
- Use default
TLS 1.2 (recommended)
. - Endpoint type
Regional
. - ACM certificate. Select wildcard matching domain from above.
- Click "Create domain name"
After this has been created, the mappings tab should be selected. From here we need to create an API Mapping to point to your specific API Gateway and stage/path. Assuming it is selected:
- Click the "API mappings" tab.
- You should see "No API mappings have been configured..." message
- Click "Configure API mappings" button.
- Click "Add new mapping" button.
- Select your API: Ex:
myapp-main (HTTP - 511n0spvi9)
. - Select your Stage: Ex:
staging
.- If you see
Stage
andstaging
ignore Stage. Known REST bug.
- If you see
- Leave
Path
empty. - Click the "Save" button.
From here there are various ways to setup Route53 and route traffic to your Lambda application. This work simply sets up API Gateway to understand how traffic is routed via what is called SNI. Choose one of the methods below matching your need for Route53.
Route53 for Public API Gateway (HTTP or REST)
✅ Make sure to complete the "API Gateway Custom Domain Names" section first.
From here all we need is a simple DNS entry in Route53 that points to the "API Gateway domain name" we created in the step above. That domain name looks something like: d-byp3km86t3.execute-api.us-east-1.amazonaws.com
- AWS Console -> Route 53 -> Hosted zones
- Click on your domain
- Click "Create record"
- Click "Switch to wizard" if not selected already.
- Select "Simple routing"
- Click "Next"
- Click "Define simple record"
- Record name. Ex:
myapp
- Record type:
A - Routes traffic to an IPv4 address and some AWS resources
- Value/Route traffic to:
Alias to API Gateway API
- Choose Region: Ex:
us-east-1
- Choose endpoint: Should autofill, Ex:
d-byp3km86t3.execute-api.us-east-1.amazonaws.com
- Evaluate target health:
No
- Click "Define simple record"
- Click "Create records"
Route53 for Private API Gateway (ALB Only or REST with ALB)
✅ Make sure to complete the "API Gateway Custom Domain Names" section first if you are using the "REST with ALB". Ignore doing so if you are using an "ALB Only".
From here all we need is a simple DNS entry in Route53 that points to our Application Load Balancer's DNS name CloudFormation output. That domain name looks something like: internal-myapp-rails-bj5cmdxb307p-856336498.us-east-1.elb.amazonaws.com
- AWS Console -> Route 53 -> Hosted zones
- Click on your domain
- Click "Create record"
- Click "Switch to wizard" if not selected already.
- Select "Simple routing"
- Click "Next"
- Click "Define simple record"
- Record name. Ex:
myapp
- Record type:
A - Routes traffic to an IPv4 address and some AWS resources
- Value/Route traffic to:
Alias to Application and Classic Load Balancer
. - Choose Region: Ex:
us-east-1
- Choose endpoint: Should autofill, Ex:
internal-myapp-rails-bj5cmdxb307p-856336498.us-east-1.elb.amazonaws.com
- Evaluate target health:
No
- Click "Define simple record"
- Click "Create records"
Optional CloudFront Distribution
This part is optional and can be used with any integration method. Instead of creating a Route53 entry for API Gateway's custom domain (d-xxxxxxxxxx.execute-api.us-east-1.amazonaws.com
) or an ALB's DNS Name (internal-myapp-rails-bj5cmdxb307p-856336498.us-east-1.elb.amazonaws.com
) you would instead use those as the CloudFront's origin. The final CloudFront distribution name (dxxxxxxxxxxxxx.cloudfront.net
) would be the Route53 target instead. Here are the steps to create your CloudFront Distribution:
- AWS Console -> CloudFront -> Create Distribution -> Web -> Get Started
- Origin Domain Name: d-xxxxxxxxxx.execute-api.us-east-1.amazonaws.com
- Origin Path: /production (or your deployed stage/env)
- Minimum Origin SSL Protocol: TLSv1.2
- Origin Protocol Policy: HTTPS Only
- Origin Custom Headers: X-Forwarded-Host myapp.example.com (⚠️ IMPORTANT)
- Viewer Protocol Policy: Redirect HTTP to HTTPS
- Allowed HTTP Methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
- Cached HTTP Methods: OPTIONS
- Cache Based on Selected Request Headers: Whitelist - Accept (⚠️ Allows
respond_to
to work) - Object Caching: Use Origin Cache Headers
- Forward Cookies: All
- Query String Forwarding and Caching: Forward all, cached based on all
- Compress Objects Automatically: Yes
- Alternate Domain Names (CNAMEs): myapp.example.com
- SSL Certificate: Custom SSL Certificate (select *.example.com from step above)
This process takes a while to fully deploy. Once done you will have a CloudFront domain name looking something like dxxxxxxxxxxxxx.cloudfront.net
. Head to Route53 and create an alias for myapp.example.com
to this CloudFront distibution domain name.