Konboi Note

AWS LambdaでGoを動かすのに嵌った

はじめに

前回の記事でaws lambdaでGoで書いたアプリを動かしたことの記事をかいた。

しかし

AWSのConsoleでのテストではうまくいったけど、手元のterminalからは403になった。

これがちゃんと動くまで色々嵌ったので解決するまでのメモ。

lambdaの登録 (前回のおさらい)

関数の作成

適当に入力する

こんな感じでビルドしたファイルをアップロードする

テストしてみる

動いている!

ここまでは前回の記事でやった

API Gateway経由でリクエストを送ってみる

トリガーの追加からAPI Gatewayを追加する

追加するとこんな感じ

適当な値を入力する

追加したら追加される

こんな感じ

テストしてみると値は返ってくるけどStatusは502

Thu Feb 08 15:12:14 UTC 2018 : Endpoint response body before transformations: {"body":"{\"body\": \"this is test\"}","time":"2018-02-08T15:12:14.599793588Z"}
Thu Feb 08 15:12:14 UTC 2018 : Endpoint response headers: {X-Amz-Executed-Version=$LATEST, x-amzn-Remapped-Content-Length=0, Connection=keep-alive, x-amzn-RequestId=71c220b1-0ce2-11e8-b0b3-f1062fe7bbc8, Content-Length=79, Date=Thu, 08 Feb 2018 15:12:14 GMT, X-Amzn-Trace-Id=root=1-5a7c68ce-b1994239ae3bf9b85d4aa043;sampled=0, Content-Type=application/json}
Thu Feb 08 15:12:14 UTC 2018 : Execution failed due to configuration error: Malformed Lambda proxy response
Thu Feb 08 15:12:14 UTC 2018 : Method completed with status: 502

terminalから送ってみると

 $ curl -H 'Content-Type:application/json' -d '{"body": "hoge"}'  https://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/echo
{"message":"Missing Authentication Token"}

AWS IAMの認証になっていたので認証をはずしてみた

変更を反映する

エラーの内容が変わった
テストと同じになった

 $ curl -H 'Content-Type:application/json' -d '{"body": "hoge"}'  https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/Echo
{"message": "Internal server error"}

Eventを利用する

エラーメッセージで調べてみるとAPI Gatewayは特定のレスポンスフォーマットである必要があるらしい

refs: https://aws.amazon.com/jp/premiumsupport/knowledge-center/malformed-502-api-gateway/

ソースコードを修正する

こんな感じでresponseをevents.APIGatewayProxyResponseにする

func EchoHandler(ctx context.Context, req *Request) (events.APIGatewayProxyResponse, error) {
	lctx, ok := lambdacontext.FromContext(ctx)
	if !ok {
		return events.APIGatewayProxyResponse{}, &ErrorResponse{
			Message: "FromContextError",
			Time:    time.Now(),
		}
	}
	log.Printf("lambda ctx info:%+v", lctx)

	body, err := json.Marshal(&Response{
		Body: req.Body,
		Time: time.Now(),
	})
	if err != nil {
		return events.APIGatewayProxyResponse{}, err
	}

	return events.APIGatewayProxyResponse{
		StatusCode: http.StatusOK,
		Body:       string(body),
	}, nil
}

ソースコードをビルドしてアップロードしなおすと…

 $ curl -H 'Content-Type:application/json' -d '{"body": "hoge"}'  https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/Echo
{"body":"{\"body\": \"hoge\"}","time":"2018-02-08T15:29:25.159554886Z"}

できた!!!

まとめ

  • Lambdaでのアプリの動かし方を学んだ
  • Eventの組み合わせはきちんと意識して開発するようがありそう
  • API Gatewayは変更したらデプロイしよう
  • API Gatewayの認証の変更はわかりづらい
  • シュッと作ってシュッと遊べるのすごい
AWS Lambda実践ガイド
AWS Lambda実践ガイド
posted with amazlet at 18.02.08
インプレス (2017-10-16)
売り上げランキング: 27,589