go-lambda-container

module
v0.0.0-...-8de2770 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 5, 2021 License: BSD-3-Clause

README

go-lambda-container

Example code for developing Go applications that can be run from the command line, as AWS Lambda functions or as containerized Lambda functions.

Important

This is work in progress. Through documentation to follow.

What is this?

This is an example package implementing a simple "hello world" application in the Go programming language. The idea is to outline and document the steps and patterns necessary to write a single application that can be run from the command line, as an AWS Lambda function or a containerized Lambda function.

hello-world

The hello-world tool emits the phrase "Hello world" and the current time.

> ./bin/hello-world -h
Emit the phrase 'Hello world' and the current time.
Usage:
	 ./bin/hello-world [options]
Valid options are:

  -mode string
    	Valid modes are: cli (command line), lambda. (default "cli")
Command line
$> make cli
go build -mod vendor -o bin/hello-world cmd/hello-world/main.go

$> ./bin/hello-world 
Hello world, 2021-03-03 15:55:47.84364 -0800 PST m=+0.128271453
Lambda
$> make lambda
if test -f main; then rm -f main; fi
if test -f hello-world.zip; then rm -f hello-world.zip; fi
GOOS=linux go build -mod vendor -o main cmd/hello-world/main.go
zip hello-world.zip main
  adding: main (deflated 48%)
rm -f main

Create a new Lambda function, in AWS, using hello-world.zip as the source code. Ensure that the Lambda handler is configured to be main. The function itself does not need any special permissions to the default role, that AWS will create by default, is sufficient.

Ensure the following environment variables are assigned:

Name Value
SFOMUSEUM_MODE lambda

Create an empty test ({}) and run it. It should succeed with a null output, writing the phrase "Hello world" to the function's log file.

Lambda (using a container image)
$> make docker
docker build -f Dockerfile -t hello-world .
Sending build context to Docker daemon  12.82MB

...Docker stuff happens

Successfully built 97c609afd399
Successfully tagged hello-world:latest

Tag and push the hello-world container image to an AWS ECS repository.

Create a new Lambda function, in AWS, using hello-world container image as the source code. The function itself does not need any special permissions to the default role, that AWS will create by default, is sufficient.

Ensure the following container image configuration values:

Name Value
CMD override /main

Ensure the following environment variables are assigned:

Name Value
SFOMUSEUM_MODE lambda

Create an empty test ({}) and run it. It should succeed with a null output, writing the phrase "Hello world" to the function's log file.

To test locally you can do:

$> docker run -e SFOMUSEUM_MODE=lambda -p 9000:8080 hello-world:latest /main

And then in another terminal:

$> curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
"Hello world, 2021-03-03 23:39:42.2782989 +0000 UTC m=+0.007045701"

read-file

The read-file tool demonstrates bundling files in your container that can be accessed by your Go application. The code uses the GoCloud blob.Bucket abstraction layer for reading files, in particular the local storage driver for access files on the local filesystem.

$> ./bin/read-file -h
Emit the contents of a file contained in the GoCloud -bucket-uri resource.
Usage:
	 ./bin/read-file [options] path/to/file
Valid options are:

  -bucket-uri string
    	A valid GoCloud file:// bucket URI. (default "file:///usr/local/example")
  -mode string
    	Valid modes are: cli (command line), lambda. (default "cli")
Command line
$> make cli
go build -mod vendor -o bin/read-file cmd/read-file/main.go
$> ./bin/read-file \
	-bucket-uri file:///usr/local/sfomuseum/go-lambda-container/ \
	README.md \
| wc -l

     155
Lambda

As written this code will not work in a traditional Lambda function because there is no filesystem to read files from.

Note: Because the code is using the GoCloud blob.Bucket abstraction layer for reading files it could be made to work from another storage system like S3. You will need to update the code to load the necessary packages in order for that to work.

Lambda (using a container image)

First, start by creating a container using the Dockerfile.readfile instructions.

$> make docker-readfile
docker build -f Dockerfile.readfile -t read-file .
Sending build context to Docker daemon  29.68MB

...Docker stuff happens...

Step 5/11 : RUN mkdir /usr/local/example
Step 6/11 : COPY README.md /usr/local/example/README.md

...More Docker stuff happens...

Successfully tagged read-file:latest

See the way we're creating a /usr/local/example directory in the container and copying the README.md file in to it? This is the file we will read later in our Lambda function.

Tag and push the read-file container image to an AWS ECS repository.

Create a new Lambda function, in AWS, using read-file container image as the source code. The function itself does not need any special permissions to the default role, that AWS will create by default, is sufficient.

Ensure the following container image configuration values:

Name Value
CMD override /main

Ensure the following environment variables are assigned:

Name Value
SFOMUSEUM_MODE lambda
SFOMUSEUM_BUCKET_URI file:///usr/local/example/

Create a new test like this:

{"path":"README.md"}

Then run it. You should see something like this:

For testing locally you can do this:

$> docker run -e SFOMUSEUM_MODE=lambda -e SFOMUSEUM_BUCKET_URI=file:///usr/local/example -p 9000:8080 read-file:latest /main
time="2021-03-04T21:48:23.104" level=info msg="exec '/main' (cwd=/go, handler=)"

And then this:

$> curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"path":"README.md"}'

"# go-lambda-container\n\nExample code for developing Go applications that can be run from the command line, as AWS Lambda functions or as containerized Lambda functions.\n\n## Important\n\nThis is work in progress. Through documentation to follow.\n\n## What is this?\n\nThis is an example package implementing a simple \"hello world\" application in the Go programming language. The idea is to outline and document the steps and patterns necessary to write a single application that can be run from the command line, as an AWS Lambda function or a containerized Lambda function. \n\n## Command line\n\n```\n$\u003e make cli\ngo build -mod vendor -o bin/hello-world cmd/hello-world/main.go\n\n$\u003e ./bin/hello-world \nHello world, 2021-03-03 15:55:47.84364 -0800 PST m=+0.128271453\n```\n\n## Lambda\n\n```\n$\u003e make lambda\nif test -f main; then rm -f main; fi\nif test -f hello-world.zip; then rm -f hello-world.zip; fi\nGOOS=linux go build -mod vendor -o main cmd/hello-world/main.go\nzip hello-world.zip main\n  adding: main (deflated 48%)\nrm -f main\n```\n\nCreate a new Lambda function, in AWS, using `hello-world.zip` as the source code. Ensure that the Lambda handler is configured to be `main`. The function itself does not need any special permissions to the default role, that AWS will create by default, is sufficient.\n\nEnsure the following environment variables are assigned:\n\n| Name | Value |\n| --- | --- |\n| SFOMUSEUM_MODE | lambda |\n\nCreate an empty test (`{}`) and run it. It should succeed with a `null` output, writing the phrase \"Hello world\" to the function's log file.\n\n## Lambda (using a container image)\n\n```\n$\u003e make docker\ndocker build -f Dockerfile -t hello-world .\nSending build context to Docker daemon  12.82MB\n\n...Docker stuff happens\n\nSuccessfully built 97c609afd399\nSuccessfully tagged hello-world:latest\n```\n\nTag and push the `hello-world` container image to an AWS ECS repository.\n\nCreate a new Lambda function, in AWS, using `hello-world` container image as the source code. The function itself does not need any special permissions to the default role, that AWS will create by default, is sufficient.\n\nEnsure the following container image configuration values:\n\n| Name | Value |\n| --- | --- |\n| CMD override | /main |\n\nEnsure the following environment variables are assigned:\n\n| Name | Value |\n| --- | --- |\n| SFOMUSEUM_MODE | lambda |\n\nCreate an empty test (`{}`) and run it. It should succeed with a `null` output, writing the phrase \"Hello world\" to the function's log file.\n\nTo test locally you can do:\n\n```\n$\u003e docker run -e SFOMUSEUM_MODE=lambda -p 9000:8080 hello-world:latest /main\n```\n\nAnd then in another terminal:\n\n```\n$\u003e curl -XPOST \"http://localhost:9000/2015-03-31/functions/function/invocations\" -d '{}'\n\"Hello world, 2021-03-03 23:39:42.2782989 +0000 UTC m=+0.007045701\"\n```"

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL