Oredemo understand series -Build and deploy Serverless Framework Golang with Docker container


俺です。

PCにシコシコ道具を整える人生が辛くなりました。
PCにぶちこむのはDockerとエディタだけでいいじゃないかと。
ビルドとデプロイといった役割はDockerコンテナに任せてしまえばいいじゃないかということで、
今回はじめてServerless Frameworkを用いたSlack appをDeployした経験を、
1億年と二千年前から何度目煎じなネタですがメモを残しておこうと思います。

きっかけ

@T_Sumisaki にslackでEC2止めたりアゲたりするslack appつくってもらい、
いざ自分のAWSのアカウントへビルド+デプロイすっかと思ったけどオラのmacOSにGolangとServerlessが入ってなかったぞ。
これからセットアップとかオラわくわくすっぞ!

ああめんどくさ。

ビルドとデプロイをコンテナに任せる構成

PCにDockerが入ってたのでこのようにしました。

  • ローカルPCのディレクトリにソースコードをgithubからcloneしてくる
  • ソースコードは自分の好きなエディタで弄る
  • GolangのコードビルドはGolang1.XなDockerコンテナに任せる
  • ServerlesアプリケーションのDeployはserverlessなDockerコンテナに任せる

ローカルPCとコンテナのデータ共有

ローカルPCにgit cloneしたrepositoryディレクトリはDockerのVolumeで共有します。
Dockerコンテナ上でビルド実行/Serverlessアプリケーションのデプロイを実現できます。

Dockerコンテナを使ったGolangのビルド

  • -vでローカルPCのソースコードディレクトリをDockerコンテナの /go/src/app と共有する
  • --rmでDockerコンテナの実行後にイメージを削除する
cd <repository>
docker run --rm -v "$PWD":/go/src/app -w /go/src/app awscli-command:latest make dep-ensure

Dockerコンテナを使ったServerlessアプリケーションのデプロイ

  • Dockerhubで公開されているserverlessコンテナを使います
  • serverlessコンテナ起動時にローカルPCの~/.aws/credentials-vで共有する
  • serverlessコンテナ起動時にローカルPCのソースコードディレクトリを-vで共有する
  • デプロイ対象のAWSのアカウントを~/.aws/credentialsのエントリで指定するようにAWS_PROFILEAWS_DEFAULT_REGION-eオプションで指定する
  • -rmでDockerコンテナの実行後にイメージを削除する

※ローカルPCかつdocker saveでコンテナをexportすることはないものの~/.aws/credentialsを共有するのがこえー方はsaml2awsをserverlessコンテナに入れ込み、一時的なトークンを渡しちゃえばいいと思います。

cd <repository>
docker run --rm -v ${HOME}/.aws/credentials:/root/.aws/credentials -v ${PWD}:/go/src/app \
-e AWS_PROFILE=${aws_profile} -e AWS_DEFAULT_REGION=${region} \
-w /go/src/app \
softinstigate/serverless sls deploy

Dockerでwrappingしたことでの引数長い問題をどうするか

DockerコンテナでGolangのビルドとServerless Frameworkのデプロイを実現できるようになりますが、
引数が長くて腱鞘炎になる問題が残ります。
これら何度も繰り返す内容はMakefileで解決します。

引数長くて辛い問題は例えば、
Golang用コンテナのビルドだったり...

docker build -f Dockerfile . -t awscli-command:latest

depの依存関係解決だったり..

docker run --rm -v "$PWD":/go/src/app -w /go/src/app awscli-command:latest make dep-ensure

Golangのビルドだったり...

docker run --rm -v "$PWD":/go/src/app -w /go/src/app awscli-command:latest make build-golang

Serverlessのdeployだったり...

docker run --rm -v ${HOME}/.aws/credentials:/root/.aws/credentials -v ${PWD}:/go/src/app \
-e AWS_PROFILE=${aws_profile} -e AWS_DEFAULT_REGION=${region} \
-w /go/src/app \
softinstigate/serverless sls deploy

よく使うコマンドはshell historyではなくMakefileに保管しておきます。

  • Makefile
aws_profile = default
region = us-east-1

build-docker-golang:
    docker build -f Dockerfile . -t awscli-command:latest
dep-ensure:
    dep ensure
build-golang:
    go get github.com/aws/aws-lambda-go/lambda
    env GOOS=linux go build -ldflags="-s -w" -o bin/igniter handler/igniter/main.go
    env GOOS=linux go build -ldflags="-s -w" -o bin/interaction handler/interaction/main.go

run-dep-ensure:
    docker run --rm -v "$PWD":/go/src/app -w /go/src/app awscli-command:latest make dep-ensure

run-build:
ifeq ($(OS),Windows_NT)
# for Windows(ToDo: get folder path)
    docker run --rm -v "$PWD":/go/src/app -w /go/src/app awscli-command:latest make build-golang
else
    docker run --rm -v "$PWD":/go/src/app -w /go/src/app awscli-command:latest make build-golang
endif

sls-deploy: 
    docker run --rm -v ${HOME}/.aws:/root/.aws -v ${PWD}:/go/src/app \
    -e AWS_PROFILE=${aws_profile} -e AWS_DEFAULT_REGION=${region} \
    -w /go/src/app \
    softinstigate/serverless sls deploy
  • Golangのビルド
$ make build-docker-golang
$ make run-dep-ensure
$ make run-build
  • Serverlessアプリケーションのデプロイ
$ make sls-deploy aws_profile=MYAWSPROFILE region=ap-northeast-1

これでDockerとエディタが入ってるPCならServerless Lambda Golangな環境のビルドとデプロイを実現できるようになりました。

今更ながら便利ですねーコンテナ。

ということでawscliなslack appのUIいじるぞー。

finish