Automate serverless Gin (Go) deployment - AWS Lambda/GHActions

Cover Image for Automate serverless Gin (Go) deployment - AWS Lambda/GHActions

1. Create a Go project.

mk dir hello
cd hello

go mod init example/hello

touch main.go
// main.go
package main

import "fmt"

func main() {
  fmt.Println("Hello, World!")
}

2. Install Gin.

go get -u github.com/gin-gonic/gin
// main.go
package main

import (
  "net/http"

  "github.com/gin-gonic/gin"
)

func main() {
  r := gin.Default()
  r.GET("/ping", func(c *gin.Context) {
    c.JSON(http.StatusOK, gin.H{
      "message": "pong",
    })
  })
  r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

3. Install and setup apex/gateway to serve in lambda.

go get -u github.com/apex/gateway
// main.go
package main

import (
	"net/http"
	"os"

	"github.com/apex/gateway"
	"github.com/gin-gonic/gin"
)

func main() {
  r := gin.Default()
  r.GET("/ping", func(c *gin.Context) {
  c.JSON(http.StatusOK, gin.H{
      "message": "pong",
    })
  })

  if isLambda() {
    gateway.ListenAndServe(":8080", r)
  } else {
    http.ListenAndServe(":8080", r)
  }
}

func isLambda() bool {
  if os.Getenv("AWS_LAMBDA_FUNCTION_NAME") != "" {
    return true
  }
  return false
}


4. Create serverless.yml.

# serverless.yml

service: hello
frameworkVersion: '3'

provider:
  name: aws
  runtime: go1.x
  stage: dev

package:
  patterns:
    - '!./**'
    - ./bin/**

functions:
  main:
    handler: bin/main
    events:
      - http:
          path: /ping
          method: get
    environment:
      GIN_MODE: release

5. Prepare the AWS Credentials needed for lambda deployment.

Plase generate or get your AWS credentials from AWS IAM and store it as part of Github's Action Secret. And that's it.

AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY

Note: For security reason, please only include the necessary permissions needed to build your aws stacks. But for the sake of this tutorial and for simplicity you can use the AdministratorAccess but don't forget to update or delete it once you're done.


6. Deploy to aws lambda from your local machine (Optional)

Just incase you want to try it first from your local machine, all you have to do:

  1. Install nodejs.

  2. Install serverless.

npm install -g serverless
  1. Build for linux (from your terminal).
GOOS=linux GOARCH=amd64 go build -o bin/main main.go
  1. Export the aws credentials to your local environment.
export AWS_ACCESS_KEY_ID=YOUR_AWS_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET_ACCESS_KEY
  1. Finally, Deploy it.
serverless deploy

7. Create a deploy workflow .github/workflows/deploy.yml file.

# .github/workflows/deploy.yml
name: Deploy to aws lambda

on:
  push:
    branches: [ "main" ]

jobs:
  deploy:
    name: deploy
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Set up Go
      uses: actions/setup-go@v3
      with:
        go-version: 1.19
        cache: true
    - name: Build for linux
      run: GOOS=linux GOARCH=amd64 go build -o bin/main main.go
    - name: Serverless deploy
      uses: serverless/[email protected]
      with:
        args: deploy
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

And that's it.

You can also use this Repo michaelhenry/go-gin-lambda as a template.