LoginSignup
10
2

More than 3 years have passed since last update.

Development Environment for AWS Lambda and Go

Last updated at Posted at 2019-12-16

When it comes to developing serverless applications, we have many options in terms of the workflow we can adopt in the process, as well as the tools to support it.

Today, I will present a sample development environment for a very simple API developed in Golang for the AWS Lambda.

Requirements

  • python (both Python 2.x and 3.x supported)
  • pip
  • Docker
  • Node
  • Golang 1.x

Localstack

Having our requirements in place, let's first install and start LocalStack:

$ pip install localstack
$ localstack start

On a mac, you may need to run the command TMPDIR=/private$TMPDIR localstack start --docker if $TMPDIR contains a symbolic link that cannot be mounted by Docker.

This is a handy tool that provides us with a local AWS cloud stack, so this will allow us to test API Gateway/Lambda calls locally.

Because LocalStack mocks many other AWS services, our functions could also interact with a DynamoDB table or a SQS queue locally with this single tool.

Serverless Framework

Next, we are going to install the Serverless Framework. This is a set of tools to support the development of serverless applications. In this case, it will be used to automate the deployment process. It is extremely convenient as it automatically creates all the resources that are needed by our API to run.

This tool supports other providers, such as Google Cloud Platform and Azure. When we work with AWS, it automates the deployment process by creating a CloudFormation stack based on our application and configuration.

Ultimately, we can use the Serverless Framework to deploy our API to AWS, but this will not be covered in this article. Instead, we are going to target our LocalStack installation to test our functions locally. What is interesting about this approach is that we have a very similar process when working locally, compared to what we do when we want to deploy our application to AWS.

To install the Serverless Framework, we just need to:

$ npm install -g serverless

Lambda Function

Now, let's create our lambda function. Create a folder for this project and then:

$ go mod init hello-lambda
$ go get github.com/aws/aws-lambda-go

This will initialize the Go module and install the necessary library. Next, create a main.go file with our lambda function:

package main

import (
    "context"
    "encoding/json"
    "time"

    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
)

type HelloLambdaResponse struct {
    Greeting    string    `json:"greeting"`
    CurrentTime time.Time `json:"current_time"`
}

func handle(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    resp := &HelloLambdaResponse{
        Greeting:    "Hello World!",
        CurrentTime: time.Now().UTC(),
    }

    responseBody, err := json.Marshal(resp)
    if err != nil {
        return events.APIGatewayProxyResponse{}, err
    }

    return events.APIGatewayProxyResponse{
        StatusCode: 200,
        Headers: map[string]string{
            "Content-Type": "application/json",
        },
        Body: string(responseBody),
    }, nil

}

func main() {
    lambda.Start(handle)
}

Deployment

We can now deploy our function to LocalStack. Let's first, install the plugin that will make the Serverless Framework target the LocalStack installation instead of the cloud:

$ npm install --save-dev serverless-localstack

Now, let's create a serverless.yml config file with the instruction on how the deployment has to be executed:

service: hello-lambda
plugins:
  - serverless-localstack
provider:
    name: aws
    runtime: go1.x
    stage: ${opt:stage, 'local'}
custom:
  localstack:
    debug: true
    stages:
      # list of stages for which the plugin should be enabled
      - local
package:
  exclude:
    - ./**
  include:
    - ./bin/**
functions:
  hello-lambda:
    handler: bin/hello-lambda
    events:
      - http:
          path: hello
          method: get

In this file, we are describing our functions below the functions: key, specifying that a GET method in the hello path will invoke the function we created in the previous step.

We are also specifying that the LocalStack environment has to be targeted when deploying to the local stage with the configuration under the custom: key.

Now, let's compile our code and run the deployment:

$ GOOS=linux GOARCH=amd64 go build -o bin/hello-lambda .
$ serverless deploy --stage local

If there are no errors, you should see a Service Information section like below, describing our function:

Service Information
service: hello-lambda
stage: local
region: us-east-1
stack: hello-lambda-local
resources: 11
api keys:
  None
endpoints:
  GET - http://localhost:4567/restapis/onw2twhxmr/local/_user_request_/hello
functions:
  hello-lambda: hello-lambda-local-hello-lambda
layers:
  None
Serverless: Run the "serverless" command to setup monitoring, troubleshooting and testing.

Now, it should be possible to call the function through the endpoint above:

$ curl http://localhost:4567/restapis/onw2twhxmr/local/_user_request_/hello
{"greeting":"Hello World!","current_time":"2019-12-16T14:44:35.086894535Z"}

Conclusion

This was an example on how to work locally with AWS Lambda functions, but definitely not the only approach. I'm still experimenting the available solutions myself, but an obvious alternative would to use the AWS SAM Local to test Lambda functions locally. You can read more about the available tools at the AWS Serverless developer tools page.

10
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
2