AWS Partner Miami Fort Lauderdale South Florida

Building Resilient and Scalable
Apps Using AWS Lambda

 

To building resilient and scalable apps using AWS Lambda, organizations are turning to microservices architectures. These applications consist of many serverless functions that execute the business logic. Each function can be mapped to API methods and endpoints using services like Application Load Balancing and Amazon API Gateway.

Sometimes all you need is an easy way to set up HTTPS in front of your function. You might also need to implement a webhook handling program or a form validation tool that runs inside a Lambda function.

Today I am happy to announce general availability of Lambda Function Urls. This new feature allows you to add HTTPS endpoints any Lambda function, and optionally configure Cross Origin Resource Sharing headers.

You can focus on the important things while we manage configuration and monitoring of a high-availability, scalable and secure HTTPS service.

How Lambda Function URLs Work

A URL can be set up for either a new function or an existing one. Let’s look at how to create a new function that handles a webhook.

When creating a new function I make sure Enable function URL is checked in Advanced Setting.

Select the Auth type AWS_IAM, or NULL. My webhook will use custom authorization logic that is based on the signature in the HTTP headers. I will choose AuthType None. This means Lambda will not check for AWS IAM Sigv4 signatures prior to invoking my function. Instead, I will extract and validate a custom header from my function handler to authorize.

Lambda Function URLs in Action

The URL for the function is now available within a few seconds. It is also easy to find and copy the function URL in the Lambda console.

AWS Lambda URLs - Create Function

URLs can be used for creating new functions or updating existing ones. Let’s look at how to create a webhook-based function.

When creating a new function, I make sure to enable the URL for the function. Advanced Setting

Select the Auth type AWS_IAM, or NULL. My webhook uses custom authorization logic. It is not based on the signature in the HTTP headers. Lambda will not check for AWS Signatures before calling my function. Instead, I will validate and extract my function handler in order to authorize.

You can now find the URL of the function in a matter of seconds.

AWS Lambda URLs - Console URL

This is the function code that manages my Node.js webhook:

exports.handler = async (event) => {

    // (optional) fetch method and querystring
    const method = event.requestContext.http.method;
    const queryParam = event.queryStringParameters.myCustomParameter;
    console.log(`Received ${method} request with ${queryParam}`)

    // retrieve signature and payload
    const webhookSignature = event.headers.SignatureHeader;
    const webhookPayload = JSON.parse(event.body);

    try {
        validateSignature(webhookSignature); // throws if invalid signature
        handleEvent(webhookPayload); // throws if processing error
    } catch (error) {
        console.error(error)
        return {
            statusCode: 400,
            body: `Cannot process event: ${error}`,
        }
    }

    return {
        statusCode: 200, // default value
        body: JSON.stringify({
            received: true,
        }),
    };
};

This code extracts a few parameters from request headers, query strings, and body. This should be very familiar if you are familiar with the API Gateway and Application Load Balancer event structures.

After I have updated the code, I decided to test the URL of the function with an HTTP client.

Here’s an example: curl

$ curl "https://4iykoi7jk2kp5hhd5irhbdprn40yxest.lambda-url.us-west-2.on.aws/?myCustomParameter=squirrel"
    -X POST
    -H "SignatureHeader: XYZ"
    -H "Content-type: application/json"
    -d '{"type": "payment-succeeded"}'

Or with a Python script:

import json
import requests

url = "https://4iykoi7jk2kp5hhd5irhbdprn40yxest.lambda-url.us-west-2.on.aws/"
headers = {'SignatureHeader': 'XYZ', 'Content-type': 'application/json'}
payload = json.dumps({'type': 'payment-succeeded'})
querystring = {'myCustomParameter': 'squirrel'}

r = requests.post(url=url, params=querystring, data=payload, headers=headers)
print(r.json())

Do not forget to set the request’s content-type to app/json, or in your testing. Otherwise, the body will default to base64-encoded and you’ll have to decode it using the Lambda handler.

This is a webhook. The function will be able to receive requests from the external system I integrate with. You only need to give them the URL of your public function and they will start receiving events.

This use case doesn’t require any CORS configuration. In other cases where the function URL is called from the browser, I’d need to configure a few more CORS parameters such as Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Expose-Headers. These CORS parameters can be easily viewed and edited in the Lambda console, or in my IaC templates. This is how it looks in the console.

 

AWS Lambda URLs - CORS

Remember that every URL for a function is unique and mapped at a specific alias, or the $LATEST version. Multiple URLs can be defined for the same function. You can create one URL for testing the $LATEST version of development, one for each stage, or alias such as staging and production.

Support for Infrastructure as Code
With AWS CloudFormation and AWS SAM you can configure Lambda Function URLs in your IaC templates right away.

Here’s an example of how to create a Lambda function with AWS SAM and its public URL, including the mapping.

WebhookFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: webhook/
      Handler: index.handler
      Runtime: nodejs14.x
      AutoPublishAlias: live
      FunctionUrlConfig:
        AuthType: NONE
        Cors:
            AllowOrigins:
                - "https://example.com"

You can create a new URL for a Lambda function URL if you already have it in your IaC templates.

Function URL PriceFunction URLs can be included in Lambda’s request and duration pricing. Let’s say you have a Lambda function that has 128 MB memory and takes 50 ms to invoke. Five million requests are received each month. The cost of the function will be $1.00 per request and $0.53 per month. In the US East Region (N. Virginia), the total cost is $1.53 per monthly.

Function URLs vs. Amazon API gateway
Function URLs are ideal for cases where you need to implement a single function microservice that does not require API Gateway’s advanced functionality, such as request validation and throttling. When you implement webhook handlers and form validators, mobile payments processing, advertisement placing, machine learning inference, etc. This is the easiest way to invoke Lambda functions while you are developing or researching.

Amazon API Gateway provides a fully managed service that makes API creation, publishing, maintenance, monitoring, and security easy at all scales. API Gateway allows you to use capabilities such as JWT/custom authorisers, request/response validation, transformation, usage plans and built-in AWS WAF support.

Generally Available Today
Function URLs can be found in all AWS Regions that have Lambda, with the exception of AWS China Regions. Many AWS Lambda Partners, such as Datadog (Terraform), Lumigo, Pulumi and Thundra are also available for support.

I look forward to hearing from you about how this functionality is being used to simplify serverless architectures, particularly in single-function use cases that you are trying to keep it simple and cost-optimized.

 

 

About JNS

As a certified AWS partner, we deliver cloud consulting services to business in Miami and all across South Florida. From all cloud infrastructure to hybrid multi-cloud environments. Call us today to learn more on how your business can potentially benefit from the cloud.

Building Resilient and
Scalable Apps Using Lamda

 

To building resilient and scalable apps using AWS Lambda, organizations are turning to microservices architectures. These applications consist of many serverless functions that execute the business logic. Each function can be mapped to API methods and endpoints using services like Application Load Balancing and Amazon API Gateway.

Sometimes all you need is an easy way to set up HTTPS in front of your function. You might also need to implement a webhook handling program or a form validation tool that runs inside a Lambda function.

Today I am happy to announce general availability of Lambda Function Urls. This new feature allows you to add HTTPS endpoints any Lambda function, and optionally configure Cross Origin Resource Sharing headers.

You can focus on the important things while we manage configuration and monitoring of a high-availability, scalable and secure HTTPS service.

How Lambda Function URLs Work

A URL can be set up for either a new function or an existing one. Let’s look at how to create a new function that handles a webhook.

When creating a new function I make sure Enable function URL is checked in Advanced Setting.

Select the Auth type AWS_IAM, or NULL. My webhook will use custom authorization logic that is based on the signature in the HTTP headers. I will choose AuthType None. This means Lambda will not check for AWS IAM Sigv4 signatures prior to invoking my function. Instead, I will extract and validate a custom header from my function handler to authorize.

Lambda Function URLs in Action

The URL for the function is now available within a few seconds. It is also easy to find and copy the function URL in the Lambda console.

AWS Lambda URLs - Create Function

URLs can be used for creating new functions or updating existing ones. Let’s look at how to create a webhook-based function.

When creating a new function, I make sure to enable the URL for the function. Advanced Setting

Select the Auth type AWS_IAM, or NULL. My webhook uses custom authorization logic. It is not based on the signature in the HTTP headers. Lambda will not check for AWS Signatures before calling my function. Instead, I will validate and extract my function handler in order to authorize.

You can now find the URL of the function in a matter of seconds.

AWS Lambda URLs - Console URL

This is the function code that manages my Node.js webhook:

exports.handler = async (event) => {

    // (optional) fetch method and querystring
    const method = event.requestContext.http.method;
    const queryParam = event.queryStringParameters.myCustomParameter;
    console.log(`Received ${method} request with ${queryParam}`)

    // retrieve signature and payload
    const webhookSignature = event.headers.SignatureHeader;
    const webhookPayload = JSON.parse(event.body);

    try {
        validateSignature(webhookSignature); // throws if invalid signature
        handleEvent(webhookPayload); // throws if processing error
    } catch (error) {
        console.error(error)
        return {
            statusCode: 400,
            body: `Cannot process event: ${error}`,
        }
    }

    return {
        statusCode: 200, // default value
        body: JSON.stringify({
            received: true,
        }),
    };
};

This code extracts a few parameters from request headers, query strings, and body. This should be very familiar if you are familiar with the API Gateway and Application Load Balancer event structures.

After I have updated the code, I decided to test the URL of the function with an HTTP client.

Here’s an example: curl

$ curl "https://4iykoi7jk2kp5hhd5irhbdprn40yxest.lambda-url.us-west-2.on.aws/?myCustomParameter=squirrel"
    -X POST
    -H "SignatureHeader: XYZ"
    -H "Content-type: application/json"
    -d '{"type": "payment-succeeded"}'

Or with a Python script:

import json
import requests

url = "https://4iykoi7jk2kp5hhd5irhbdprn40yxest.lambda-url.us-west-2.on.aws/"
headers = {'SignatureHeader': 'XYZ', 'Content-type': 'application/json'}
payload = json.dumps({'type': 'payment-succeeded'})
querystring = {'myCustomParameter': 'squirrel'}

r = requests.post(url=url, params=querystring, data=payload, headers=headers)
print(r.json())

Do not forget to set the request’s content-type to app/json, or in your testing. Otherwise, the body will default to base64-encoded and you’ll have to decode it using the Lambda handler.

This is a webhook. The function will be able to receive requests from the external system I integrate with. You only need to give them the URL of your public function and they will start receiving events.

This use case doesn’t require any CORS configuration. In other cases where the function URL is called from the browser, I’d need to configure a few more CORS parameters such as Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Expose-Headers. These CORS parameters can be easily viewed and edited in the Lambda console, or in my IaC templates. This is how it looks in the console.

 

AWS Lambda URLs - CORS

Remember that every URL for a function is unique and mapped at a specific alias, or the $LATEST version. Multiple URLs can be defined for the same function. You can create one URL for testing the $LATEST version of development, one for each stage, or alias such as staging and production.

Support for Infrastructure as Code
With AWS CloudFormation and AWS SAM you can configure Lambda Function URLs in your IaC templates right away.

Here’s an example of how to create a Lambda function with AWS SAM and its public URL, including the mapping.

WebhookFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: webhook/
      Handler: index.handler
      Runtime: nodejs14.x
      AutoPublishAlias: live
      FunctionUrlConfig:
        AuthType: NONE
        Cors:
            AllowOrigins:
                - "https://example.com"

You can create a new URL for a Lambda function URL if you already have it in your IaC templates.

Function URL PriceFunction URLs can be included in Lambda’s request and duration pricing. Let’s say you have a Lambda function that has 128 MB memory and takes 50 ms to invoke. Five million requests are received each month. The cost of the function will be $1.00 per request and $0.53 per month. In the US East Region (N. Virginia), the total cost is $1.53 per monthly.

Function URLs vs. Amazon API gateway
Function URLs are ideal for cases where you need to implement a single function microservice that does not require API Gateway’s advanced functionality, such as request validation and throttling. When you implement webhook handlers and form validators, mobile payments processing, advertisement placing, machine learning inference, etc. This is the easiest way to invoke Lambda functions while you are developing or researching.

Amazon API Gateway provides a fully managed service that makes API creation, publishing, maintenance, monitoring, and security easy at all scales. API Gateway allows you to use capabilities such as JWT/custom authorisers, request/response validation, transformation, usage plans and built-in AWS WAF support.

Generally Available Today
Function URLs can be found in all AWS Regions that have Lambda, with the exception of AWS China Regions. Many AWS Lambda Partners, such as Datadog (Terraform), Lumigo, Pulumi and Thundra are also available for support.

I look forward to hearing from you about how this functionality is being used to simplify serverless architectures, particularly in single-function use cases that you are trying to keep it simple and cost-optimized.

 

 

About JNS

As a certified AWS partner, we deliver cloud consulting services to business in Miami and all across South Florida. From all cloud infrastructure to hybrid multi-cloud environments. Call us today to learn more on how your business can potentially benefit from the cloud.