ALBのバックエンドにLambdaを選択してみた! #reinvent

こんにちは、中村です。

[速報]ALBのバックエンドにLambdaを選択できるようになりました!#reinventで速報が出ましたがALB Support for Lambda が発表されました。

今回は早速ALB + Lambdaを作ってみようと思います。

やってみた!

今回は、node8.10で新規作成時にできる関数ベースに使います。

とりあえずLambdaが作成されました。次にALBを作成します。EC2ダッシュボードのロードバランサーからロードバランサーの作成をします。

HTTPでアクセスするので、セキュリティーグループはHTTPを開けておいてください。 次にターゲットグループを作成します。

ヘルスチェックを有効化すると、詳細設定画面が表示されます。 ヘルスチェックを実行すると、LambdaがInvokeされるので設定には注意が必要です。

最後にLambdaを選択し作成します。先ほど作ったLambdaを選択しましょう。
これでcurlを叩いてみましょう。

$ curl -v http://xxxxxhogehoge.ap-northeast-1.elb.amazonaws.com
* Rebuilt URL to: http://xxxxxhogehoge.ap-northeast-1.elb.amazonaws.com/
*   Trying xxxxxxx...
* TCP_NODELAY set
* Connected to xxxxxhogehoge.ap-northeast-1.elb.amazonaws.com (xxxxxxx) port 80 (#0)
> GET / HTTP/1.1
> Host: xxxxxhogehoge.ap-northeast-1.elb.amazonaws.com
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 502 Bad Gateway
< Server: awselb/2.0
< Date: Thu, 29 Nov 2018 19:47:27 GMT
< Content-Type: text/html
< Content-Length: 138
< Connection: keep-alive
<
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
</body>
</html>
* Connection #0 to host xxxxxhogehoge.ap-northeast-1.elb.amazonaws.com left intact

これで完成!かと思いきや動きませんでした。
どうやらヘルスチェックに失敗しているようです。

ステータスのiのアイコンをクリックすると詳細が表示されます。The response from the Lambda function is not in the expected formatとあるので、おそらくレスポンスの形が違うようです。API Gatewayでは意識せずにできていましたがALBでは自前で行う必要があるようです。

Lambda functions as targets for Application Load Balancersを読んでみると、Lambdaのレスポンス情報が記述されていました。どうやらレスポンスの内容に不足があることがわかったので、Lambdaを合わせて変更してみましょう。またALB + Lambdaの場合は、リクエスト・レスポンス共にテキストかバイナリである必要があります。

const response = {
    statusCode: 200,
    statusDescription: '200 OK',
    isBase64Encoded: false,
    headers: {
        'Content-Type': 'text/html; charset=utf-8'
    },
    body: JSON.stringify('Hello from Lambda!'),
};

これでヘルスチェックを待ってみましょう。レスポンスフォーマットが正常になればステータスがhealthyになります。

確認が取れたら、もう一度curlしてみてください。 正常に行くとこのようなレスポンスが返されます

* Rebuilt URL to: http://xxxxxhogehoge.ap-northeast-1.elb.amazonaws.com/
*   Trying xxxxxxx...
* TCP_NODELAY set
* Connected to xxxxxhogehoge.ap-northeast-1.elb.amazonaws.com (xxxxxxx) port 80 (#0)
> GET / HTTP/1.1
> Host: xxxxxhogehoge.ap-northeast-1.elb.amazonaws.com
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: awselb/2.0
< Date: Thu, 29 Nov 2018 19:56:18 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 20
< Connection: keep-alive
<
* Connection #0 to host xxxxxhogehoge.ap-northeast-1.elb.amazonaws.com left intact
"Hello from Lambda!"

Appendix

  • LambdaにALBを設定している状態でも、API Gatewayのバックエンドとしても利用ができます。

まとめ

いかがでしたでしょうか。
今回はLambdaの大量アップデートということで非常に嬉しいです。早速案件で活用ができそうです。