お客さんとサーバレス勉強モブプロをやることになりました。 AWSによるサーバーレスアーキテクチャ を参考書籍として、Node.js で書かれている内容を全て Go にしてみようというもの。ワタシ、Python 以外で Lambda 書く自信ナイ。。そもそも Go 書いたことない。。
ということで、勉強がてら
- Golang で Lambda ファンクションを作る
- ↑ を SAM 化する
をやってみましたので、手順についてメモします。「Go のお作法的にちがうだろー」などあればぜひご教示いただければと思います。
- 作者: 長尾高弘
- 出版社/メーカー: 翔泳社
- 発売日: 2018/03/14
- メディア: Kindle版
- この商品を含むブログを見る
Go で Lambda ファンクションを作るまで
ローカル環境を整える
まずは Go のインストールです。( brew update
してなかったからか Go のバージョンが古くもう一度入れ直すはめに。後述します。)
$ brew install go $ go version go version go1.6.3 darwin/amd64
次に GOPATH
なるものをインストールし go get
したときのパッケージ?モジュール?の配置先を指定する必要があるとのこと。
$ more ~/.bash_profile -> `export GOPATH=$HOME/go` を追加する $ source ~/.bash_profile
試しに Hello World してみる。
package main import "fmt" func main() { hello() } func hello() { fmt.Println("Hello, go world!!") }
$ go build helloworld.go $ ./helloworld Hello, go world!!
動きました:)
Lambda 用のパッケージを導入
続いて、Lambda 用のパッケージの導入。
$ go get -u github.com/aws/aws-lambda-go/lambda unrecognized import path "context"
unrecognized import path "context"
??🤔
どうやら Go のバージョンが古い模様🤔
Getting Started - The Go Programming Language
こちらから Go の最新バージョンをインストールし直し、配置場所を変更(これ正しいのか自信ないです。が、動作はします。)。
$ mv /usr/local/go/bin/go /usr/local/bin/
再度、Go パッケージの導入。
$ go get -u github.com/aws/aws-lambda-go/lambda
成功した模様。最初に設定した GOPATH
を見ると何やらインストールされているようです。( GOPATH
ってどこに設定すべきなのだろう? npm
のようにプロジェクト毎に配置先変えるべきものな気もするけど。追って調べる。)
$ ll ~/go/src/github.com/aws/aws-lambda-go/ total 36 drwxr-xr-x 15 hogehoge staff 510 4 19 01:16 . drwxr-xr-x 3 hogehoge staff 102 4 19 01:16 .. drwxr-xr-x 15 hogehoge staff 510 4 19 01:26 .git -rw-r--r-- 1 hogehoge staff 974 4 19 01:16 .travis.yml -rw-r--r-- 1 hogehoge staff 893 4 19 01:16 Gopkg.lock -rw-r--r-- 1 hogehoge staff 534 4 19 01:16 Gopkg.toml -rw-r--r-- 1 hogehoge staff 11359 4 19 01:16 LICENSE -rw-r--r-- 1 hogehoge staff 879 4 19 01:16 LICENSE-LAMBDACODE -rw-r--r-- 1 hogehoge staff 300 4 19 01:16 LICENSE-SUMMARY -rw-r--r-- 1 hogehoge staff 2608 4 19 01:16 README.md drwxr-xr-x 10 hogehoge staff 340 4 19 01:16 cfn drwxr-xr-x 3 hogehoge staff 102 4 19 01:16 cmd drwxr-xr-x 50 hogehoge staff 1700 4 19 01:16 events drwxr-xr-x 11 hogehoge staff 374 4 19 01:16 lambda drwxr-xr-x 4 hogehoge staff 136 4 19 01:16 lambdacontext
次にソースコードを作成します。といっても、AWS 公式 GitHub からそのまま持ってきただけです。
package main import ( "github.com/aws/aws-lambda-go/lambda" ) func hello() (string, error) { return "Hello World!", nil } func main() { lambda.Start(hello) }
ビルドして、zip 化します。ビルド時は GOOS
と GOARCH
を指定する必要があります。
$ GOOS=linux GOARCH=amd64 go build sample.go $ zip -r sample.zip ./sample
出来上がった sample.zip
をアップロードしてみます。ハンドラを sample
とするのを忘れないように。
実行してみると、
いい感じです😃
SAM 化する
せっかくなので SAM 化してみます。下の記事を参考にしています。
まず、テンプレートの作成です。IAM ロールには DynamoDB 権限だけ振ってます(DynamoDB 参照していませんが、、そのうち。)。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: Go on Lambda sample. # SAM Resources Resources: SamSampleLambda: Type: AWS::Serverless::Function Properties: CodeUri: sample.zip Handler: sample Runtime: go1.x Role: !GetAtt GoOnLambdaIamRole.Arn Timeout: 30 GoOnLambdaIamRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: "sts:AssumeRole" Policies: - PolicyName: "dynamodb_for_go_onlambda" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: "dynamodb:*" Resource: "*"
次にテンプレート置き場の S3 バケットを作ります。 --profile
指定は各環境に応じて置き換えて(削除して)ください。
aws s3 mb s3://(★任意のバケット名) --profile sam-sample
最後にデプロイ用のシェルを作ります。
GOOS=linux GOARCH=amd64 go build sample.go zip -r sample.zip ./sample aws cloudformation package \ --template-file template.yaml \ --s3-bucket (★任意のバケット名) \ --output-template-file packaged-template.yaml \ --profile sam-sample aws cloudformation deploy \ --template-file packaged-template.yaml \ --stack-name (★任意のバケット名) \ --capabilities CAPABILITY_IAM \ --profile sam-sample
デプロイしてみます。上手くいったでしょうか??
$ sh deploy.sh
まとめ
Python で SAM を学んでおくと、言語が変わってもナレッジをほぼそのまま使える!という感想を得ました。ぜひ SAM シリーズやってみてください!!(宣伝)。