Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

AWS Lambda in Golang

1,941 views

Published on

JAWS-UG沖縄 真夏の熱すぎるサーバレス祭り! 2016年08月でお話した資料です。

Published in: Internet
  • Be the first to comment

AWS Lambda in Golang

  1. 1. @k_nishijima AWS Lambda in Golang JAWS-UG沖縄 真夏の熱すぎるサーバレス祭り! 2016年08月 @k_nishijima The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/) The design is licensed under the Creative Commons 3.0 Attributions license.
  2. 2. @k_nishijima 皆さんこんにちは! Go言語でコード書いてますか? 2
  3. 3. @k_nishijima 仕事で書いてる人? 趣味で書いてる人? 書いてない人? 3
  4. 4. @k_nishijima 今日は実践 「Go言語でLambda関数を書く」 をお届けします 4
  5. 5. @k_nishijima あんた誰? 5 西島 幸一郎 / にしじま こういちろう
 アールスリーインスティテュート ソリューションアーキテクト https://www.r3it.com
 大阪の会社に所属、宜野湾の自宅から100%リモートワーク okinawa.goのコアメンバー JAWS−UG沖縄のコアメンバー ハッカーズチャンプルー実行委員長 ご質問などあればFacebook/Twitterなどでお気軽に〜♪ @k_nishijima nishijima.koichiro
  6. 6. @k_nishijima アジェンダ 6 ๏ AWSとGolangの関係をおさらい ๏ 利用ツールの紹介 ๏ 実際のLambda関数の書き方 ๏ 簡単なハンズオン
  7. 7. @k_nishijima AWSとGo言語 7
  8. 8. @k_nishijima AWSとGo言語 8 ๏ AWS SDK for Go あります
 https://aws.amazon.com/jp/sdk-for-go/
 ๏ 新サービスにもかなりの勢いで追随してます
 https://github.com/aws/aws-sdk-go
 ๏ ただし今のところ公式にはLambdaの対応言語ではありません
 【Node.js (JavaScript)、Python、および Java (Java 8 互換)】
 https://aws.amazon.com/jp/lambda/faqs/
  9. 9. @k_nishijima え、じゃあどうやって LambdaをGoで書くの? 9
  10. 10. @k_nishijima 利用ツールの紹介 10
  11. 11. @k_nishijima 三種の神器:利用ツールの紹介 11 ๏ APEX : Lambda関数のデプロイ管理
 http://apex.run/
 https://github.com/apex/apex ๏ Simple API Gateway : API Gatewayの設定
 https://github.com/horike37/simple-api-gateway
 ๏ Terraform : インフラの管理 https://www.terraform.io/
  12. 12. @k_nishijima 12 ๏ Lambda関数の管理に特化したツール
 ๏ 環境構築はTerraformを組み合わせて使うことを想定 ๏ Node.jsのshimの魔法によりGo言語の実行をサポート
 →このおかげでGoでLambdaが書ける! APEX
  13. 13. @k_nishijima 13 ๏ 個人的にも支援中 ๏ コードで貢献したかったがGoスキルが足りず…
 ひとまずお金で支援することにした(^_^;) APEX
  14. 14. @k_nishijima Simple API Gateway 14 ๏ API Gatewayの設定をCLIで行うツール
 ๏ マネコンの設定画面は罠が多すぎるので…
 API作る際にはこれを利用して作るととても楽です
  15. 15. @k_nishijima Simple API Gateway 15 ๏ こっちはコードで貢献できた!
  16. 16. @k_nishijima 16 ๏ みんな大好きHashiCorp社謹製のインフラ管理ツール
 ๏ JSONライクな設定ファイルからインフラを自動生成/破棄 ๏ 組み合わせとしては、IAMの権限設定やLambda以外のリソース 管理に利用すると吉 Terraform
  17. 17. @k_nishijima この辺のツールを使って 実際に何かLambdaを使って
 Web APIを作ってみましょう 17
  18. 18. @k_nishijima お題 問い合わせフォームを
 DynamoDBに保存する API 18
  19. 19. @k_nishijima 実際には 管理者にメールしたり 送信元にメールしたり Slackに通知したり 色々やりたいけど
 その辺は簡単に実装できるので各自! 19
  20. 20. @k_nishijima 20 ๏ https://github.com/k-nishijima/lambda-handson- jawsug-okinawa-201608
 ๏ infra以下にTerraformのtfファイル ๏ lambda以下にLambda関数のファイル ソースリポジトリ
  21. 21. @k_nishijima 21 ๏ Terraformで作られたAWSの環境(IAMロール、DynamoDB) ๏ API GatewayでホストされるWeb API ๏ Goで書かれたLambda関数(APEXでデプロイ) ๏ Goで書かれたコアライブラリ(AWSリソースを利用する実体) 全体構成 Goで書かれたLambdaSimple API Gatewayで設定 HTTPリクエスト Lambdaで動いてるところに API GatewayでHTTP経由で 呼び出すインターフェイス をつけるイメージ
  22. 22. @k_nishijima 実際の開発の流れ 22 1. Terraform でDB環境・IAM実行権限などを設定 2. Goでコーディング、テスト 3. APEXでLambda関数としてデプロイ 4. Simple API GatewayでAPI作成、デプロイ(はじめの1回だけ) 5. APIを叩いてテスト。OK?
 
 問題があれば、2と3と5をぐるぐる繰り返す…
  23. 23. @k_nishijima 23 ๏ インストールは
 https://www.terraform.io/intro/getting-started/install.html ๏ リポジトリのinfraディレクトリのREADME.mdを確認の上、
 “terraform apply"
 ๏ DynamoDBのテーブルとIAM Roleが作られる Terraformで環境構築
  24. 24. @k_nishijima さあGoでコーディング 24 ๏ その前に!
 プロジェクト構成をどうすべきか考える必要がある。
 ๏ 自分の場合は、GOPATH配下にコアライブラリを置き、
 Lambda関数側からはそれを呼ぶ、という形にした。
 ベストかどうかは分からんです・・・教えて偉い人!
  25. 25. @k_nishijima プロジェクト構成(例) 25 コアライブラリ: ~/gopath/src/github.com/k- nishijima/lambda-handson APEX管理配下の
 Lambda関数: ~/lambda-handson/ functions/funcname/ 
 importして
 使う ๏ コアライブラリはそれだけで単体テスト ๏ APEX管理配下の関数からimportして利用
  26. 26. @k_nishijima この構成のメリット 26 ๏ コアライブラリ側の、通常のGo言語のコーディング・デバッグ でほとんど作業は完結する
 (Lambda関数としてのデバッグはほぼ不要) ๏ AWSのサービスを呼び出すものもローカルで完結 ๏ DynamoDB local、GoAws(未使用だけどSNS/SQSエミュレータ)
  27. 27. @k_nishijima コアライブラリのコーディング、テスト 27 ๏ https://github.com/k-nishijima/lambda-handson-golang-201608/ blob/master/dao.go
 ๏ 普通にGoでAWSを利用するコーディング
 (制約はさておき、Lambdaから呼ばれるからといって特殊なコーディ ングはない) ๏ HTTPリクエストを構造体経由で受け取る想定で書くと良い
  28. 28. @k_nishijima コアライブラリのコーディング、テスト 28 ๏ 構造体はJSONとvalidateのアノテーションに注目
 ๏ AWSの権限を取る部分をProfile指定とロール指定 の両対応にしておくと後で便利
 (svcメソッドの部分)
  29. 29. @k_nishijima コアライブラリのコーディング、テスト 29 ๏ テストが終わったら、”go install” しておく
 ※これでAPEX管理下のLambdaから呼び出す準備が整う
 ๏ コアライブラリを改修したら
 再度go installをお忘れなく
  30. 30. @k_nishijima 30 やっと本題(?) GoでLambda関数を書く
  31. 31. @k_nishijima APEXでプロジェクトひな形作成 31 ๏ $ apex -p lambda-handson-201608 init
 でプロジェクト雛形作成
 (-pはプロジェクトを作るときに使うAWS profile名)。
 ๏ Lambda関数の実行用ロールなんかも作ってくれる
 (が、今回はTerraformで作ったロールを使う)
  32. 32. @k_nishijima APEXでプロジェクトひな形作成 32 ├── functions │   └── hello │   └── index.js └── project.json ── 関数ディレクトリ ── ディレクトリ名が関数名suffix ── 実装 ── プロジェクト全体の設定ファイル ๏ Node.jsならそのままindex.jsをいじっていけば hello関数が出来上がる(が、今回は削除する)
  33. 33. @k_nishijima project.json重要 33 ๏ project.jsonはプロジェクト全体の設定ファイル
 ๏ name: 各関数のprefixになる ๏ メモリ量とかタイムアウトとかここで書ける ๏ Lambda関数実行時のroleもここで指定 ๏ 同じような書式で関数ごとの設定もfunction.jsonで可
  34. 34. @k_nishijima GoでLambda関数作成時の注意点 34 ๏ APEXではSTDINとSTDOUTをNodeとGo言語のやり取 りに使うので、例えばロギングなどは必ずSTDERR に出力しないといけない。
 os.Stderr.WriteString(“hoge”) みたいな
  35. 35. @k_nishijima 実際のソース: イベントから構造体への変換 35 func main() { apex.HandleFunc(func(event json.RawMessage, ctx *apex.Context) (interface{}, error) { // リクエストを格納する構造体 var request lambdaHandson.AddValueRequest if err := json.Unmarshal(event, &request); err != nil { return nil, err }
  36. 36. @k_nishijima 実際のソース: json.Unmarshalするときに、JSONアノテーションが効く 36 type AddValueRequest struct { Stage string `json:"stage" valid:"required"` Email string `json:"email" valid:"email,length(1|512),required"` Message string `json:"message" valid:"length(1|1024),required"` } { "stage": "dev", "email": "foo@bar.com", "message": "hello golang"} まあunmarshalだけなら アノテーション書かなくても
 大丈夫だけど・・・
 
 JSONをレスポンスするとき
 アノテーション重要 リクエスト
 のJSON
  37. 37. @k_nishijima 実際のソース: validateはgovalidatorを使ってみました 37 type AddValueRequest struct { Stage string `json:"stage" valid:"required"` Email string `json:"email" valid:"email,length(1|512),required"` Message string `json:"message" valid:"length(1|1024),required"` } ๏ https://github.com/asaskevich/govalidator
 ๏ 他にも同種の便利なパッケージはあると思うので探してみて!
  38. 38. @k_nishijima 実際のソース: 実行したいメソッドを呼ぶ 38 err = dao.Put(request) if err != nil { return nil, err } ๏ Lambda関数側はほぼ定形的なコーディングとするように仕向け、
 可能な限りシンプルにしておく ๏ Lambda上にロジックやら条件分岐やらを書き出すと・・・(^_^;)
  39. 39. @k_nishijima Lambda環境で動かす時のTIPS:
 必要な権限の取り方 39 ๏ LambdaはIAM Roleを使って動くので、権限はAccessKeyなどを
 指定などする必要はない
 = 「Profile指定とロール指定の両対応にしておくと便利」の件
 ๏ このコードの実装では、Lambda関数が読む設定ファイルから、
 Profileの指定を削除しておけばOK
  40. 40. @k_nishijima ダメ・ゼッタイ(^^; 40
  41. 41. @k_nishijima 41 $ apex -p lambda-handson-201608 deploy contact ๏ これで contact関数をデプロイ。
 コードを修正してテストを通したらデプロイ、
 そして確認。これを何度も繰り返す。 ๏ これをマネコンのGUIでやってたら死んじゃいます(^_^;) APEXでデプロイ
  42. 42. @k_nishijima APEXでデプロイ 42 関数名がproject.jsonのname + functionディレクトリ 名になっているのが分かる
  43. 43. @k_nishijima APEXでLambda関数実行 43 $ apex -p lambda-handson-201608 invoke contact < request_contact.json ๏ JSONファイルを引数としてcontact関数をinvoke。
 上手く動けばレスポンスが返ってくる。
  44. 44. @k_nishijima 今回はDynamoDBの中身を見る
 関数を作ってないので 44 ๏ 手動でマネージメントコンソールからDynamoDBの中身を 見てください(^_^;)
 ๏ コアライブラリにGetItemsというメソッドを付けておき ましたので、データ取得APIもすぐ出来ると思います!
  45. 45. @k_nishijima APEXで実行時ログを見る 45 $ apex -p lambda-handson-201608 logs contact ๏ 動かなかったりした時はログをチェック
  46. 46. @k_nishijima 46 以上です!
  47. 47. @k_nishijima ここまでで 47 ๏ Goで書いた自前のライブラリを利用する、
 Goで書かれたLambda関数が動くようになりました。 ๏ このような関数を例えばスケジューリング実行やS3のイベント に反応して実行するようにすれば、実務にもそのまま使えます。
  48. 48. @k_nishijima だがしかし まだWeb APIになってない>< Lambda関数はそのままでは
 HTTPS経由で呼べない… 48
  49. 49. @k_nishijima ここで API Gateway の登場です 49
  50. 50. @k_nishijima Web APIになれば ブラウザから普通に叩ける。
 HTMLだけホストしておけば
 大丈夫になる! 50
  51. 51. @k_nishijima Simple API GatewayでAPI作成 51 ๏ インストールは
 “npm install -g simple-api-gateway”
 ๏ ES6のコードなのでNodeは4以上、
 勿論AWS CLIも必要です。詳しくは
 https://github.com/horike37/simple-api-gateway
  52. 52. @k_nishijima Simple API GatewayでAPI作成 52
  53. 53. @k_nishijima 実際作ってみる 53 ๏ POST /contactにリクエスト投げると ๏ Lambdaが呼ばれてよろしく処理される ๏ そんなAPIを作りましょう
  54. 54. @k_nishijima 利用するAWSの権限の設定は? 54 ๏ https://github.com/horike37/simple-api-gateway/ issues/5 ๏ コントリビュートチャンス!!
 お待ち申し上げております(^_^;)
  55. 55. @k_nishijima 実際作ってみる 55 west-mbp:lambda-handson-jawsug-okinawa-201608 nishijima$ apigw create ? Please select Region for API Gatway ap-northeast-1 ? Please input API Name Handson API API Create Success!! Please action `apigw edit` and set up API
  56. 56. @k_nishijima 実際作ってみる 56 west-mbp:lambda-handson-jawsug-okinawa-201608 nishijima$ apigw edit ? Please select Region for API Gatway ap-northeast-1 ? Please select API Handson API ? Do you want to use an existing Resources on Handson APIor create a new one? Create A New Resouce ? Please select parent Resource / ? Please input Resouce Path contact ? Please select method POST ? Please select backend lambda function lambda-handson-jawsug-okinawa-201608_contact ? May I set enable CORS? Yes ? Set up mapping template? (y/N) y で、エディタが開くのでマッピングテンプレートを入れて
 ? Please edit mapping template Received ? May I create the API? Yes Create Success!! Resource and Method on Handson API API.
  57. 57. @k_nishijima マッピングテンプレートって何? 57 ๏ Integration Requestに指定できる、URLパラメータ/パス パラメータ/HTTPヘッダなどをLambda関数のコードに渡す ためのテンプレート ๏ 想定するURLパラメータとともに、APIGWのステージやHTTP ヘッダなどをLambda関数に渡すことが出来る
  58. 58. @k_nishijima APIを作ったら、ステージ名をつけてデプロイ 58 west-mbp:lambda-handson-jawsug-okinawa-201608 nishijima$ apigw deploy ? Please select Region for API Gatway ap-northeast-1 ? Please select API Handson API ? Please input Stage Name dev Deploy success! Endpoint:https://あなたの.execute-api.ap-northeast-1.amazonaws.com/dev ๏ これでステージ「dev」のAPI完成。ステージ = 環境と言い換えてもOK。 ๏ ステージごとURLが発行されるので、まったく別の環境として利用可能。 ๏ Lambdaのエイリアスと連動したり、このコードの例のように環境変数と して扱ってプログラムの動作を切り替えたり、いろいろ利用できます。
  59. 59. @k_nishijima 呼び出してみる 59 $ curl -H "Content-Type: application/json"
 -X POST
 -d "email=curl@foo.com&message=hello world via curl"
 https://あなたのURL.execute-api.ap-northeast-1.amazonaws.com/dev/contact "ok"
  60. 60. @k_nishijima 60 出来た!?
  61. 61. @k_nishijima はじめに戻って:
 サーバレスアーキテクチャとは? 61 ๏ Q: 開発は楽になった? ๏ A: 1関数の責任範囲がとても狭くなるので、相対的に楽にな る。デバッグも楽。
 また、とにかく繰り返しになるデプロイが楽なのがいい。
  62. 62. @k_nishijima はじめに戻って:
 サーバレスアーキテクチャとは? 62 ๏ Q: スケールする感じする? ๏ A: 極力ステートレスな実装にして、バックエンドのデータ ソースも速度で詰まらないDynamoDBなどを活用すれば、ス ケールしないほうがおかしい
  63. 63. @k_nishijima セッションとか クライアント側の状態管理は!? 63 ๏ 何を言っとるんですか、時代は21世紀ですよ。
 そんなものはありません(建前 ๏ JavaScriptでAWS SigV4を実装した話を聞きたいですか、 そうですか(イラネw
  64. 64. @k_nishijima おや、こんなのも… 64 ๏ A Go framework for AWS Lambda microservices
 http://gosparta.io/ ๏ 誰か試してLTしてくださいな(^^)/
  65. 65. @k_nishijima まとめ 65 ๏ AWS SDK for Go があるので
 AWSリソースを使ったLambdaを書くのはとても簡単
  66. 66. @k_nishijima まとめ 66 ๏ Goは非常にパワフルな言語なので、
 生産性高くサクサクLambda関数が書ける
  67. 67. @k_nishijima まとめ 67 ๏ きっとAWS CLIがGoでリライトされる未来が来る!(来ないかもw ๏ それはどうでもいいとして(^_^;)
 現状でまったく不満はないですが、公式にLambdaでサポートされ ると更に嬉しいですね!
  68. 68. @k_nishijima 68 Thank you so much! Any questions?

×