[Golang]シングルバイナリのWebアプリケーションをElastic Beanstalkで実行する

はじめに

GolangでWebアプリケーションを作成して、シングルバイナリに纏めたものをElastic Beanstalkで実行してみました。以下、そのソースと手順となります。

ソースについて

Webアプリケーションはechoを使って実装しました。

echoのドキュメント内のCRUD Recipeを元に、(実運用を考慮して)handlerの部分を別ファイルに切り出して実装しました。また、Elastic Beanstalkで実行するためportは5000としてあります。

main.go

package main

import (
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"

	"github.com/SrcHndWng/go-echo-elasticbeanstalk-sample/handlers"
)

func main() {
	e := echo.New()

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// Routes
	e.POST("/users", handlers.CreateUser)
	e.GET("/users/:id", handlers.GetUser)
	e.PUT("/users/:id", handlers.UpdateUser)
	e.DELETE("/users/:id", handlers.DeleteUser)

	// Start server
	e.Logger.Fatal(e.Start(":5000"))
}

handlers/users.go

package handlers

import (
	"net/http"
	"strconv"

	"github.com/labstack/echo"
)

type (
	user struct {
		ID   int    `json:"id"`
		Name string `json:"name"`
	}
)

var (
	users = map[int]*user{}
	seq   = 1
)

// CreateUser Handler
func CreateUser(c echo.Context) error {
	u := &user{
		ID: seq,
	}
	if err := c.Bind(u); err != nil {
		return err
	}
	users[u.ID] = u
	seq++
	return c.JSON(http.StatusCreated, u)
}

// GetUser Handler
func GetUser(c echo.Context) error {
	id, _ := strconv.Atoi(c.Param("id"))
	return c.JSON(http.StatusOK, users[id])
}

// UpdateUser Handler
func UpdateUser(c echo.Context) error {
	u := new(user)
	if err := c.Bind(u); err != nil {
		return err
	}
	id, _ := strconv.Atoi(c.Param("id"))
	users[id].Name = u.Name
	return c.JSON(http.StatusOK, users[id])
}

// DeleteUser Handler
func DeleteUser(c echo.Context) error {
	id, _ := strconv.Atoi(c.Param("id"))
	delete(users, id)
	return c.NoContent(http.StatusNoContent)
}

デプロイの手順

事前準備

Elastic Beanstalkで

  • Web Server環境
  • プラットフォームはGoを選択

して環境を作成しておいてください。

ソースバンドル作成

ソースをビルドしてシングルバイナリを作成し、Elastic Beanstalkがアプリを実行するための指示を記述したProcfileを用意します。シングルバイナリとProcfileをzipで圧縮してソースバンドルを作成します。

1. build

$ GOARCH=amd64 GOOS=linux go build -o build/bin/application

2. zip

$ cd build
$ zip -r ../app.zip *
$ cd ..

デプロイ

上記で作成したソースバンドル(app.zip)をElastic Beanstalkにデプロイします。

動作確認

以下のように登録、取得をcurlで実行して動作していることを確認します。

$ curl -X POST \
    -H 'Content-Type: application/json' \
    -d '{"name":"Joe Smith"}' \
    <Elastic BeanstalkアプリケーションのURL>/users
$ curl <Elastic BeanstalkアプリケーションのURL>/users/1

まとめ

ソースを実装する → シングルバイナリに纏める → デプロイする、というシンプルな流れになったかと思います。何かの参考になれば幸いです。

今回作成したソースは以下となります。
go-echo-elasticbeanstalk-sample

参考サイト

  • https://dev.classmethod.jp/cloud/aws/elastic-beanstalk-supported-go/
  • https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/go-environment.html
  • https://stackoverflow.com/questions/42209109/deploying-golang-app-in-cmd-folder-to-aws-beanstalk
  • https://binhbv.wordpress.com/2017/03/20/deploying-a-simple-golang-application-to-aws-elastic-beanstalk-echo-framework/
  • https://echo.labstack.com/cookbook/crud