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
2.8k
シングルバイナリにこだわる - 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 はいいぞ / kamakura.go#7
fujiwara3
1
300
ISUCONに強くなるかもしれない日々の過ごしかた/Findy ISUCON 2024-11-14
fujiwara3
9
1.1k
「最高のチューニング」をしないために / hack@delta 24.10
fujiwara3
21
4k
AWS Lambdaで実現するスケーラブルで低コストなWebサービス構築/YAPC::Hakodate2024
fujiwara3
10
4.6k
CEL(Common Expression Language)で書いた条件にマッチしたIAM Policyを見つける / iam-policy-finder
fujiwara3
2
1.5k
awslim - Goで実装された高速なAWS CLIの代替品を作った/layerx.go#1
fujiwara3
6
760
AWS CLIの起動が重くてつらいので aws-sdk-client-go を書いた / kamakura.go#6
fujiwara3
7
10k
コードを書く隙間を見つけて生きていく技術/Findy 思考の現在地
fujiwara3
31
7.1k
fujiwara-ware OSSをひたすら紹介する/ya8-2024
fujiwara3
8
810
Other Decks in Technology
See All in Technology
How to be an AWS Community Builder | 君もAWS Community Builderになろう!〜2024 冬 CB募集直前対策編?!〜
coosuke
PRO
2
2.9k
株式会社ログラス − エンジニア向け会社説明資料 / Loglass Comapany Deck for Engineer
loglass2019
3
32k
3年でバックエンドエンジニアが5倍に増えても破綻しなかったアーキテクチャ そして、これから / Software architecture that scales even with a 5x increase in backend engineers in 3 years
euglena1215
8
2.7k
[トレノケ雲の会 mod.13] 3回目のre:Inventで気づいたこと -CloudOperationsを添えて-
shintaro_fukatsu
0
110
watsonx.ai Dojo #5 ファインチューニングとInstructLAB
oniak3ibm
PRO
0
190
なぜCodeceptJSを選んだか
goataka
0
170
生成AIをより賢く エンジニアのための RAG入門 - Oracle AI Jam Session #20
kutsushitaneko
4
290
LINEスキマニにおけるフロントエンド開発
lycorptech_jp
PRO
0
340
レンジャーシステムズ | 会社紹介(採用ピッチ)
rssytems
0
260
多領域インシデントマネジメントへの挑戦:ハードウェアとソフトウェアの融合が生む課題/Challenge to multidisciplinary incident management: Issues created by the fusion of hardware and software
bitkey
PRO
2
110
スタートアップで取り組んでいるAzureとMicrosoft 365のセキュリティ対策/How to Improve Azure and Microsoft 365 Security at Startup
yuj1osm
0
230
宇宙ベンチャーにおける最近の情シス取り組みについて
axelmizu
0
120
Featured
See All Featured
How to train your dragon (web standard)
notwaldorf
88
5.7k
It's Worth the Effort
3n
183
28k
Side Projects
sachag
452
42k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
111
49k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Adopting Sorbet at Scale
ufuk
73
9.1k
How To Stay Up To Date on Web Technology
chriscoyier
789
250k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
170
Designing Experiences People Love
moore
138
23k
Typedesign – Prime Four
hannesfritz
40
2.4k
Six Lessons from altMBA
skipperchong
27
3.5k
Statistics for Hackers
jakevdp
796
220k
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" }