Background
While researching how to run a Go web application on AWS Lambda, I came across a technology called the AWS Lambda Web Adapter.
The AWS Lambda Web Adapter allows web applications built with various frameworks (e.g., Express.js, Flask, Laravel, Next.js, etc.) to run on Lambda.
https://github.com/awslabs/aws-lambda-web-adapter?tab=readme-ov-file#examples
It’s reasonable to assume that web application frameworks not listed in the official examples, such as Ruby on Rails, can also be run on Lambda.
In this case, I used the AWS Lambda Web Adapter and SAM (Serverless Application Model) to deploy a simple server application built with the Go web framework Echo via Lambda Function URLs.
The code I created is publicly available as a template repository on GitHub:
https://github.com/ryichk/go-echo-lambda-function-url-template
While researching, I found samples using Gin in the official AWS Lambda Web Adapter examples and a Zenn article with a Fiber sample. However, I couldn’t find any samples using Echo, so I decided to publish this article.
https://github.com/awslabs/aws-lambda-web-adapter/tree/main/examples/gin
Steps and Explanation
1. Building the Echo Server
Build a web application using Echo. For this example, I created a simple app that displays Hello!
when accessing localhost:8000/.
package main
import (
"net/http"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
func main() {
e := echo.New()
e.GET("/", hello)
e.Logger.Fatal(e.Start(":8000"))
}
func hello(c echo.Context) error {
return c.String(http.StatusOK, "Hello!")
}
2. Creating the Dockerfile
The Dockerfile was based on the Gin Dockerfile from the official Lambda Web Adapter examples.
FROM golang:1.24-alpine AS build_base
RUN apk add --no-cache git
WORKDIR /app
COPY . .
RUN go mod download
RUN GOOS=linux CGO_ENABLED=0 go build -o bootstrap ./app
FROM alpine:3.9
RUN apk add ca-certificates
# Only this line is needed to use the Lambda Web Adapter in the Docker image
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.8.4 /lambda-adapter /opt/extensions/lambda-adapter
COPY --from=build_base /app/bootstrap /app/bootstrap
ENV PORT=8000 AWS_LWA_ASYNC_INIT=true
EXPOSE 8000
CMD ["/app/bootstrap"]
By default, the Lambda Web Adapter assumes the web app listens on port 8080. To use a different port, specify it using the PORT
or AWS_LWA_PORT
environment variable.
However, in the Lambda execution environment, the web app runs as a non-root user, so it cannot listen on port numbers below 1024. Additionally, it’s best to avoid ports 3000 (used by CloudWatch Lambda Insight extension) and 9001 (used by the Lambda Runtime API).
The following environment variable is optional:
AWS_LWA_ASYNC_INIT=true
If a Lambda function doesn’t complete initialization within 10 seconds, Lambda restarts the function and charges for initialization. The Lambda Web Adapter supports asynchronous initialization to avoid restarts by utilizing the 10-second initialization window. When enabled, it performs readiness checks for up to 9.8 seconds. If the web app isn’t ready, it notifies the Lambda service of initialization completion and continues readiness checks in the handler. This feature is disabled by default but can be enabled by setting AWS_LWA_ASYNC_INIT
or ASYNC_INIT
to true
.
3. Creating the SAM template.yaml
For Lambda Function URLs, I referenced the template.yaml for nextjs-response-streaming from the official examples.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: SAM Template for Go's Echo Web application.
Globals:
Function:
Timeout: 5
MemorySize: 128
Resources:
GoEchoAppFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: app/
PackageType: Image
Architectures:
- x86_64
FunctionUrlConfig:
AuthType: NONE
Metadata:
DockerTag: v1
DockerContext: .
Dockerfile: Dockerfile
Outputs:
GoEchoAppFunctionOutput:
Description: "Go's Echo App Function ARN"
Value: !GetAtt GoEchoAppFunction.Arn
GoEchoAppFunctionUrlOutput:
Description: "Go's Echo App Function URL"
Value: !GetAtt GoEchoAppFunctionUrl.FunctionUrl
Setting AuthType
to NONE
in FunctionUrlConfig
makes the URL publicly accessible.
5. Building with SAM CLI
$ sam build
Building codeuri: /Pathto/go-echo-lambda-function-url-template runtime: None architecture: x86_64 functions: GoEchoAppFunction
Building image for GoEchoAppFunction function
Setting DockerBuildArgs for GoEchoAppFunction function
Step 1/13 : FROM golang:1.24-alpine AS build_base
~ Omitted ~
Successfully tagged goechoappfunction:v1
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
6. Deploying with SAM CLI
$ sam deploy
~ Omitted ~
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
2024-08-24 21:45:24 - Waiting for stack create/update to complete
CloudFormation events from stack operations (refresh every 5.0 seconds)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
UPDATE_IN_PROGRESS AWS::CloudFormation::Stack go-echo-app User Initiated
UPDATE_IN_PROGRESS AWS::Lambda::Function GoEchoAppFunction -
UPDATE_COMPLETE AWS::Lambda::Function GoEchoAppFunction -
UPDATE_COMPLETE_CLEANUP_IN_PROGRESS AWS::CloudFormation::Stack go-echo-app -
UPDATE_COMPLETE AWS::CloudFormation::Stack go-echo-app -
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CloudFormation outputs from deployed stack
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key GoEchoAppFunctionUrlOutput
Description Go's Echo App Function URL
Value https://xxx.lambda-url.ap-northeast-1.on.aws/
Key GoEchoAppFunctionOutput
Description Go's Echo App Function ARN
Value arn:aws:lambda:ap-northeast-1:000000000000:function:go-echo-app-GoEchoAppFunction-XXXXXXXX
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - go-echo-app in ap-northeast-1
7. Verification
$ curl https://xxx.lambda-url.ap-northeast-1.on.aws/
Hello!%
8. Deleting Resources
$ sam delete