Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
シングルバイナリにこだわる - AWS Lambda編 / Nature Bath vol.6
Search
FUJIWARA Shunichiro
November 18, 2020
Technology
4
3k
シングルバイナリにこだわる - AWS Lambda編 / Nature Bath vol.6
Nature Bath vol.6【勉強会】みんなのGo言語 執筆陣による「Go開発・運用の現場」の発表資料です
https://nature.connpass.com/event/194611/
FUJIWARA Shunichiro
November 18, 2020
Tweet
Share
More Decks by FUJIWARA Shunichiro
See All by FUJIWARA Shunichiro
alecthomas/kong はいいぞ
fujiwara3
6
1.3k
ecspressoの設計思想に至る道 / sekkeinight2025
fujiwara3
12
2.3k
さくらのIaaS基盤のモニタリングとOpenTelemetry/OSC Hokkaido 2025
fujiwara3
3
1k
監視のこれまでとこれから/sakura monitoring seminar 2025
fujiwara3
11
4.9k
k6による負荷試験 入門から日常的な実践まで/Re:TechTalk #01
fujiwara3
2
110
困難を「一般解」で解く
fujiwara3
10
3.7k
「隙間家具OSS」に至る道/Fujiwara Tech Conference 2025
fujiwara3
7
12k
alecthomas/kong はいいぞ / kamakura.go#7
fujiwara3
1
1.1k
ISUCONに強くなるかもしれない日々の過ごしかた/Findy ISUCON 2024-11-14
fujiwara3
11
1.4k
Other Decks in Technology
See All in Technology
AI時代の経営、Bet AI Vision #BetAIDay
layerx
PRO
1
1.6k
Gemini in Android Studio - Google I/O Bangkok '25
akexorcist
0
180
LLM開発を支えるエヌビディアの生成AIエコシステム
acceleratedmu3n
0
370
VLMサービスを用いた請求書データ化検証 / SaaSxML_Session_1
sansan_randd
0
210
Kiroから考える AIコーディングツールの潮流
s4yuba
4
630
AI人生苦節10年で会得したAIがやること_人間がやること.pdf
shibuiwilliam
1
270
2時間で300+テーブルをデータ基盤に連携するためのAI活用 / FukuokaDataEngineer
sansan_randd
0
120
Bet "Bet AI" - Accelerating Our AI Journey #BetAIDay
layerx
PRO
4
1.4k
オブザーバビリティプラットフォーム開発におけるオブザーバビリティとの向き合い / Hatena Engineer Seminar #34 オブザーバビリティの実現と運用編
arthur1
0
330
帳票構造化タスクにおけるLLMファインチューニングの性能評価
yosukeyoshida
1
230
AI コードレビューが面倒すぎるのでテスト駆動開発で解決しようとして読んだら、根本的に俺の勘違いだった
mutsumix
0
160
Power Automate のパフォーマンス改善レシピ / Power Automate Performance Improvement Recipes
karamem0
0
290
Featured
See All Featured
It's Worth the Effort
3n
185
28k
Adopting Sorbet at Scale
ufuk
77
9.5k
Side Projects
sachag
455
43k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
283
13k
A Tale of Four Properties
chriscoyier
160
23k
Documentation Writing (for coders)
carmenintech
73
5k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
Writing Fast Ruby
sferik
628
62k
Navigating Team Friction
lara
188
15k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
870
A Modern Web Designer's Workflow
chriscoyier
695
190k
Transcript
シングルバイナリにこだわる - AWS Lambda 編 2020.11.18 Nature Bath vol.6 ⾯⽩法⼈カヤック
藤原俊⼀郎 @fujiwara
@fujiwara github.com/kayac/ecspresso Amazon ECS デプロイツール github.com/fujiwara/lambroll AWS Lambda デプロイツール
AWS Lambda を何の⾔語で書いていますか? Node.js Python Ruby Java Go .NET Custom
Runtime Bash Perl COBOL...
Go で Lambda を書くと嬉しい ランタイムの寿命に影響されにくい デプロイするものはビルド済のx86_64バイナリ = ⾔語のEoLに影響されない 起動も実⾏も速い Goが好き
Go で Lambda を書く https://github.com/aws/aws-lambda-go#getting-started // main.go package main import
( "github.com/aws/aws-lambda-go/lambda" ) func hello() (string, error) { return "Hello ƛ!", nil } func main() { // Make the handler available for Remote Procedure Call by AWS Lambda lambda.Start(hello) } この main.go をビルドして Zip に含めて Handler として呼ぶ
kayac/s3-object-router https://github.com/kayac/s3-object-router S3 に置かれたObjectを指定したルールで切り分ける君 {"tag": "app.info", "source": "stdout", "message": "xxx"}
{"tag": "app.warn", "source": "stderr", "message": "yyy"} {"tag": "app.info", "source": "stdout", "message": "zzz"} ルール path/to/{{ .tag }}/{{ .source }} で処理すると path/to/app.info/stdout/... に 13⾏⽬が path/to/app.warn/stderr/... に 2⾏⽬が保存される S3 Event Notification でこの Lambda を呼んで実⾏する
Lambda の典型的なユースケース = S3 イベントトリガ CLI から S3 URL s3://bucket/object
を指定して実⾏できたら便利ですよね! 開発中とかリカバリとか世の中にはいろいろある いちいち Lambda にデプロイして aws lambda invoke-function ... より CLI で叩きたい $ aws lambda invoke-function \ --function-name s3-object-router \ --payload '{"Records":[{"s3":{"bucket":{"name":"bucket-name"},"object":{"key":"object-key"}}}]}' ではなく $ s3-object-router s3://bucket-name/object-key ってしたい
「シングルバイナリにこだわる」とは Lambda⽤とCLI⽤のバイナリを個別にビルドするのは無駄では??? main.go がちょっと違うだけで本体はほぼ同じ ビルド時間2倍、サイズも2倍 ファイルの管理も⾯倒 Lambda でも CLI でも動く1個のバイナリを
GitHub releases においておきたい
Lambda でも CLI でも⾃動判別してよしなに動くコード 環境変数 AWS_EXECUTION_ENV を⾒て判別! if strings.HasPrefix(os.Getenv("AWS_EXECUTION_ENV"), "AWS_Lambda")
|| os.Getenv("AWS_LAMBDA_RUNTIME_API") != "" { // Lambda として動いている lambda.Start(handler) } else { // Lambda ではない // ... } 2020-11-18現在 カスタムランタイム provided.al2 で AWS_EXECUTION_ENV が設定されない不具合 AWS_LAMBDA_RUNTIME_API があるかも⾒たほうがよい サポートケースで報告済、近⽇修正予定とのこと
コマンドラインオプションは環境変数でも設定できるように Lambdaでは起動時にコマンドライン引数を指定できないので flag は環境変数でも指定できるようにしておく $ myapp -port 8080 $ MYAPP_PORT=8080
myapp Lambda に限らずコンテナでも環境変数のほうが個別に上書きできて便利
コマンドラインオプションは環境変数でも設定できるように flag.VisitAll() を使うと… func main() { var port int flag.IntVar(&port,
"port", 8080, "port number") flag.VisitAll(func(f *flag.Flag) { name := "MYAPP_" + strings.ToUpper(f.Name) if v, exists := os.LookupEnv(name); exists { f.Value.Set(v) } }) flag.Parse() fmt.Printf("%d\n", port) }
fujiwara/ridge https://github.com/fujiwara/ridge API Gateway REST/HTTP API ALB Lambda の HTTP
ハンドラを net/http で書ける君 package main import ( "fmt" "net/http" "github.com/fujiwara/ridge" ) func main() { var mux = http.NewServeMux() mux.HandleFunc("/", handleRoot) ridge.Run(":8080", "/", mux) } func handleRoot(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain") fmt.Fprintln(w, "Hello World") }
ridge を使ったバイナリでも⾃動判別 Lambda として動作する場合 Lambda payload を net/http.Request に変換 handler
アプリケーション に *Request ResponseWriter を渡す net/http.ResponseWriter に書かれたものを Lambda response に変換 Lambda 以外で動作する場合 net/http.Server でネイティブな HTTP server として動作 EC2 ECS 等でもそのまま動く!
【PR】 Lambda のデプロイには fujiwara/lambroll を https://github.com/fujiwara/lambroll Lambda Function のみ をデプロイすることに特化したミニマルなデプロイツール
他のものは⾃分で⽤意できるんだ!という⼈向け function.json とGoのビルド済バイナリだけで lambroll deploy できます { "FunctionName": "my-go-lambda", "Handler": "handler", "MemorySize": 256, "Role": "arn:aws:iam::123456789012:role/lambda", "Runtime": "go1.x" }