Reputation: 1175
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
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
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:
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
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