passing cloud front custom domain URL to lambda












0















I have a custom domain URL (my-custom-domain.com), and the REST API supports query and path parameters.



https://my-custom-domain.com/hello



https://my-custom-domain.com?firstparam=abc&secondparam=def



The invoked lambda has to return the response with some path/query parameters appended to the custom domain URL in json body. Basically the other resources which can be accessed.



Example:
https://my-custom-domain.com/hellofromlambda1123



https://my-custom-domain.com?firstparam=abc&secondparam=yourblogpage&pagenumber=30



An Ideal usecase is pagination, where I have to give the previous and next links. How do I pass the custom domain URL to my lambda.
I am working on node js 8



In conventional JAVA programming we can achieve this by HttpServletRequest.getRequestURL().
What is the way to get the custom Domain URL. I have enabled Headers for DefaultCacheBehavior. The host in the lambda event gives the API gateway URL. Is there a way to get the mapping of the Custom Domain inside lambda?



My Cloud Formation Template for custom domain looks like this



AWSTemplateFormatVersion: '2010-09-09'
Description: Custom domain template

Parameters:
ServiceName:
Description: Name of the Service
Type: String
DeploymentEnv:
Default: dev
Description: The environment this stack is being deployed to.
Type: String
CertificateId:
Description: SSL Certificate Id
Type: String
DomainName:
Description: Name of the custom domain
Type: String
HostedZoneId:
Description: Id of the hosted zone
Type: String

Resources:
APIDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- DomainName:
Fn::ImportValue:
!Sub "InvokeURL-${DeploymentEnv}"
Id: !Sub 'Custom-Domain-${DeploymentEnv}'
CustomOriginConfig:
OriginProtocolPolicy: https-only
OriginSSLProtocols: [TLSv1.2]
Enabled: 'true'
DefaultCacheBehavior:
AllowedMethods:
- DELETE
- GET
- HEAD
- OPTIONS
- PATCH
- POST
- PUT
DefaultTTL: 0
TargetOriginId: !Sub 'Custom-Domain-${DeploymentEnv}'
ForwardedValues:
QueryString: 'true'
Cookies:
Forward: none
Headers:
- 'Accept'
- 'api-version'
- 'Authorization'
ViewerProtocolPolicy: https-only
Aliases:
- !Sub '${DomainName}'
ViewerCertificate:
AcmCertificateArn: !Sub '${CertificateId}'
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1.2_2018
APIDNSRecord:
Type: AWS::Route53::RecordSet
DependsOn: "APIDistribution"
Properties:
HostedZoneId: !Sub '${HostedZoneId}'
Comment: DNS name for the custom distribution.
Name: !Sub '${DomainName}'
Type: A
AliasTarget:
DNSName: !GetAtt APIDistribution.DomainName
HostedZoneId: Z2FDTNDATAQYW2
EvaluateTargetHealth: false
Outputs:
DomainName:
Value: !GetAtt APIDistribution.DomainName









share|improve this question

























  • So the issue here seems to be that you are creating your own CloudFront distribution, and setting its Origin Domain Name to an API Gateway endpoint -- and, with this configuration, it is to be expected that API Gateway is not actually aware of the custom domain name. While this is a valid configuration and sometimes a desirable one, is there a specific reason you're doing it this way rather than configuring the custom domain name in API Gateway itself? The optimal solution may depend on your reasoning.

    – Michael - sqlbot
    Nov 16 '18 at 12:46













  • Yes @Michael-sqlbot the intention of having the cloud front aware is that, if we might want more than one routes for a given API Gateway, we would configure that in custom domain itself. Also, we would want to run all cloud formation using template files for automation.

    – Klose
    Nov 16 '18 at 14:43
















0















I have a custom domain URL (my-custom-domain.com), and the REST API supports query and path parameters.



https://my-custom-domain.com/hello



https://my-custom-domain.com?firstparam=abc&secondparam=def



The invoked lambda has to return the response with some path/query parameters appended to the custom domain URL in json body. Basically the other resources which can be accessed.



Example:
https://my-custom-domain.com/hellofromlambda1123



https://my-custom-domain.com?firstparam=abc&secondparam=yourblogpage&pagenumber=30



An Ideal usecase is pagination, where I have to give the previous and next links. How do I pass the custom domain URL to my lambda.
I am working on node js 8



In conventional JAVA programming we can achieve this by HttpServletRequest.getRequestURL().
What is the way to get the custom Domain URL. I have enabled Headers for DefaultCacheBehavior. The host in the lambda event gives the API gateway URL. Is there a way to get the mapping of the Custom Domain inside lambda?



My Cloud Formation Template for custom domain looks like this



AWSTemplateFormatVersion: '2010-09-09'
Description: Custom domain template

Parameters:
ServiceName:
Description: Name of the Service
Type: String
DeploymentEnv:
Default: dev
Description: The environment this stack is being deployed to.
Type: String
CertificateId:
Description: SSL Certificate Id
Type: String
DomainName:
Description: Name of the custom domain
Type: String
HostedZoneId:
Description: Id of the hosted zone
Type: String

Resources:
APIDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- DomainName:
Fn::ImportValue:
!Sub "InvokeURL-${DeploymentEnv}"
Id: !Sub 'Custom-Domain-${DeploymentEnv}'
CustomOriginConfig:
OriginProtocolPolicy: https-only
OriginSSLProtocols: [TLSv1.2]
Enabled: 'true'
DefaultCacheBehavior:
AllowedMethods:
- DELETE
- GET
- HEAD
- OPTIONS
- PATCH
- POST
- PUT
DefaultTTL: 0
TargetOriginId: !Sub 'Custom-Domain-${DeploymentEnv}'
ForwardedValues:
QueryString: 'true'
Cookies:
Forward: none
Headers:
- 'Accept'
- 'api-version'
- 'Authorization'
ViewerProtocolPolicy: https-only
Aliases:
- !Sub '${DomainName}'
ViewerCertificate:
AcmCertificateArn: !Sub '${CertificateId}'
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1.2_2018
APIDNSRecord:
Type: AWS::Route53::RecordSet
DependsOn: "APIDistribution"
Properties:
HostedZoneId: !Sub '${HostedZoneId}'
Comment: DNS name for the custom distribution.
Name: !Sub '${DomainName}'
Type: A
AliasTarget:
DNSName: !GetAtt APIDistribution.DomainName
HostedZoneId: Z2FDTNDATAQYW2
EvaluateTargetHealth: false
Outputs:
DomainName:
Value: !GetAtt APIDistribution.DomainName









share|improve this question

























  • So the issue here seems to be that you are creating your own CloudFront distribution, and setting its Origin Domain Name to an API Gateway endpoint -- and, with this configuration, it is to be expected that API Gateway is not actually aware of the custom domain name. While this is a valid configuration and sometimes a desirable one, is there a specific reason you're doing it this way rather than configuring the custom domain name in API Gateway itself? The optimal solution may depend on your reasoning.

    – Michael - sqlbot
    Nov 16 '18 at 12:46













  • Yes @Michael-sqlbot the intention of having the cloud front aware is that, if we might want more than one routes for a given API Gateway, we would configure that in custom domain itself. Also, we would want to run all cloud formation using template files for automation.

    – Klose
    Nov 16 '18 at 14:43














0












0








0








I have a custom domain URL (my-custom-domain.com), and the REST API supports query and path parameters.



https://my-custom-domain.com/hello



https://my-custom-domain.com?firstparam=abc&secondparam=def



The invoked lambda has to return the response with some path/query parameters appended to the custom domain URL in json body. Basically the other resources which can be accessed.



Example:
https://my-custom-domain.com/hellofromlambda1123



https://my-custom-domain.com?firstparam=abc&secondparam=yourblogpage&pagenumber=30



An Ideal usecase is pagination, where I have to give the previous and next links. How do I pass the custom domain URL to my lambda.
I am working on node js 8



In conventional JAVA programming we can achieve this by HttpServletRequest.getRequestURL().
What is the way to get the custom Domain URL. I have enabled Headers for DefaultCacheBehavior. The host in the lambda event gives the API gateway URL. Is there a way to get the mapping of the Custom Domain inside lambda?



My Cloud Formation Template for custom domain looks like this



AWSTemplateFormatVersion: '2010-09-09'
Description: Custom domain template

Parameters:
ServiceName:
Description: Name of the Service
Type: String
DeploymentEnv:
Default: dev
Description: The environment this stack is being deployed to.
Type: String
CertificateId:
Description: SSL Certificate Id
Type: String
DomainName:
Description: Name of the custom domain
Type: String
HostedZoneId:
Description: Id of the hosted zone
Type: String

Resources:
APIDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- DomainName:
Fn::ImportValue:
!Sub "InvokeURL-${DeploymentEnv}"
Id: !Sub 'Custom-Domain-${DeploymentEnv}'
CustomOriginConfig:
OriginProtocolPolicy: https-only
OriginSSLProtocols: [TLSv1.2]
Enabled: 'true'
DefaultCacheBehavior:
AllowedMethods:
- DELETE
- GET
- HEAD
- OPTIONS
- PATCH
- POST
- PUT
DefaultTTL: 0
TargetOriginId: !Sub 'Custom-Domain-${DeploymentEnv}'
ForwardedValues:
QueryString: 'true'
Cookies:
Forward: none
Headers:
- 'Accept'
- 'api-version'
- 'Authorization'
ViewerProtocolPolicy: https-only
Aliases:
- !Sub '${DomainName}'
ViewerCertificate:
AcmCertificateArn: !Sub '${CertificateId}'
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1.2_2018
APIDNSRecord:
Type: AWS::Route53::RecordSet
DependsOn: "APIDistribution"
Properties:
HostedZoneId: !Sub '${HostedZoneId}'
Comment: DNS name for the custom distribution.
Name: !Sub '${DomainName}'
Type: A
AliasTarget:
DNSName: !GetAtt APIDistribution.DomainName
HostedZoneId: Z2FDTNDATAQYW2
EvaluateTargetHealth: false
Outputs:
DomainName:
Value: !GetAtt APIDistribution.DomainName









share|improve this question
















I have a custom domain URL (my-custom-domain.com), and the REST API supports query and path parameters.



https://my-custom-domain.com/hello



https://my-custom-domain.com?firstparam=abc&secondparam=def



The invoked lambda has to return the response with some path/query parameters appended to the custom domain URL in json body. Basically the other resources which can be accessed.



Example:
https://my-custom-domain.com/hellofromlambda1123



https://my-custom-domain.com?firstparam=abc&secondparam=yourblogpage&pagenumber=30



An Ideal usecase is pagination, where I have to give the previous and next links. How do I pass the custom domain URL to my lambda.
I am working on node js 8



In conventional JAVA programming we can achieve this by HttpServletRequest.getRequestURL().
What is the way to get the custom Domain URL. I have enabled Headers for DefaultCacheBehavior. The host in the lambda event gives the API gateway URL. Is there a way to get the mapping of the Custom Domain inside lambda?



My Cloud Formation Template for custom domain looks like this



AWSTemplateFormatVersion: '2010-09-09'
Description: Custom domain template

Parameters:
ServiceName:
Description: Name of the Service
Type: String
DeploymentEnv:
Default: dev
Description: The environment this stack is being deployed to.
Type: String
CertificateId:
Description: SSL Certificate Id
Type: String
DomainName:
Description: Name of the custom domain
Type: String
HostedZoneId:
Description: Id of the hosted zone
Type: String

Resources:
APIDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- DomainName:
Fn::ImportValue:
!Sub "InvokeURL-${DeploymentEnv}"
Id: !Sub 'Custom-Domain-${DeploymentEnv}'
CustomOriginConfig:
OriginProtocolPolicy: https-only
OriginSSLProtocols: [TLSv1.2]
Enabled: 'true'
DefaultCacheBehavior:
AllowedMethods:
- DELETE
- GET
- HEAD
- OPTIONS
- PATCH
- POST
- PUT
DefaultTTL: 0
TargetOriginId: !Sub 'Custom-Domain-${DeploymentEnv}'
ForwardedValues:
QueryString: 'true'
Cookies:
Forward: none
Headers:
- 'Accept'
- 'api-version'
- 'Authorization'
ViewerProtocolPolicy: https-only
Aliases:
- !Sub '${DomainName}'
ViewerCertificate:
AcmCertificateArn: !Sub '${CertificateId}'
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1.2_2018
APIDNSRecord:
Type: AWS::Route53::RecordSet
DependsOn: "APIDistribution"
Properties:
HostedZoneId: !Sub '${HostedZoneId}'
Comment: DNS name for the custom distribution.
Name: !Sub '${DomainName}'
Type: A
AliasTarget:
DNSName: !GetAtt APIDistribution.DomainName
HostedZoneId: Z2FDTNDATAQYW2
EvaluateTargetHealth: false
Outputs:
DomainName:
Value: !GetAtt APIDistribution.DomainName






node.js aws-lambda aws-api-gateway aws-cloudfront






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 16 '18 at 12:10







Klose

















asked Nov 16 '18 at 6:58









KloseKlose

135




135













  • So the issue here seems to be that you are creating your own CloudFront distribution, and setting its Origin Domain Name to an API Gateway endpoint -- and, with this configuration, it is to be expected that API Gateway is not actually aware of the custom domain name. While this is a valid configuration and sometimes a desirable one, is there a specific reason you're doing it this way rather than configuring the custom domain name in API Gateway itself? The optimal solution may depend on your reasoning.

    – Michael - sqlbot
    Nov 16 '18 at 12:46













  • Yes @Michael-sqlbot the intention of having the cloud front aware is that, if we might want more than one routes for a given API Gateway, we would configure that in custom domain itself. Also, we would want to run all cloud formation using template files for automation.

    – Klose
    Nov 16 '18 at 14:43



















  • So the issue here seems to be that you are creating your own CloudFront distribution, and setting its Origin Domain Name to an API Gateway endpoint -- and, with this configuration, it is to be expected that API Gateway is not actually aware of the custom domain name. While this is a valid configuration and sometimes a desirable one, is there a specific reason you're doing it this way rather than configuring the custom domain name in API Gateway itself? The optimal solution may depend on your reasoning.

    – Michael - sqlbot
    Nov 16 '18 at 12:46













  • Yes @Michael-sqlbot the intention of having the cloud front aware is that, if we might want more than one routes for a given API Gateway, we would configure that in custom domain itself. Also, we would want to run all cloud formation using template files for automation.

    – Klose
    Nov 16 '18 at 14:43

















So the issue here seems to be that you are creating your own CloudFront distribution, and setting its Origin Domain Name to an API Gateway endpoint -- and, with this configuration, it is to be expected that API Gateway is not actually aware of the custom domain name. While this is a valid configuration and sometimes a desirable one, is there a specific reason you're doing it this way rather than configuring the custom domain name in API Gateway itself? The optimal solution may depend on your reasoning.

– Michael - sqlbot
Nov 16 '18 at 12:46







So the issue here seems to be that you are creating your own CloudFront distribution, and setting its Origin Domain Name to an API Gateway endpoint -- and, with this configuration, it is to be expected that API Gateway is not actually aware of the custom domain name. While this is a valid configuration and sometimes a desirable one, is there a specific reason you're doing it this way rather than configuring the custom domain name in API Gateway itself? The optimal solution may depend on your reasoning.

– Michael - sqlbot
Nov 16 '18 at 12:46















Yes @Michael-sqlbot the intention of having the cloud front aware is that, if we might want more than one routes for a given API Gateway, we would configure that in custom domain itself. Also, we would want to run all cloud formation using template files for automation.

– Klose
Nov 16 '18 at 14:43





Yes @Michael-sqlbot the intention of having the cloud front aware is that, if we might want more than one routes for a given API Gateway, we would configure that in custom domain itself. Also, we would want to run all cloud formation using template files for automation.

– Klose
Nov 16 '18 at 14:43












2 Answers
2






active

oldest

votes


















0














Thanks to @thomasmichaelwallace for pointing to my post on the AWS Forum that explains a way to inject the original request Host header into an alternate request header, using a Lambda@Edge Origin Request trigger. That is one solution, but requires the Lambda trigger, so there is additional overhead and cost. That solution was really about a CloudFront distribution that handles multiple domain names, but needs to send a single Host header to the back-end application while alerting the application of another request header, which I arbitrarily called X-Forwarded-Host.



There are alternatives.



If the CloudFront distribution is only handling one incoming hostname, you could simply configure a static custom origin header. These are injected unconditionally into requests by CloudFront (and if the original requester sets such a header, it is dropped before the configured header is injected). Set X-Forwarded-Host: api.example.com and it will be injected into all requests and visible at API Gateway.



That is the simplest solution and based on what's in the question, it should work.



But the intuitive solution does not work -- you can't simply whitelist the Host header for forwarding to the origin, because that isn't what API Gateway is expecting.



But there should be a way to make it expect that header.



The following is based on a number of observations that are accurate, independently, but I have not tested them all together. Here's the idea:




  • use a Regional API Gateway deployment, not Edge-Optimized. You don't want an edge-optimized deployment anyway when you are using your own CloudFront distribution because this increases latency by sending the request through the CloudFront network redundantly. It also won't work in this setup.

  • configure your API as a custom domain (for your exposed domain)

  • attaching the appropriate certificate to API Gateway, but

  • do, not point DNS to the assigned regional domain name API Gateway gives you; instead,

  • use the assigned regional endpoint hostname as the Origin Domain Name in CloudFront

  • whitelist the Host header for forwarding


This should work because it will cause API Gateway to expect the original Host header, coupled with the way CloudFront handles TLS on the back-end when the Host header is whitelisted for forwarding.






share|improve this answer
























  • Thanks I achieved it using custom origin header.

    – Klose
    Nov 21 '18 at 6:52



















0














When using API Gateway + Lambda with the Lambda Proxy integration the event the lambda receives includes the headers.Host and headers.X-Forwarded-Proto keys which can be concatenated to build the full request url.



For example for https://my-custom-domain.com/hellofromlambda1123



{
"headers": {
"Host": "my-custom-domain.com"
"X-Forwarded-Proto": "https"
}
}





share|improve this answer
























  • Hi the "HOST" property has the API Gateway URL. But I need the Custom Domain URL. Is there a way to find the Custom Domain URL using the API Gateway URL?

    – Klose
    Nov 16 '18 at 9:47













  • Have you checked that? We use base path mapping to get a custom domain url and Host is the correct domain...

    – thomasmichaelwallace
    Nov 16 '18 at 9:48











  • Yes I have :) The "host" is the API Gateway URL. The custom Domain URL generated in the AWS CloudFront is not coming in "host" :(

    – Klose
    Nov 16 '18 at 9:57











  • How are you providing your domain- are you using API gateway's basePathMapping?

    – thomasmichaelwallace
    Nov 16 '18 at 10:11











  • I am using cloud formation template. From my API Gateway lambda I export the invoke url, and map it under cloudFront's cloud formation template under AWS::CloudFront::Distribution. Added the template in the question above.

    – Klose
    Nov 16 '18 at 12:07














Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53332884%2fpassing-cloud-front-custom-domain-url-to-lambda%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














Thanks to @thomasmichaelwallace for pointing to my post on the AWS Forum that explains a way to inject the original request Host header into an alternate request header, using a Lambda@Edge Origin Request trigger. That is one solution, but requires the Lambda trigger, so there is additional overhead and cost. That solution was really about a CloudFront distribution that handles multiple domain names, but needs to send a single Host header to the back-end application while alerting the application of another request header, which I arbitrarily called X-Forwarded-Host.



There are alternatives.



If the CloudFront distribution is only handling one incoming hostname, you could simply configure a static custom origin header. These are injected unconditionally into requests by CloudFront (and if the original requester sets such a header, it is dropped before the configured header is injected). Set X-Forwarded-Host: api.example.com and it will be injected into all requests and visible at API Gateway.



That is the simplest solution and based on what's in the question, it should work.



But the intuitive solution does not work -- you can't simply whitelist the Host header for forwarding to the origin, because that isn't what API Gateway is expecting.



But there should be a way to make it expect that header.



The following is based on a number of observations that are accurate, independently, but I have not tested them all together. Here's the idea:




  • use a Regional API Gateway deployment, not Edge-Optimized. You don't want an edge-optimized deployment anyway when you are using your own CloudFront distribution because this increases latency by sending the request through the CloudFront network redundantly. It also won't work in this setup.

  • configure your API as a custom domain (for your exposed domain)

  • attaching the appropriate certificate to API Gateway, but

  • do, not point DNS to the assigned regional domain name API Gateway gives you; instead,

  • use the assigned regional endpoint hostname as the Origin Domain Name in CloudFront

  • whitelist the Host header for forwarding


This should work because it will cause API Gateway to expect the original Host header, coupled with the way CloudFront handles TLS on the back-end when the Host header is whitelisted for forwarding.






share|improve this answer
























  • Thanks I achieved it using custom origin header.

    – Klose
    Nov 21 '18 at 6:52
















0














Thanks to @thomasmichaelwallace for pointing to my post on the AWS Forum that explains a way to inject the original request Host header into an alternate request header, using a Lambda@Edge Origin Request trigger. That is one solution, but requires the Lambda trigger, so there is additional overhead and cost. That solution was really about a CloudFront distribution that handles multiple domain names, but needs to send a single Host header to the back-end application while alerting the application of another request header, which I arbitrarily called X-Forwarded-Host.



There are alternatives.



If the CloudFront distribution is only handling one incoming hostname, you could simply configure a static custom origin header. These are injected unconditionally into requests by CloudFront (and if the original requester sets such a header, it is dropped before the configured header is injected). Set X-Forwarded-Host: api.example.com and it will be injected into all requests and visible at API Gateway.



That is the simplest solution and based on what's in the question, it should work.



But the intuitive solution does not work -- you can't simply whitelist the Host header for forwarding to the origin, because that isn't what API Gateway is expecting.



But there should be a way to make it expect that header.



The following is based on a number of observations that are accurate, independently, but I have not tested them all together. Here's the idea:




  • use a Regional API Gateway deployment, not Edge-Optimized. You don't want an edge-optimized deployment anyway when you are using your own CloudFront distribution because this increases latency by sending the request through the CloudFront network redundantly. It also won't work in this setup.

  • configure your API as a custom domain (for your exposed domain)

  • attaching the appropriate certificate to API Gateway, but

  • do, not point DNS to the assigned regional domain name API Gateway gives you; instead,

  • use the assigned regional endpoint hostname as the Origin Domain Name in CloudFront

  • whitelist the Host header for forwarding


This should work because it will cause API Gateway to expect the original Host header, coupled with the way CloudFront handles TLS on the back-end when the Host header is whitelisted for forwarding.






share|improve this answer
























  • Thanks I achieved it using custom origin header.

    – Klose
    Nov 21 '18 at 6:52














0












0








0







Thanks to @thomasmichaelwallace for pointing to my post on the AWS Forum that explains a way to inject the original request Host header into an alternate request header, using a Lambda@Edge Origin Request trigger. That is one solution, but requires the Lambda trigger, so there is additional overhead and cost. That solution was really about a CloudFront distribution that handles multiple domain names, but needs to send a single Host header to the back-end application while alerting the application of another request header, which I arbitrarily called X-Forwarded-Host.



There are alternatives.



If the CloudFront distribution is only handling one incoming hostname, you could simply configure a static custom origin header. These are injected unconditionally into requests by CloudFront (and if the original requester sets such a header, it is dropped before the configured header is injected). Set X-Forwarded-Host: api.example.com and it will be injected into all requests and visible at API Gateway.



That is the simplest solution and based on what's in the question, it should work.



But the intuitive solution does not work -- you can't simply whitelist the Host header for forwarding to the origin, because that isn't what API Gateway is expecting.



But there should be a way to make it expect that header.



The following is based on a number of observations that are accurate, independently, but I have not tested them all together. Here's the idea:




  • use a Regional API Gateway deployment, not Edge-Optimized. You don't want an edge-optimized deployment anyway when you are using your own CloudFront distribution because this increases latency by sending the request through the CloudFront network redundantly. It also won't work in this setup.

  • configure your API as a custom domain (for your exposed domain)

  • attaching the appropriate certificate to API Gateway, but

  • do, not point DNS to the assigned regional domain name API Gateway gives you; instead,

  • use the assigned regional endpoint hostname as the Origin Domain Name in CloudFront

  • whitelist the Host header for forwarding


This should work because it will cause API Gateway to expect the original Host header, coupled with the way CloudFront handles TLS on the back-end when the Host header is whitelisted for forwarding.






share|improve this answer













Thanks to @thomasmichaelwallace for pointing to my post on the AWS Forum that explains a way to inject the original request Host header into an alternate request header, using a Lambda@Edge Origin Request trigger. That is one solution, but requires the Lambda trigger, so there is additional overhead and cost. That solution was really about a CloudFront distribution that handles multiple domain names, but needs to send a single Host header to the back-end application while alerting the application of another request header, which I arbitrarily called X-Forwarded-Host.



There are alternatives.



If the CloudFront distribution is only handling one incoming hostname, you could simply configure a static custom origin header. These are injected unconditionally into requests by CloudFront (and if the original requester sets such a header, it is dropped before the configured header is injected). Set X-Forwarded-Host: api.example.com and it will be injected into all requests and visible at API Gateway.



That is the simplest solution and based on what's in the question, it should work.



But the intuitive solution does not work -- you can't simply whitelist the Host header for forwarding to the origin, because that isn't what API Gateway is expecting.



But there should be a way to make it expect that header.



The following is based on a number of observations that are accurate, independently, but I have not tested them all together. Here's the idea:




  • use a Regional API Gateway deployment, not Edge-Optimized. You don't want an edge-optimized deployment anyway when you are using your own CloudFront distribution because this increases latency by sending the request through the CloudFront network redundantly. It also won't work in this setup.

  • configure your API as a custom domain (for your exposed domain)

  • attaching the appropriate certificate to API Gateway, but

  • do, not point DNS to the assigned regional domain name API Gateway gives you; instead,

  • use the assigned regional endpoint hostname as the Origin Domain Name in CloudFront

  • whitelist the Host header for forwarding


This should work because it will cause API Gateway to expect the original Host header, coupled with the way CloudFront handles TLS on the back-end when the Host header is whitelisted for forwarding.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 16 '18 at 17:55









Michael - sqlbotMichael - sqlbot

95.1k13141207




95.1k13141207













  • Thanks I achieved it using custom origin header.

    – Klose
    Nov 21 '18 at 6:52



















  • Thanks I achieved it using custom origin header.

    – Klose
    Nov 21 '18 at 6:52

















Thanks I achieved it using custom origin header.

– Klose
Nov 21 '18 at 6:52





Thanks I achieved it using custom origin header.

– Klose
Nov 21 '18 at 6:52













0














When using API Gateway + Lambda with the Lambda Proxy integration the event the lambda receives includes the headers.Host and headers.X-Forwarded-Proto keys which can be concatenated to build the full request url.



For example for https://my-custom-domain.com/hellofromlambda1123



{
"headers": {
"Host": "my-custom-domain.com"
"X-Forwarded-Proto": "https"
}
}





share|improve this answer
























  • Hi the "HOST" property has the API Gateway URL. But I need the Custom Domain URL. Is there a way to find the Custom Domain URL using the API Gateway URL?

    – Klose
    Nov 16 '18 at 9:47













  • Have you checked that? We use base path mapping to get a custom domain url and Host is the correct domain...

    – thomasmichaelwallace
    Nov 16 '18 at 9:48











  • Yes I have :) The "host" is the API Gateway URL. The custom Domain URL generated in the AWS CloudFront is not coming in "host" :(

    – Klose
    Nov 16 '18 at 9:57











  • How are you providing your domain- are you using API gateway's basePathMapping?

    – thomasmichaelwallace
    Nov 16 '18 at 10:11











  • I am using cloud formation template. From my API Gateway lambda I export the invoke url, and map it under cloudFront's cloud formation template under AWS::CloudFront::Distribution. Added the template in the question above.

    – Klose
    Nov 16 '18 at 12:07


















0














When using API Gateway + Lambda with the Lambda Proxy integration the event the lambda receives includes the headers.Host and headers.X-Forwarded-Proto keys which can be concatenated to build the full request url.



For example for https://my-custom-domain.com/hellofromlambda1123



{
"headers": {
"Host": "my-custom-domain.com"
"X-Forwarded-Proto": "https"
}
}





share|improve this answer
























  • Hi the "HOST" property has the API Gateway URL. But I need the Custom Domain URL. Is there a way to find the Custom Domain URL using the API Gateway URL?

    – Klose
    Nov 16 '18 at 9:47













  • Have you checked that? We use base path mapping to get a custom domain url and Host is the correct domain...

    – thomasmichaelwallace
    Nov 16 '18 at 9:48











  • Yes I have :) The "host" is the API Gateway URL. The custom Domain URL generated in the AWS CloudFront is not coming in "host" :(

    – Klose
    Nov 16 '18 at 9:57











  • How are you providing your domain- are you using API gateway's basePathMapping?

    – thomasmichaelwallace
    Nov 16 '18 at 10:11











  • I am using cloud formation template. From my API Gateway lambda I export the invoke url, and map it under cloudFront's cloud formation template under AWS::CloudFront::Distribution. Added the template in the question above.

    – Klose
    Nov 16 '18 at 12:07
















0












0








0







When using API Gateway + Lambda with the Lambda Proxy integration the event the lambda receives includes the headers.Host and headers.X-Forwarded-Proto keys which can be concatenated to build the full request url.



For example for https://my-custom-domain.com/hellofromlambda1123



{
"headers": {
"Host": "my-custom-domain.com"
"X-Forwarded-Proto": "https"
}
}





share|improve this answer













When using API Gateway + Lambda with the Lambda Proxy integration the event the lambda receives includes the headers.Host and headers.X-Forwarded-Proto keys which can be concatenated to build the full request url.



For example for https://my-custom-domain.com/hellofromlambda1123



{
"headers": {
"Host": "my-custom-domain.com"
"X-Forwarded-Proto": "https"
}
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 16 '18 at 9:15









thomasmichaelwallacethomasmichaelwallace

2,7901919




2,7901919













  • Hi the "HOST" property has the API Gateway URL. But I need the Custom Domain URL. Is there a way to find the Custom Domain URL using the API Gateway URL?

    – Klose
    Nov 16 '18 at 9:47













  • Have you checked that? We use base path mapping to get a custom domain url and Host is the correct domain...

    – thomasmichaelwallace
    Nov 16 '18 at 9:48











  • Yes I have :) The "host" is the API Gateway URL. The custom Domain URL generated in the AWS CloudFront is not coming in "host" :(

    – Klose
    Nov 16 '18 at 9:57











  • How are you providing your domain- are you using API gateway's basePathMapping?

    – thomasmichaelwallace
    Nov 16 '18 at 10:11











  • I am using cloud formation template. From my API Gateway lambda I export the invoke url, and map it under cloudFront's cloud formation template under AWS::CloudFront::Distribution. Added the template in the question above.

    – Klose
    Nov 16 '18 at 12:07





















  • Hi the "HOST" property has the API Gateway URL. But I need the Custom Domain URL. Is there a way to find the Custom Domain URL using the API Gateway URL?

    – Klose
    Nov 16 '18 at 9:47













  • Have you checked that? We use base path mapping to get a custom domain url and Host is the correct domain...

    – thomasmichaelwallace
    Nov 16 '18 at 9:48











  • Yes I have :) The "host" is the API Gateway URL. The custom Domain URL generated in the AWS CloudFront is not coming in "host" :(

    – Klose
    Nov 16 '18 at 9:57











  • How are you providing your domain- are you using API gateway's basePathMapping?

    – thomasmichaelwallace
    Nov 16 '18 at 10:11











  • I am using cloud formation template. From my API Gateway lambda I export the invoke url, and map it under cloudFront's cloud formation template under AWS::CloudFront::Distribution. Added the template in the question above.

    – Klose
    Nov 16 '18 at 12:07



















Hi the "HOST" property has the API Gateway URL. But I need the Custom Domain URL. Is there a way to find the Custom Domain URL using the API Gateway URL?

– Klose
Nov 16 '18 at 9:47







Hi the "HOST" property has the API Gateway URL. But I need the Custom Domain URL. Is there a way to find the Custom Domain URL using the API Gateway URL?

– Klose
Nov 16 '18 at 9:47















Have you checked that? We use base path mapping to get a custom domain url and Host is the correct domain...

– thomasmichaelwallace
Nov 16 '18 at 9:48





Have you checked that? We use base path mapping to get a custom domain url and Host is the correct domain...

– thomasmichaelwallace
Nov 16 '18 at 9:48













Yes I have :) The "host" is the API Gateway URL. The custom Domain URL generated in the AWS CloudFront is not coming in "host" :(

– Klose
Nov 16 '18 at 9:57





Yes I have :) The "host" is the API Gateway URL. The custom Domain URL generated in the AWS CloudFront is not coming in "host" :(

– Klose
Nov 16 '18 at 9:57













How are you providing your domain- are you using API gateway's basePathMapping?

– thomasmichaelwallace
Nov 16 '18 at 10:11





How are you providing your domain- are you using API gateway's basePathMapping?

– thomasmichaelwallace
Nov 16 '18 at 10:11













I am using cloud formation template. From my API Gateway lambda I export the invoke url, and map it under cloudFront's cloud formation template under AWS::CloudFront::Distribution. Added the template in the question above.

– Klose
Nov 16 '18 at 12:07







I am using cloud formation template. From my API Gateway lambda I export the invoke url, and map it under cloudFront's cloud formation template under AWS::CloudFront::Distribution. Added the template in the question above.

– Klose
Nov 16 '18 at 12:07




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53332884%2fpassing-cloud-front-custom-domain-url-to-lambda%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Florida Star v. B. J. F.

Danny Elfman

Lugert, Oklahoma