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
「隙間家具OSS」に至る道/Fujiwara Tech Conference 2025
fujiwara3
7
10k
alecthomas/kong はいいぞ / kamakura.go#7
fujiwara3
1
800
ISUCONに強くなるかもしれない日々の過ごしかた/Findy ISUCON 2024-11-14
fujiwara3
10
1.2k
「最高のチューニング」をしないために / hack@delta 24.10
fujiwara3
21
4.2k
AWS Lambdaで実現するスケーラブルで低コストなWebサービス構築/YAPC::Hakodate2024
fujiwara3
10
5.7k
CEL(Common Expression Language)で書いた条件にマッチしたIAM Policyを見つける / iam-policy-finder
fujiwara3
2
1.7k
awslim - Goで実装された高速なAWS CLIの代替品を作った/layerx.go#1
fujiwara3
6
810
AWS CLIの起動が重くてつらいので aws-sdk-client-go を書いた / kamakura.go#6
fujiwara3
7
11k
コードを書く隙間を見つけて生きていく技術/Findy 思考の現在地
fujiwara3
31
7.2k
Other Decks in Technology
See All in Technology
設計を積み重ねてシステムを刷新する
sansantech
PRO
0
160
【5分でわかる】セーフィー エンジニア向け会社紹介
safie_recruit
0
18k
2/18 Making Security Scale: メルカリが考えるセキュリティ戦略 - Coincheck x LayerX x Mercari
jsonf
0
150
生成AI×財務経理:PoCで挑むSlack AI Bot開発と現場巻き込みのリアル
pohdccoe
1
580
【詳説】コンテンツ配信 システムの複数機能 基盤への拡張
hatena
0
220
クラウド食堂とは?
hiyanger
0
110
Autonomous Database Serverless 技術詳細 / adb-s_technical_detail_jp
oracle4engineer
PRO
17
45k
「正しく」失敗できる チームの作り方 〜リアルな事例から紐解く失敗を恐れない組織とは〜 / A team that can fail correctly
i35_267
4
830
OPENLOGI Company Profile
hr01
0
60k
Visualize, Visualize, Visualize and rclone
tomoaki0705
9
81k
エンジニアが加速させるプロダクトディスカバリー 〜最速で価値ある機能を見つける方法〜 / product discovery accelerated by engineers
rince
4
560
急成長する企業で作った、エンジニアが輝ける制度/ 20250227 Rinto Ikenoue
shift_evolve
0
110
Featured
See All Featured
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.3k
Faster Mobile Websites
deanohume
306
31k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.4k
Side Projects
sachag
452
42k
GraphQLの誤解/rethinking-graphql
sonatard
68
10k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
6
570
Code Review Best Practice
trishagee
67
18k
Navigating Team Friction
lara
183
15k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3k
Optimising Largest Contentful Paint
csswizardry
34
3.1k
Why You Should Never Use an ORM
jnunemaker
PRO
55
9.2k
Automating Front-end Workflow
addyosmani
1368
200k
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" }