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.7k
ecspressoの設計思想に至る道 / sekkeinight2025
fujiwara3
12
2.8k
さくらのIaaS基盤のモニタリングとOpenTelemetry/OSC Hokkaido 2025
fujiwara3
3
1.2k
監視のこれまでとこれから/sakura monitoring seminar 2025
fujiwara3
11
5.2k
k6による負荷試験 入門から日常的な実践まで/Re:TechTalk #01
fujiwara3
2
130
困難を「一般解」で解く
fujiwara3
10
3.8k
「隙間家具OSS」に至る道/Fujiwara Tech Conference 2025
fujiwara3
7
13k
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
[ JAWS-UG 東京 CommunityBuilders Night #2 ]SlackとAmazon Q Developerで 運用効率化を模索する
sh_fk2
1
160
Skrub: machine-learning with dataframes
gaelvaroquaux
0
120
Language Update: Java
skrb
2
280
Webブラウザ向け動画配信プレイヤーの 大規模リプレイスから得た知見と学び
yud0uhu
0
210
AI エージェントとはそもそも何か? - 技術背景から Amazon Bedrock AgentCore での実装まで- / AI Agent Unicorn Day 2025
hariby
4
1.2k
研究開発と製品開発、両利きのロボティクス
youtalk
1
470
allow_retry と Arel.sql / allow_retry and Arel.sql
euglena1215
1
150
Function Body Macros で、SwiftUI の View に Accessibility Identifier を自動付与する/Function Body Macros: Autogenerate accessibility identifiers for SwiftUI Views
miichan
2
170
MCPで変わる Amebaデザインシステム「Spindle」の開発
spindle
PRO
3
2.9k
「魔法少女まどか☆マギカ Magia Exedra」での負荷試験の実践と学び
gree_tech
PRO
0
600
Nstockの一人目エンジニアが 3年間かけて向き合ってきた セキュリティのこととこれから〜あれから半年〜
yo41sawada
0
210
250905 大吉祥寺.pm 2025 前夜祭 「プログラミングに出会って20年、『今』が1番楽しい」
msykd
PRO
1
480
Featured
See All Featured
Documentation Writing (for coders)
carmenintech
74
5k
It's Worth the Effort
3n
187
28k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
4 Signs Your Business is Dying
shpigford
184
22k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.6k
Git: the NoSQL Database
bkeepers
PRO
431
66k
For a Future-Friendly Web
brad_frost
180
9.9k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
How to Ace a Technical Interview
jacobian
279
23k
Thoughts on Productivity
jonyablonski
70
4.8k
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" }