Hands-On Serverless Applications with Go を読んだ

AWS Lambda を Go で使う方法を学びたくなり、Hands-On Serverless Applications with Go を読んでみました。

github.com

大まかな流れは

  • Go で Lambda 関数を書く
  • API Gateway とつなぐ
  • DynamoDB とつなぐ
  • CI / CD を入れる (Code Pipeline, Code Build)
  • CloudFront で Websiteホスティング
  • Test / Monitoring / Security / Cost / IaaS

といった感じ。

Chapter 8: Scaling Up Your Application までは本の内容と現在の仕様との違いをなんとか吸収できたものの、Chapter 9 での CouldFront で動かす Website が思ったように動かずそこからは流し読みになってしまいました。 2018年に出版された本なのでそこそこコードも動いてくれるのではと期待したのですが、結構修正が必要でした。また AWS の UI も変わったようで本には書いていない項目があったりしてどうしたものかと少々悩みました。

後半は流し読みになってしまい消化不良なものの、今まで使ったことがなかった DynamoDB に触れることができ、また Lambda 関数がバージョン管理できるものだと知ることができたので読んでよかったと思います。

引っかかったところ

Send の仕様

GitHub issue にも上がっていますが、Send()Send(context.Background()) としないと動かないコードがちょこちょこありました。

github.com

docs.aws.amazon.com

AWS CLIAPI Gateway に DELETE methods を追加

GET, POST を追加するときはマネジメントコンソールからポチポチと追加したのですが、DELETE に関しては AWS CLI を使って追加するという内容でした。 本に書いてある通りにコマンドを打つと一応 DELETE が追加されているようでしたが、なぜか思った挙動をせず。一度それを消して、マネジメントコンソールから DELETE を追加すると想定した挙動になりました。

aws apigateway get-methodaws apigateway get-method-response を使ってそれぞれの方法での差を確認して本には書いていない aws apigateway put-integration-response を追加してみたらうまく動作するようになりました。

# --integration-http-method は POST にする
aws apigateway put-integration \
    --rest-api-id $API_ID \
    --resource-id $RESOURCE_ID \
    --http-method DELETE \
    --type AWS_PROXY \
    --integration-http-method POST \
    --uri arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:ACCOUNT_ID:function:DeleteMovie/invocations \
    --region ap-northeast-1

aws apigateway put-method-response \
    --rest-api-id $API_ID \
    --resource-id $RESOURCE_ID \
    --http-method DELETE \
    --status-code 200 \
    --response-models '{"application/json":"Empty"}' \
    --region ap-northeast-1


# 本には書いていないがこのコマンドも必要
aws apigateway put-integration-response \
    --rest-api-id $API_ID \
    --resource-id $RESOURCE_ID \
    --http-method DELETE \
    --status-code 200 \
    --selection-pattern "" \
    --region ap-northeast-1 \

aws apigateway create-deployment \
    --rest-api-id $API_ID \
    --stage-name default \
    --region ap-northeast-1

マネジメントコンソールで作った method との差を確認

aws apigateway get-method \
--rest-api-id $API_ID \
--resource-id $RESOURCE_ID \
--http-method DELETE

aws apigateway get-method-response \
--rest-api-id $API_ID \
--resource-id $RESOURCE_ID \
--http-method DELETE \
--status-code 200

どうやら AWS CLI でリソースを作る場合、マネジメントコンソールで作るときに暗黙的によしなにしてくれていることも全て自分の手でコントロールしないといけないようです。 以前 Terraform でリソースを使ったときにも同様なことで引っかかったので、この手の AWSAPI を通して(?) リソースを作るのは難しいなぁと改めて実感。

stackoverflow.com

CodeBuild がうまく動かない

GitHub と連携して master ブランチに変更が入るたびに CI を回って、GitHub からコードを取得 -> コンパイル -> Lambda 関数を更新 という流れがあったのですが、どうにもコンパイルがうまくいかず。 S3 には GitHub 引っ張ってきたコードは置かれていたので、GitHub との連携の部分は問題なさそうだったもののコンパイルしたバイナリが S3 の所定の場所に置かれず。権限などでエラーにもなっていないので何が悪いのかもわからず。変な設定を入れてわざと CI を失敗させようとしても Succeed になってしまい、どうにも解決できませんでした。