lambda 50MBの壁を越えたい
初期環境
- lambda
- serverless framework
- typescript
serverless-layersは使用済み
背景
Lambdaにデプロイするにはzipにして50MBまでの容量でないといけない。
仕事のプロジェクトでは開始早々、デプロイすると48.6MBになる。
そのため50MBの制限を回避する方法を調べた結果、ECRを使用すると上限突破できるという記事を
見つけた。
参照:
ECR導入
まずはECRを導入していく
その前にaws cliを導入していなかったので、下記記事を参考に導入
aws cliで作成
$ aws ecr create-repository --repository-name <リポジトリ名> --image-scanning-configuration scanOnPush=true
エラー
An error occurred (AccessDeniedException) when calling the CreateRepository operation: User: arn:aws:iam::429663746063:user/optemo-weel is not authorized to perform: ecr:CreateRepository on resource: arn:aws:ecr:ap-northeast-1:429663746063:repository/serverless-lambda-nestjs because no identity-based policy allows the ecr:CreateRepository action
アクセス権限がないとのことなので、使用しているポリシーを作成してアタッチ(とりあえず、ecrはフルアクセスにした)
再度コマンド実行!
{
"repository": {
"repositoryArn": "arn:aws:ecr:${リージョン}:${registryId}:repository/${リポジトリ名},
"registryId": ${レジストリーID},
"repositoryName": ${リポジトリ名},
"repositoryUri": "${レジストリーID}.dkr.ecr.ap-northeast-1.amazonaws.com/${リポジトリ名}",
"createdAt": "2022-03-20T17:45:11+09:00",
"imageTagMutability": "MUTABLE",
"imageScanningConfiguration": {
"scanOnPush": true
},
"encryptionConfiguration": {
"encryptionType": "AES256"
}
}
}
無事作成できた♪
参照
ECR設定
ログイン
$ aws ecr get-login-password --region <リージョン> |
$ docker login --username AWS --password-stdin <アカウントID>.dkr.ecr.<リージョン>.amazonaws.com
Login Succeeded
いい感じ!二つのコマンド同時に実行したら良いっぽい!
参照
Dockerfile作成
先にこれを作ってもよかったのかも
# AWS ベースイメージを使用
FROM public.ecr.aws/lambda/nodejs:14
# ソースコードを関数のルートディレクトリにコピーします。
COPY package.json package-lock.json /dist/
RUN npm install
# CMD にハンドラを設定します。
CMD ["index.handler"]
今回僕はnestjsを使用しているので、build後のディレクトリ/dist
をcopyに入れておく。
認識あっているかは不安。。。
参考
今回僕はnestjsを使用しているので、build後のディレクトリ/distをcopyに入れておく。
認識あっているかは不安。。。
違った。変更後は後述
Docker イメージをプッシュする
ビルド
$ docker build -t ${リポジトリー名} .
タグをつける
$ docker tag ${リポジトリー名}:latest ${レジストリーID}.dkr.ecr.${リージョン}.amazonaws.com/serverless-lambda-nestjs:latest
プッシュ
$ docker push ${レジストリーID}.dkr.ecr.${リージョン}.amazonaws.com/${リポジトリー名}:latest
The push refers to repository
3d5d030acacf: Pushed
ed7a3fdccd0d: Pushed
6b7df015875a: Pushed
9d3bb0756fb6: Pushed
5f96311c404e: Pushed
90578680ae78: Pushed
9c58b1736bc5: Pushed
edc0c3a324d0: Pushed
latest: digest: sha256:9a226e6a3d344566b4a12a6d2f78b48a4b0d1f06cjofc8f62924k95bb25eb346 size: 1995
sha256:9a226e6a3d344566b4a12a6d2f78b48a4b0d1f06cjofc8f62924k95bb25eb346
は後で使うので保存しとく
コマンドはAmazon ECRの作成したリポジトリないから確認できる
sha256:9a226e6a3d344566b4a12a6d2f78b48a4b0d1f06cjofc8f62924k95bb25eb346は後で使うので保存しとく
僕の実装の仕方的に結局使わなくてよかった。
デプロイ
$ sls deploy
Resource handler returned message: "Invalid request provided: Updating PackageType is not supported"
(RequestToken: 92c94c08-86c8-deea-f965-989b7351cabe, HandlerErrorCode: InvalidRequest)
その後
Error:
CREATE_FAILED: IndexLogGroup (AWS::Logs::LogGroup)
Resource handler returned message: "Resource of type 'AWS::Logs::LogGroup' with identifier '{"/properties/LogGroupName":"/aws/lambda/${lambda関数名}"}' already exists." (RequestToken: 2c0809s79-79s2c-87s9a-d443-ce36b18f22422, HandlerErrorCode: AlreadyExists)
わからない。。。
原因調査はまだ後日
エラー原因調査
1つ目のエラーはすでに同じ名前の関数をzip形式で作成していたので、そのタイプをimageに後から変更することはできないとエラーが出ていたと判断した。
そのため、serverless.ymlのserviceを変更して対応!
解決した!
2つ目のエラーは同じ名前のロググループがすでに存在するというエラーだったため、そのロググループを作成して対応!
解決した!
しかし、更なるエラーが出てきた。
Resource handler returned message: "Lambda layers are not supported for functions created with container images.
(Service: Lambda, Status Code: 400, Request ID: 353ab0fd-f5a0-4b92-a6d8-2287cf6cc154, Extended Request ID: null)" (RequestToken: 552cafdd-72df-b683-f3be-3ab8ebdb35dc, HandlerErrorCode: InvalidRequest)
docker imageでのデプロイの際はLambdaレイヤーを使えないというエラーぽい。
ブラグインのserverless-layers
をコメントアウトし、対応!
できたーーーーー!!!
Nestが動かなかった
デプロイはできたがnestが動かなかったので、色々試した。
これが一番詰まった。。
結果下記の修正で動いた!
- Dockerfile修正
- serverless.yml修正
Dockerfile修正
# AWS ベースイメージを使用
FROM public.ecr.aws/lambda/nodejs:14
# ソースコードを関数のルートディレクトリにコピーします。
COPY . .
RUN npm install
# CMD にハンドラを設定します。
CMD ["dist/index.handler"]
全部コピーするように変更した!
yarn install
にするとダメだった。
serverless.yml修正
ecr:
images:
${tag_name}:
path: ./
...
functions:
index:
image:
name: ${tag_name}
これでNestの軌道まで確認できた!!!
完成!!
意外と長い道のりだった。
おかしな箇所、もっとこうしたら良いなどありましたら、ぜひコメントください!