Reputation: 1061
I have deployed the new Lambda function URL feature with a Cloudfront distribution to enable a custom domain. However, my backend needs the real host head and not the one Cloudfront rewrites (see host here), in this case to the function URL https://xxxxxxxx.lambda-url.eu-central-1.on.aws/.
I also tried using the managed origin request policy AllViewer, but this neither works and in the browser it returns: "Message: null" and the x-cache header says cloudfront error.
My config currently looks like this:
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
PriceClass: PriceClass_100
HttpVersion: http2
IPV6Enabled: true
Comment: Distribution for Lambda Function URL
Origins:
# extract function url form your lambda resource
- DomainName: !Select [2, !Split ["/", !GetAtt ApiLambdaFunctionUrl.FunctionUrl]]
Id: LambdaOrigin
CustomOriginConfig:
HTTPSPort: 443
OriginProtocolPolicy: https-only
Enabled: 'true'
DefaultCacheBehavior:
TargetOriginId: LambdaOrigin
# Disable caching as http api did not allow either
CachePolicyId: '4135ea2d-6df8-44a3-9df3-4b5a84be39ad'
ViewerProtocolPolicy: redirect-to-https
SmoothStreaming: 'false'
Compress: 'true'
Aliases:
- sub.domain.com
ViewerCertificate:
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1.2_2019
AcmCertificateArn: xxxxx
FunctionRecordSetGroup:
Type: AWS::Route53::RecordSetGroup
DeletionPolicy: Delete
DependsOn:
- CloudFrontDistribution
Properties:
HostedZoneName: domain.com.
RecordSets:
- Name: sub.domain.com
Type: A
AliasTarget:
# The following HosteZoneId is always used for alias records pointing to CF.
HostedZoneId: Z2FDTNDATAQYW2
DNSName: { 'Fn::GetAtt': [CloudFrontDistribution, DomainName] }
How can I achieve forwarding the host header?
Upvotes: 3
Views: 3234
Reputation: 61
I had the same issue with CloudFront when parsing the host
header via the origin_request
and origin_response
Lambda@Edge
functions since the header contains the value of the origin
because that is the request's destination. The request/response Lambdas are book-end functions that run before and after the call to the origin server.
In the case of @peterhack (OP), the Lambda function URL is the origin
without utilizing Lambda@Edge
request/response interceptors, but the principle is the same.
A CloudFront Function receives the correct host header because it receives the original viewer_request
event. Since one cannot meaningfully overwrite the host
header, I substituted a generic header viewer-host
to receive the value:
// Cloudfront Function (ES5)
// viewer_request
function handler(event) {
var request = event.request;
request.headers["viewer-host"] = request.headers.host;
return request;
}
Note: Here, we add the header to the
request
object and return therequest
object from the function so that CloudFront will continue onto theorigin
rather than immediately returning aresponse
.
If you have trouble, AWS provides a similar example for modifying the request headers and includes links to more information.
Additionally, you will need to manually add the new header to the Origin Request Policy since AllViewer
cannot be used for a Lambda origin
because it forwards the wrong header as indicated by @carlos-garces in this thread.
With the Cloudfront Function in place, modify your Lambda function to parse the new header.
Lambda@Edge
example:
const hostHeader = event.Records[0].cf.request.headers['viewer-host'][0].value
Lambda origin
URL example:
const hostHeader = event.headers['viewer-host']
One drawback is that your CloudFront Distribution will always run a CloudFront Function regardless of origin
caching, and your desired origin Lambda will incur an additional Lambda invocation count, but only when reaching the origin
.
With 2,000,000 free CloudFront Function invocations per month, there is a buffer until incurring an added cost. Depending on your use case, it may fit within the free tier.
Upvotes: 1
Reputation: 833
The key is the host http header You need to use " https://xxxxxxxx.lambda-url.eu-central-1.on.aws/." as host header otherwise will not work. Please check this anwser.
https://stackoverflow.com/a/73364712
Upvotes: -1