9
votes

We have a wildcard(*) subdomain pointing to a CloudFront distribution. The origin is API Gateway.

We need to know the original Host header within API Gateway so we can route the requests.

Simply whitelisting the Host header in CloudFront returns an error when accessing the CloudFront distribution via HTTP - presumably because API Gateway needs the Host header to know which API to invoke.

If this is the case, is it possible to forward the Host header via X-Forwarded-Host from CloudFront to the API Gateway? Or... is there an alternative way to use wildcard subdomains with API Gateway?

1
If you whitelist the Host header, it should pass the Host header through to the origin as Host (i.e. not as X-Forwarded-Host). Can you post the actual error you receive? Is it just a 500 with no content, or is there a body or error message? May also be worth reviewing the Cloudwatch Logs for the API Gateway for a more detailed error message.Chris Simon
@ChrisSimon passing the original request's host header as Host: would result in the request never arriving at API Gateway, which expects a single, assigned value in Host -- so there would be no logs generated there. The question here is how to funnel multiple request host values (wildcard) through to one target, without losing track of the original hostname, by sending it as an alternate header, like X-Forwarded-Host, created automatically by CloudFront.Michael - sqlbot
@Michael-sqlbot precisely what I want (do you know if it's possible?!).Also, I can confirm that I get a 403 from CloudFront (ERROR. The request could not be satisfied. Bad request.) and that API Gateway never gets hit (and doesn't generate any logs in CloudWatch... but it does if you hit the API directly, not going via CloudFront).Lawrence Wagerfield
It is possible to do it one-off, but not wildcard, natively. I'll write a full answer later today as time permits, but your best choices are (a) individual, almost-identical distributions, one per incoming hostname, using a Custom Origin Header to add a static X-Forwarded-Host: (easy to automate, though), or (b) EC2-based proxy between CF and API-GW to copy Host: to X-Forwarded-Host: before changing Host: and sending to API-GW. I have both scenarios in my systems today.Michael - sqlbot
EC2-based proxy sounds best: the only reason we're needing to use wildcards is because CF distributions take so long to create and modify (~30 minutes), so ideally we want 1 CF distribution that we can re-use for all our live, test, dev and staging instances, which we can spin-up and tear-down without having to wait for CF to apply its changes. We thought wildcard CNAMEs in CF would solve this problem... looks like it does, just not if you're using API Gateway / Lambda as your origin :( thank you greatly for your time in answering :)Lawrence Wagerfield

1 Answers

2
votes

This isn't quite an answer to your original question, but it might be an alternative way of achieving your goals.

Firstly, sharing a CF distribution between all environments (including prod) carries risk with it - when you need to test a change to the CF configuration you will necessarily be modifying the prod CF dist with untested changes which could have significant consequences.

Secondly, while it's wonderful if you can test the whole environment at all stages in a CI/CD pipeline, it's not always possible (and CF is particularly bad for it) - so it's about finding a balance between short feedback cycles and thoroughness of testing.

The solution is usually to introduce extra stages to your pipeline, where the early stages give rapid feedback on the most common problems, and later stages give slower feedback on less frequent problems.

In your case, I'd suggest:

  1. Branch deployments do not deploy CF - tests target the API Gateway directly
  2. Master/Default deployments DO deploy CF - to a 'staging' environment - tests target the staging CF distribution
  3. Successfully tested releases to the 'staging' environment are promoted to production

By introducing the staging environment, you get rapid feedback on branch builds, but you still have the opportunity to test things behind the cache before going into prod.

If you are making changes to the CF configuration, you could make your deployment script dynamically decide to include CF in the branch deployment off some trigger (perhaps the presence of the word 'cloudfront' in the branch name - although that could be a bit 'magical' for some!) and you could test those changes on the branch before merging to master for testing in staging.