AWS Lambda functions recently announced the launch of Lambda URLs where you can invoke the Lambda function directly with an HTTP API. You can read the announcement here.
Key take-aways
Setting up Function URL when creating a new Lambda Function
Whenever creating a new Lambda function from AWS console, under the advance section you can enable Enable function URL - new. This setup accepts other configuration parameters such as one of authentication type for the Function URL -
- AWS IAM
- NONE, making the Function URL publicly accessible.
And also you can specify if the Function URL should be Cross-origin resource sharing (CORS) so that Lambda function URL can be invoked from any domain.
This auto-generates a policy which allows the invocation of AWS Lambda function for AuthType : NONE
.
{
"Version": "2012-10-17",
"Statement": [
{
"StatementId": "FunctionURLAllowPublicAccess",
"Effect": "Allow",
"Principal": "*",
"Action": "lambda:InvokeFunctionUrl",
"Resource": "arn:aws:lambda:us-east-1:xxxxx:function:xxxx",
"Condition": {
"StringEquals": {
"lambda:FunctionUrlAuthType": "NONE"
}
}
}
]
}
The process of setting up Function URLs from AWS Console.
The same with SAM CLI is supported where we can configure the AuthType
accepting the values AWS_IAM
or NONE
, Cors
and AllowOrigins
to allow specific origins or all with AllowOrigin : *
.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
function-url-demo
Sample SAM Template for function-url-demo
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello-world/
Handler: app.lambdaHandler
Runtime: nodejs14.x
Architectures:
- x86_64
FunctionUrlConfig:
AuthType: NONE
Cors:
AllowOrigins:
- "*"
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldFunctionArn:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
Once the Lambda function is created, the boiler plate code and the Function URL is available on the console. The complete Function URLs configurations are available under the Function URL menu in Configuration tab of the Lambda function.
CORS Configuration
With Function URLs, you can allow access to any or specific domain(s). Once you enable the CORS configuration for your Lambda function URL the below settings are available.
These CORS headers with AllowOrigin
property could be configured as an array list items.
We can also configure that specific headers are allowed or exposed also as array list items.
Since the invocation of Lambda function is over HTTP endpoint, we can also ensure that only the needed HTTP method is allowed for invocation.
The invocation allows storing cookies of the credentials and also allowing the max-ages for cached requests.
How it works!?
Once the Lambda function with function URL enabled generates a invocation URL which the format -
https://<url-id>.lambda-url.<region>.on.aws
Where the url-id
is a uniquely identified ID for your Lambda function for that specific region.
The Function URL could be invoked similar to how any other REST APIs are invoked with CURL, Postman or for GET
it would work on web browser as well.
Whenever a request is done, the parameters from headers or body with different content-type are taken as inputs similar to how Proxy based API Gateway invocation.
Sample input from invoking the Function URL via Postman.
{
"version": "2.0",
"routeKey": "$default",
"rawPath": "/favicon.ico",
"rawQueryString": "",
"headers": {
"sec-fetch-mode": "no-cors",
"referer": "https://uhpwurwzubchzjsqxxxxxxxxxxx.lambda-url.us-east-1.on.aws/",
"sec-fetch-site": "same-origin",
"accept-language": "en-US,en;q=0.9",
"x-forwarded-proto": "https",
"x-forwarded-port": "443",
"x-forwarded-for": "xx.xx.xxx.xxx",
"accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
"sec-gpc": "1",
"x-amzn-trace-id": "Root=1-62531267-32fd08fb47a0f72211d92c63",
"host": "uhpwurwzubchzjsqspwroode2a0bqnbx.lambda-url.us-east-1.on.aws",
"accept-encoding": "gzip, deflate, br",
"sec-fetch-dest": "image",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.79 Safari/537.36"
},
"requestContext": {
"accountId": "anonymous",
"apiId": "uhpwurwzubchzjsqxxxxxxxxxxx",
"domainName": "uhpwurwzubchzjsqxxxxxxxxxxx.lambda-url.us-east-1.on.aws",
"domainPrefix": "uhpwurwzubchzjsqxxxxxxxxxxx",
"http": {
"method": "GET",
"path": "/favicon.ico",
"protocol": "HTTP/1.1",
"sourceIp": "xx.xx.xxx.xxx",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.79 Safari/537.36"
},
"requestId": "f2fb1ec9-5347-491d-88ea-15f90750cc01",
"routeKey": "$default",
"stage": "$default",
"time": "10/Apr/2022:17:22:47 +0000",
"timeEpoch": 1649611367689
},
"isBase64Encoded": false
}
And the Postman request is also successful which returns the response.
To understand more, you can refer to the documentation.
Common use-cases
- Service to service integrations
- Webhooks
- Lambda function serving as a mono-lambda function
Conclusion
AWS Lambda functions with Function URLs enables faster and direct invocation of Lambda function but this is not a replacement to AWS API Gateway as the functionalities in terms of Firewall features, throttling which are not supported natively on Lambda function URL.