Many organisations are moving away from a monolithic approach to adopting a microservices architecture when building highly scalable and performant applications. This allows engineers to focus on developing services that have their own business logic to achieve a specific goal.
But sometimes, what you really need is to build multiple single-function microservices to implement specific business logic in your application workflow. And all you require is a simple process to configure an HTTP(S) endpoint in front of your functions without focusing on learning, provisioning and managing additional services.
Recently, Amazon AWS announced the availability of Lambda function URLs. This new feature lets you assign dedicated HTTPS endpoints to any Lambda function with the option to configure Cross-Origin Resource Sharing Headers (CORS).
AWS Lambda functions allow your engineering team to focus on building what matters most to the organisation. At the same time, AWS handles the configuration and monitoring of your HTTP endpoints and services.
Let’s take a closer look.
What is AWS Lambda?
AWS Lambda is a serverless, event-driven compute service that lets you run code for any application or backend service without having to provision or manage additional services.
How does AWS Lambda Work?
Simply put, a client/user will send request(s) that may contain data to AWS Lambda. Once AWS Lambda receives those request(s), it will run a defined number of containers depending on the size or volume of data of those request(s).
A single request is given to a single container to execute code provided by the user to satisfy the query. When the request(s) grows, it creates multiple containers and shares multiple request(s). AWS Lambda will automatically scale depending on the number of requests, and the great thing is that you are only charged based on the number of requests for your functions and the time it takes for your code to execute.
Features of AWS Lambda
- Lambda will automatically run our code without requiring us to configure or manage servers and additional services → All we need to do is essentially write our code and upload it to Lambda, and the service will handle the rest.
- Automatically scale our application by running code in response to each trigger → Meaning the code will run in parallel and process each trigger individually. Scaling is based on the size of the workload.
- Metered on the second → You only pay for the time the code runs, and you do not have to pay for any of the servers.
Function URL Pricing
Function URLs are baked into Lambda’s request and duration pricing. The cost will depend on many factors, including your use case and API scale. Please refer to AWS Lambda Pricing for more details.
AWS Lambda Function URL In Action
The following example will use Tyk as our gateway service between the client and our backend services. We will create an API definition with an upstream to our Lambda function HTTPS endpoint and implement a basic API key authorisation process.
But first…
Why do we want to use Tyk in front of AWS Lambda?
The awesome thing about Tyk is that we have adopted the idea of “batteries-included” as part of our core offering. Meaning Tyk provides out-of-the-box functionality and features that help companies efficiently build, secure, monitor, and support APIs and services which power them.
For example, we can take advantage of the developer portal by publishing our APIs to allow developers to self-register and receive authentication tokens to access our Lambda functions.
Depending on your API scale, this might save you a tremendous amount in AWS API Gateway fees.
What we’re really talking about here is API Management. An upgraded level of maturity where an organisation enables product-or-API-lead-growth.
AWS Lambda Function URL Tutorial
Create and configure our AWS Lambda function
The first step is to head to the AWS Lambda dashboard and generate our Lambda function.
1. Click Create function.
Next, you will be presented with a create function user interface allowing you to configure the appropriate settings.
2. Provide the Function name field with a meaningful name that fits your use case. In this example, we will set the field to: HelloTyk.
3. Check Enable function URL → This option will assign an HTTP(S) endpoint to your Lambda function.
4. Set Auth type to NONE → This option will make our function URL publicly available. But do not worry! Later in this tutorial, we will add custom authorisation logic based on a signature/API key in the HTTP headers.
5. Check Configure cross-origin resource sharing (CORS) → Allows access to your URL function from any origin. Of course, this will depend on your use case, but we will keep it default and allow all origins in this example.
6. Click Create function.
Well done! We just created our AWS Lambda function and retrieved the assigned HTTPS endpoint URL.
7. Retrieve Function URL.
Now let’s hit our function URL endpoint and see the results.
If you replace the URL in the curl command with the function URL and run the following command, if successful, you should receive a message “Hello from Lambda!”.
Via Curl
curl -X GET "https://7dswl6arly7rgruzny5e7h3wxm0jkawa.lambda-url.us-east-1.on.aws/" "Hello from Lambda!"
Via Postman
Modify AWS Lambda Function Code Source
Now that we have successfully created our Lambda function, let’s modify the code source and add business logic to allow traffic through our Tyk Gateway.
We’ll protect our service with an API KEY and configure Tyk to provide it as a header to authenticate our Lambda service.
Please keep in mind that this basic example is not the most scalable method, but it will provide you with a simple step that you can easily replace. For instance, we can replace this with IAM credentials which Tyk can exchange for an access token.
JavaScript Code Source Example:
exports.handler = async (event) => { const x_api_key = '61c75107-9225-4656-8022-e82685e57dcd'; const method = event.requestContext.http.method; let response = { statusCode: 403, body: JSON.stringify('Forbidden') }; // Log request method console.log(`Received ${method} request`); try { // Validate whether or not the x-api-key has been set by the Tyk Gateway. // This validation can and should be integrated with AWS Secrets Manager. // https://aws.amazon.com/blogs/security/how-to-securely-provide-database-credentials-to-lambda-functions-by-using-aws-secrets-manager/ if (event.headers['x-api-key'] == x_api_key) { // Perform business logic... console.log(`Success API Key Check.`); response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!') } } } catch (error) { // Log error returned console.error(`Failed API Key Check: ${error}`) return { statusCode: 400, body: `Cannot process event: ${error}`, } } return response; };
Update the AWS Lambda function code source with the example code above:
1. Replace the Lambda function code source with the Javascript code source example from above.
2. Replace the x-api-key with a generated API key → This API key will be used to authorise requests coming through Tyk and prevent all other requests.
3. Click Deploy.
If we attempt to send a request directly to our function URL endpoint, we will receive a “Forbidden” error message. This means that we have successfully added some business logic to our code to only allow authorised traffic through Tyk.
Via Curl
curl -X GET "https://7dswl6arly7rgruzny5e7h3wxm0jkawa.lambda-url.us-east-1.on.aws/" "Forbidden"
Via Postman
Add a new API to Tyk
Success! We have just created a Lambda function and added some code source to ensure that all our traffic is authorised through Tyk using an API key from the request header. The final step is to add an API to Tyk and pass the required header values to our Lambda function to perform the custom authorisation required.
Create an API definition and configure the target URL as the Lambda function URL:
1. Provide a meaningful API name. In this case, we have set the Name to Tyk Lambda API.
2. Set the Upstream URL to the function URL retrieved from Step 1 → This will proxy all our traffic from Tyk Lambda API endpoint to our AWS Lambda function upstream.
a. An additional step needed is to configure the Authentication mode for this API. In this example, we have set our Authentication Mode to Authentication Token.
Inject x-api-key to our Request Header:
3. Click the Endpoint Designer.
4. Add the x-api-key header name and value → This request header will be sent to the Lambda function, which will be used to authorise the request.
5. Click Add and then Update to ensure the changes have been saved.
That’s it! We have now deployed a Lambda function, assigned an HTTPs endpoint to it, and we’ve secured it with Tyk.
In this example, I have configured our Authentication Mode to Authentication Token (an API access token that will be used in our API request example below).
Let’s make an API request to our Lambda function through Tyk:
Via Curl
curl -X GET 'https://inevitable-thunderhead-mgw.aws-use1.cloud-ara.tyk.io/tyk-lambda-api/' \ -H "Authorization: Bearer {API_ACCESS_TOKEN}" "Hello from Lambda!"
Via Postman
Benefits of Tyk and AWS Lambda
We can leverage Tyk to secure our AWS Lambda function URL endpoints in many ways. As the example above demonstrates, we can authorise against the signature or token in the HTTP headers sent from our Tyk Gateway. Another option would be to develop a custom plugin for our Tyk Gateway and enable them to each API that uses AWS IAM credentials to generate a valid Authorisation header that the AWS Lambda function authorises against.
You can check AWS’s well-written documentation around security and auth model for function URLs.
Now, we can access our API using any auth type that Tyk provides out of the box instead of just the ones offered by AWS Lambda. In addition, we can take advantage of all the powerful features that Tyk offers to empower our engineers to focus on what matters most to our organisation.