DEV Community

Cover image for Creating an HTTPS Lambda Endpoint without API Gateway
Shane Nolan
Shane Nolan

Posted on • Originally published at shanenullain.Medium


Creating an HTTPS Lambda Endpoint without API Gateway

Amazon Web Services (AWS) recently announced Function URLs, a new in-built feature that allows you to invoke your functions through an HTTPS endpoint. By default, the endpoint is secure using AWS Identity Access Management (IAM) but you can allow public access with optional Cross-Origin Resource Sharing (CORS) configurations and/or custom authorisation logic. Originally, if you wanted to invoke a Lambda function publicly via HTTPS you would need to set up and configure AWS API Gateway or AWS Elastic Load Balancing and pay additional fees once you exceeded their free tier. Fortunately, Function URLs don't incur an additional cost πŸŽ‰. I’d recommend you continue to use these services if you’re building a serverless REST API or require additional features such as request-response transformations. For small use-cases such as webhooks or determining the price of a cryptocurrency, Function URLs are more suited.

This blog post will demonstrate how to create an HTTPS Lambda endpoint using Function URLs, Python and Terraform, an open-source infrastructure as code tool. If you’d rather not use Terraform, Function URLs can be created directly via the AWS user interface (UI). You can follow the official AWS guide here. You can use any compatible programming language with AWS Lambda for this demonstration since the principles are the same. You can view the project's source code on Github.

Python Lambda Function

First, create a Python project with being the entry point for Lambda. I recommend using this modern Python development environment for a more straightforward implementation but your own will suffice. This project will use the Python version 3.9.0 . You can view a list of supported versions here. Your project directory structure should replicate this:

β”œβ”€β”€ .editorconfig
β”œβ”€β”€ lambda_function_url_terraform
β”‚   β”œβ”€β”€
β”‚   └──
β”œβ”€β”€ poetry.lock
β”œβ”€β”€ pyproject.toml
β”œβ”€β”€ setup.cfg
└── tests

2 directories, 10 files
Enter fullscreen mode Exit fullscreen mode

For this example, the Lambda handler will return a JSON object with a body containing a message and status code of 200.

Python Lambda Handler

To ensure the Lambda handler is working as expected write a unit test in tests/ to validate its response.

Unit test to validate the Lambda handler's response.

Terraform Deployment

If you don’t have Terraform already installed, you can follow the official installation documentation. Once installed, confirm the installation was successful by executing:

Confirmation of Terraforms installation.

First, create the required Terraform deployment file at the top level of your Python project. Declare 1.0.0 as the Terraform version and 4.9.0 as the Hashicorp AWS provider version since that's when Function URLs functionality was implemented. You can review the merge request here. Next, declare the AWS region, for example eu-west-1 . Once declared should look like this:

Initial Terraform deployment code.

Before the Lambda function can be implemented, an IAM role with a trust policy needs to be created. In this case, the AWS Lambda service will be trusted and allowed to call the AWS Security Token Service (STS) AssumeRole action. Append the IAM role resource to file. Its implementation should look like this:

Lambda IAM role with required trust policy.

Execute the following commands to create a zip file called containing the projects source code and its requirements for Lambda:

# Install zip package to zip files/folders:
sudo apt-get install zip

poetry build; 
poetry run pip install --upgrade -t package dist/*.whl;
(cd package; zip -r ../ . -x '*.pyc';)

# Pip installation without Poetry or zip:
pip freeze > requirements.txt
pip install -r requirements.txt -t package
# zip the package folder.
Enter fullscreen mode Exit fullscreen mode

Once packaged the Lambda function is ready to be implemented. Depending on your setup you may need to modify the following attributes:

  • runtime depending on your Python version.

  • function_name the name you want to give your Lambda function.

  • handler the path to your Lambda handler.

The Lambda function resource should look like this:

Terraform AWS Lambda function resource code.

The filename attribute is the filename along with the extension of our packaged project. Similarly, the source_code_hash attribute is used to determine if the packaged project has been updated, i.e. a code change. The role attribute is a reference to the previously implemented IAM role. Append the Lambda function to .

Lastly, create the Function URL resource and save the generated URL.The authorization_type is set to NONE , meaning it allows public access. You have the option of restricting access to authenticated IAM users only, as well as CORS configuration capabilities. You can read about them here. The Lambda Function URL resource should look like this:

Terraform AWS Lambda Function URL resource code.

The output resource function_url saves the generated Function URL. Append both the Function URL and output resource to . With all the Terraform components together, should replicate this:

Deploying with Terraform requires only a single command after the infrastructure is coded but first, you need to initialise Terraform inside of the project by executing terraform init . Additionally, set your AWS_ACCESS_KEY_ID , AWS_SECRET_ACCESS_KEY and AWS_REGION via the command line. If you’re unfamiliar with configuring your AWS credentials you can read more about it on the official AWS and Terraform documentation.

Once initialised, deploy your Lambda function using terraform apply and accept the confirmation of the required changes. After deployment, it will output the Lambda Function URL πŸŽ‰.

Terraform AWS Lambda Function URL deployment.

Test the public endpoint by either opening the URL in a browser or using an API testing tool such as httpie. The below example uses Terraform to retrieve the generated Function URL via terraform output and a GET request is submitted to the URL via httpie.

httpie GET request to the Lambda Function URL.

Top comments (0)

Timeless DEV post...

Git Concepts I Wish I Knew Years Ago

The most used technology by developers is not Javascript.

It's not Python or HTML.

It hardly even gets mentioned in interviews or listed as a pre-requisite for jobs.

I'm talking about Git and version control of course.

One does not simply learn git