Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
daesu committed Jul 31, 2024
0 parents commit ca224b4
Show file tree
Hide file tree
Showing 15 changed files with 490 additions and 0 deletions.
46 changes: 46 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: service CI

on:
push:
branches:
- master
pull_request:
branches:
- master

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Docker Buildx (Ubuntu)
uses: docker/setup-buildx-action@v1

- name: Set up QEMU (Ubuntu)
uses: docker/setup-qemu-action@v1

- name: Install Docker Compose (Ubuntu)
run: |
sudo apt-get update
sudo apt-get install -y docker-compose
- name: Check Docker version
run: docker --version

- name: Check Docker Compose version
run: docker-compose --version

- name: Run Makefile setup target
run: make setup

- name: Run Makefile build target
run: make build

- name: Run Makefile tests target
run: make run-tests
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.env*
!.env.example
bin/*
.vscode/
serverless/
.serverless/
node_modules/
bin/
terraform*
.terraform/
.terraform*
22 changes: 22 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM golang:1.22.2-alpine AS terraform_go

# Install necessary tools
RUN apk add --no-cache curl unzip

# Download and install Terraform
RUN curl -fsSL https://releases.hashicorp.com/terraform/1.3.0/terraform_1.3.0_linux_amd64.zip -o terraform.zip && \
unzip terraform.zip && \
mv terraform /usr/local/bin/ && \
rm terraform.zip

WORKDIR /opt/app

COPY go.mod go.sum ./
RUN go mod download

COPY . .

RUN go build -o /opt/app/bin/service main.go

# Set the entrypoint to Terraform
CMD ["terraform"]
31 changes: 31 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
AWS_REGION ?= eu-west-1

setup:
@if [ ! -d ".terraform" ]; then \
echo "initializing terraform ..."; \
docker-compose run --rm terraform_go terraform init; \
fi

build: setup
@mkdir -p bin
docker-compose run --rm service sh -c "cd /opt/app && env GOOS=linux go build -tags aws_lambda -ldflags='-s -w' -o /opt/app/bin/service main.go"
cp bootstrap bin/
cd bin; zip -r service.zip service bootstrap

clean:
rm -rf bin/*
rm -rf .terraform/
rm -f .terraform*
rm -f terraform.*

tests:
docker-compose run --rm test

run:
docker-compose up service

deploy: build
docker-compose run --rm terraform_go terraform apply -var="region=$(AWS_REGION)" -auto-approve

destroy:
docker-compose run --rm terraform_go terraform destroy -var="region=$(AWS_REGION)" -auto-approve
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# go-lambda

Skeleton to setup a go lambda function with api-gateway on AWS using terraform. Projects uses the [3musketeers](https://3musketeers.pages.dev/guide/) pattern.

## Running

Can be run through `go` directly or through `make` & `docker-compose`.

## Local

Create a `.env` file by copying the contents of `.env.example` and optionally adding values.

```
make build
```

Running locally will start a server at `http://localhost:8081` with a single `GET` endpoint `ping`

```
make run
```

Or alternatively if you want to use `go` directly, `go run main.go`

### Running Tests

```
make tests
```

### Deploying to AWS lambda

Deploying to AWS lambda requires adding valid AWS credentials to `.env`

```
make deploy
```

This will provision AWS Lambda and an API Gateway for the service.

To tear down the resources

```
make destroy
```

2 changes: 2 additions & 0 deletions bootstrap
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
exec /var/task/service
37 changes: 37 additions & 0 deletions cmd/serve.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//go:build !aws_lambda
// +build !aws_lambda

package cmd

import (
"os"
"os/signal"
"syscall"

http "service/http"

"github.com/rs/zerolog/log"
)

// Start the API server
func Start(server *http.Server) error {
log.Info().Msg("Starting server")

errCh := make(chan error, 1)
go func() {
if err := server.ListenAndServe(); err != nil {
log.Error().Err(err).Msg("http server failed")
errCh <- err
}
}()

// catch errors and termination signals
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)
select {
case <-interrupt:
log.Info().Msg("shutdown is requested")
case <-errCh:
}
return nil
}
20 changes: 20 additions & 0 deletions cmd/serve_aws.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//go:build aws_lambda
// +build aws_lambda

package cmd

import (
http "service/http"

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

func Start(server *http.Server) error {
adapter := httpadapter.New(server.Handler)

log.Info().Msg("Starting Lambda")
lambda.Start(adapter.Proxy)
return nil
}
28 changes: 28 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: "3.5"
services:
base:
build:
context: .
dockerfile: Dockerfile
env_file:
- .env
volumes:
- .:/opt/app

terraform_go:
extends:
service: base
command: sh -c "cd /opt/app && terraform init"

service:
extends:
service: base
command: sh -c "cd /opt/app && go run main.go"
ports:
- "8081:8081"

test:
extends:
service: base
command: sh -c "cd /opt/app && go test -v ./..."

16 changes: 16 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module service

go 1.22.2

require (
github.com/aws/aws-lambda-go v1.47.0
github.com/awslabs/aws-lambda-go-api-proxy v0.16.2
github.com/rs/zerolog v1.33.0
github.com/urfave/negroni v1.0.0
)

require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
golang.org/x/sys v0.16.0 // indirect
)
47 changes: 47 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
github.com/aws/aws-lambda-go v1.47.0 h1:0H8s0vumYx/YKs4sE7YM0ktwL2eWse+kfopsRI1sXVI=
github.com/aws/aws-lambda-go v1.47.0/go.mod h1:dpMpZgvWx5vuQJfBt0zqBha60q7Dd7RfgJv23DymV8A=
github.com/awslabs/aws-lambda-go-api-proxy v0.16.2 h1:CJyGEyO1CIwOnXTU40urf0mchf6t3voxpvUDikOU9LY=
github.com/awslabs/aws-lambda-go-api-proxy v0.16.2/go.mod h1:vxxjwBHe/KbgFeNlAP/Tvp4SsVRL3WQamcWRxqVh0z0=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU=
github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
30 changes: 30 additions & 0 deletions http/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package http

import (
"io"
"net/http"
"strings"

"github.com/rs/zerolog/log"
)

type handler struct {
name string
}

func NewHandler(name string) *handler {
return &handler{name}
}

func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
payload := &strings.Builder{}
_, err := io.Copy(payload, r.Body)
if err != nil {
log.Error().Err(err).Msg("failed to read body")
w.WriteHeader(http.StatusBadRequest)
return
}

log.Info().Msg(payload.String())
w.WriteHeader(http.StatusOK)
}
32 changes: 32 additions & 0 deletions http/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package http

import (
"net/http"

"github.com/urfave/negroni"
)

type Server struct {
*http.Server
}

func Address() string {
return ":8081"
}

func NewServer() (*Server, error) {
mux := http.NewServeMux()

handler := NewHandler("handler")

mux.Handle("/ping", handler)
router := negroni.New()
router.UseHandler(mux)

srv := &http.Server{
Addr: Address(),
Handler: router,
}

return &Server{srv}, nil
}
Loading

0 comments on commit ca224b4

Please sign in to comment.