Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
シングルバイナリにこだわる - AWS Lambda編 / Nature Bath vol.6
FUJIWARA Shunichiro
November 18, 2020
Technology
4
1.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
1年間のポストモーテム運用とそこから生まれたツール sre-advisor / SRE NEXT 2022
fujiwara3
5
2.6k
気軽に始めるGraviton2マネージドサービスによるコスト最適化 / Amazon Game Tech Night #23
fujiwara3
4
1.2k
Amazon Auroraを活用したソーシャルゲームの複数ワールドデータ統合 / AWS Dev Day Online Japan
fujiwara3
10
4.7k
GitHub Actionsに「強い」AWSの権限を渡したい / AWS credentials on Actions
fujiwara3
7
11k
ecspresso exec
fujiwara3
0
590
がんばらないスポットインスタンス運用 / Spot-instance-Matsuri
fujiwara3
1
2.8k
knockrd / kichijojipm23
fujiwara3
1
170
Webサービスを1日10回デプロイするための取り組み / SRE NEXT 2020
fujiwara3
22
24k
クラウドネイティブな監視をMackerelで / Mackerel Day#2
fujiwara3
4
3.7k
Other Decks in Technology
See All in Technology
Embedded SRE at Mercari
tcnksm
0
750
CADDi HCMC Technology Center
caddi_eng
0
200
Salesforce女子部-権限についてまとめてみたその1
sfggjp
0
170
How We Foster Reliability in Diversity
nari_ex
PRO
8
2k
~スタートアップの人たちに捧ぐ~ 監視再入門 in AWS
track3jyo
PRO
30
8.3k
エンジニアインターンの採用〜実際の開発への関与について for EM meetup#10
dmiyamoto
1
250
mROS 2のススメ
takasehideki
0
280
ZOZOTOWNのProduction Readiness Checklistと信頼性向上の取り組み / Improvement the reliability of ZOZOTOWN with Production Readiness Checklist
akitok_
5
1.3k
AWS全体のセキュリティ管理と快適なセキュリティ運用
cmusudakeisuke
2
10k
Learning from AWS Customer Security Incidents [2022]
ramimac
0
320
暗号資産ウォレット入門(MetaMaskの入門~NFTの購入~詐欺の注意事項など)
kayato
2
140
ITエンジニアを取り巻く環境とキャリアパス / A career path for Japanese IT engineers
takatama
0
550
Featured
See All Featured
XXLCSS - How to scale CSS and keep your sanity
sugarenia
236
1M
Clear Off the Table
cherdarchuk
79
280k
Side Projects
sachag
449
37k
Gamification - CAS2011
davidbonilla
75
3.9k
How STYLIGHT went responsive
nonsquared
85
3.9k
What the flash - Photography Introduction
edds
61
9.8k
Designing the Hi-DPI Web
ddemaree
272
32k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
655
120k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
119
28k
jQuery: Nuts, Bolts and Bling
dougneiner
56
6.4k
Scaling GitHub
holman
451
140k
Robots, Beer and Maslow
schacon
152
7.1k
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" }