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