AWS Lambda Function URLs
A quick look at how to add a HTTPS endpoint to your Lambda Functions without API Gateway using AWS Lambda Function URLs and some extra tips for managing them.
AWS Lambda functions allow you to build applications without the need to worry about provisioning servers, simply write your code and off you go.
Now firstly, I’m not a developer so I won’t be going to deep from a code side here but even I have made the odd AWS Lambda function to trigger something or respond with some data (especially when I’ve been working with AWS Connect).
Now let’s say you wanted to create a function just to respond to a simple web request. Previously to do this you would either:
- Setup and API with Amazon API Gateway which would route the HTTP request to the Lambda function, or
- You could setup an Application Load Balancer to route the HTTP request to a function.
Both methods provide a lot of functionality but sometimes (and especially for some of my uses cases) just mean extra layers and extra configuration, as well as extra cost.
Introducing AWS Lambda Function URLs. This newly released feature (6th April 2022) provides your Lambda function a dedicated HTTPS endpoint.
Let’s take a look.
I’m going to start with a super simple hello world function.
This will simple reply “Hello from Lambda!” when we call the function.
Now let’s get a Function URL for this Lambda function.
In your Lambda functions console, Select Configuration, then on the left tabs select Function URL, then click Create function URL.
This will bring us to the Configure Function URL page which provides us some options for security.
Currently we have two main authentication options, AWS_IAM and NONE.
Basically this boils down to use IAM to control who can make requests to your function URL or implement your own authentication/authorisation process in your function.
On top of Auth type, you can also configure a Cross-Origin Resource Sharing (CORS) policy for your function, this allows you to control what domains can access your function and control headers and methods.
For this demo however I’m going to ignore security and make my function completely public to the world. Now obviously this may not be a smart thing depending on your use case.
Underneath, Lambda is using resource-based policies to control these actions, when you set the auth type to none, the following resource-based policy permissions are applied to the function.
{
"Version": "2012-10-17",
"Statement": [
{
"StatementId": "FunctionURLAllowPublicAccess",
"Effect": "Allow",
"Principal": "*",
"Action": "lambda:InvokeFunctionUrl",
"Resource": "arn:aws:lambda:ap-southeast-2:1*******1:function:LambdaFunctionURL",
"Condition": {
"StringEquals": {
"lambda:FunctionUrlAuthType": "NONE"
}
}
}
]
}
As we can see from this policy, we are:
- allowing (Effect: Allow)
- anyone (Principal:*)
- to invoke (Action: lambda:InvokeFunctionURL)
- the function (Resource: arn:aws:lambda:ap-southeast-2:1*******1:function:LambdaFunctionURL)
- with no auth type (lambda:FunctionUrlAuthType: NONE).
Function URL’s are created in the following format: https://url-id.lambda-url.region.on.aws
Now if we take this URL and put it on our browser we get:
Awesome, Lambda Function URL’s let you simply enable any function with a HTTPS endpoint quickly.
Some other helpful information
Now while playing around with this new functionality there where a few things I thought that might be good to bring up.
The URL
According to the documentation, the Lambda URL is generated using a number of factors, including your AWS Account ID. As AWS states this process is deterministic, it may be possible for anyone to figure out your account ID from the URL.
Throttling
It is possible to throttle the processing rate of the function and while this won’t be as comprehensive as API Gateway, it may do the trick for smaller things. To throttle the function you just need to configure reserved concurrency for the function.
Your functions maximum request rate (per second) is 10x the configured reserved concurrency. So, in this example where I have set it to 1, this means our maximum requests per second is 10.
When your function clamps down the function will respond with a HTTP 429 code and look something like this
Let say you having an issue or getting attacked and you want to reject everything getting sent at the function, just set the reserve concurrency to 0.
Controlling the use of Functional URLs
Now you may be thinking, Hey! these are cool but no thanks, or Hey! There’s no way I want non AWS authenticated functions.
Service Control Policy’s (SCP) are a great way to handle this across an entire AWS Organisation.
Here are some sample policies that can help:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action":[
"lambda:CreateFunctionUrlConfig",
"lambda:UpdateFunctionUrlConfig"
],
"Resource": "arn:aws:lambda:*:*:function:*",
"Condition": {
"StringNotEquals": {
"lambda:FunctionUrlAuthType": "AWS_IAM"
}
}
}
]
}
This SCP policy will deny users from updating or creating a functional URL that doesn’t use AWS_IAM authentication. It will however let you delete them.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action":[
"lambda:CreateFunctionUrlConfig",
"lambda:UpdateFunctionUrlConfig"
],
"Resource": "arn:aws:lambda:*:*:function:*"
}
]
}
This SCP policy will just outright deny users from using functional URLs. It will however still allow you to delete them.
Alias
You can also create Function URLs for Lambda function Alias’s as well, simply go to your alias’s configuration like the main function and create a Function URL, this URL will map straight to the alias version of the Lambda Function.
Monitoring
AWS has made some new CloudWatch metrics (to support monitoring the function URLs
- UrlRequestCount – The number of requests made to the function URL
- Url4xxError - The number of requests that returned a 4XX HTTP status code. 4XX series codes indicate client-side errors, such as bad requests.
- Url5xxError - The number of requests that returned a 5XX HTTP status code. 5XX series codes indicate server-side errors, such as function errors and timeouts.
- UrlLatency - The time between when the function URL receives a request and when the function URL returns a response.
Go experiment
I don’t usually post much about more development focused functionality but this one really caught my eye and will be useful for the small things I work on, hopefully it might solve and simplify things for you.