Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

AWS Lambda in Golang

1 943 vues

Publié le

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

Publié dans : Internet
  • Soyez le premier à commenter

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?

×