Max
Max

Reputation: 1175

Run golang lambda function locally

I'm trying to develop a lambda that has to work with S3 and dynamoDB. The thing is that because I am not familiar with the SDK of aws for go I will have lots of tests and tries. Each time I will change the code is another time I have to compile the project and upload it to aws. Is there any way to do it locally? pass some kind of configuration that lets me call the services of aws locally, from my computer? Thanks!

This has to do mostly with golang, other languages like python can run directly on the aws lambda function page, and node has cloud9 support.

Upvotes: 4

Views: 14979

Answers (3)

diogoa
diogoa

Reputation: 171

You can download locally the AWS lambda runtime environment as described in AWS documentation

mkdir -p ~/.aws-lambda-rie && curl -Lo ~/.aws-lambda-rie/aws-lambda-rie \
https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie \
&& chmod +x ~/.aws-lambda-rie/aws-lambda-rie               

To test the lambda function locally run you can then run on a terminal session:

~/.aws-lambda-rie/aws-lambda-rie go run main.go

This will start a server listening on port 8080. To actually trigger the lambda function, you can finally run on another terminal session:

curl -XPOST "http://localhost:8080/2015-03-31/functions/function/invocations" -d '{"Name": "World"}'

Last but not least, I'd suggest you to have a look at localstack. You can start a docker container that runs locally and will mock AWS S3 & DynamoDB APIs, so you can check your code for correctness still without having to deploy anything to AWS.

Upvotes: 2

scosman
scosman

Reputation: 2585

I like the newish AWSLabs Go API Proxy for this: https://github.com/awslabs/aws-lambda-go-api-proxy

It allows you to write a standard HTTP server using your tools of choice (plain old go, Gin, Gorilla, etc), then run that server on Lambda. It has several benefits:

  • Removes almost all Lambda specific code/conventions from your codebase for more idiomatic go
  • Easily covert existing golang HTTP server to lambda execution mode
  • Support parallel execution modes. I use a ENV variable to switch between them in example below. I use straight HTTP for local dev, and Lambda for deployment.

Example app with 1 function

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "os"

    "github.com/aws/aws-lambda-go/lambda"
    "github.com/awslabs/aws-lambda-go-api-proxy/httpadapter"
)

// map of our functions, which can be handled as HTTP or Lambda
var functions = map[string]http.HandlerFunc{
    "ping": PingHandler,
}

func main() {
    for name, handler := range functions {
        path := fmt.Sprintf("/%s", name)
        http.HandleFunc(path, handler)
    }

    httpPort := os.Getenv("HTTP_PORT")
    if httpPort == "" {
        log.Println("Starting Lambda Handler")
        lambda.Start(httpadapter.New(http.DefaultServeMux).ProxyWithContext)
    } else {
        log.Printf("Starting HTTP server on port %s\n", httpPort)
        formattedPort := fmt.Sprintf(":%s", httpPort)
        log.Fatal(http.ListenAndServe(formattedPort, nil))
    }
}

// Sample Func
func PingHandler(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "pong")
}

Running as HTTP is easy: go build -out main && HTTP_PORT=7575 ./main. This is super fast, making it easy to rebuilt and test.

You can still build and run in a docker container to test Lambda mapping before deploying using the steps others have mentioned.

Upvotes: 2

John
John

Reputation: 975

You can use the lambci docker image(s) to execute your code locally using the same Lambda runtimes that are used on AWS.

https://github.com/lambci/docker-lambda

You can also run dynamo DB locally in another container as well

https://hub.docker.com/r/amazon/dynamodb-local/

To simulate credentials/roles that would be available on Lambda, just pass in your Api creds VIA environment variables. ( for s3 access )

Cheers -JH

Upvotes: 4

Related Questions