3
votes

I have a website distributed with CloudFront, with S3 as an origin. I've written a Lambda function that takes a contact form submission and sends the email along with SES. The Lambda test out just fine : )

But, I'm clueless when it comes to routing POST requests from CloudFront to that backend Lambda function. How do I do this?

Update: Okay, I've got the API Gateway test triggering the Lambda function just fine, but I can't seem to call it from CloudFront (or rather using a curl command to my domain set up with CloudFront).

Do I need to list my domain as a custom domain in API Gateway?

If I list the path /api/* in my CloudFront Behaviors, do I have to mirror that in my API Gateway set up? So, does my API Gateway need to start with /api before I add specific resources?

Update 2 I think I needed to leave or remove the /dev off the end of the API Gateway URL. dev being my stage.

Update 3 Okay, it feels one step away now. I've got everything hooked up. The test request hits cloudfront, it forwards to api gateway, gateway calls lambda (at this point I'm shaking my head at how complicated we've made all this), and lambda sends back success or failure to api gateway, and we're peachy. Except, I get MethodNotAllowed when I do it from curl or the browser. Do I need to add an IAM role to CloudFront to access API Gateway?

Update 4 Still not working. And now, I'm back to getting my usual 404 error page that my Default Origin (S3). Seems like serverless is a fading dream.

Update 5 Trying a different approach, recommended here: https://serverfault.com/a/839368 The idea is to use API Gateway's Custom Domain name features with a subdomain like api.example.com and then use a Route53 Alias record to direct subdomain traffic to API Gateway. This could work. Then CloudFront would handle traffic to example.com and www.example.com, and API Gateway would get requests to api.example.com. Now the challenging bit is that in HTML forms the action attribute will have to go to a different subdomain. Let's see what kinds of errors and crazy behavior we get : (

3
Yes I believe your API paths in API Gateway will need to be prefixed with /apiMark B
@MarkB, still not working, but almost there. When I send a POST request via curl in the terminal, I still get the 404 from my S3 origin. The precedence in CloudFront seems right. Not sure what's up.Costa Michailidis
Okay, so now it's API Gateway that responds in to my curl request, but it says 'Method Not Allowed on that Resource'. Note for people who get this far, you have to leave off the leading / in your path pattern in CloudFront Behaviors.Costa Michailidis
I wish I could just skip API Gateway!!! Ugghghghgh : (Costa Michailidis

3 Answers

1
votes

First you would setup API Gateway in front of your Lambda function so it can be called via a POST request. It sounds like you may already have that part done?

Then if you want the POST to go through CloudFront you would add a second origin in CloudFront that points to your API Gateway.

2
votes

This is all possible, but its tricky to configure. To help I created an open-source boilerplate app that correctly sets up:

  • A static site with CloudFront and S3
  • An API with API Gateway and Lambda
  • CORS between the static site and API
  • Optional OAuth 2.0 and JWT cookie for the static site

See this static JavaScript app for an example of a static site POSTing to an API backed by Lambda.

0
votes

Depends on what you're using as your backend (which language, framework, etc.), there are different ways, but 'em all about one thing: Invoke

Kind-of the most generic call - HTTP is right there, the API call examples by language are referenced at the end of the doc.