部署自定义运行时 lambda 时 sam 包太大

sam package too large when deploying custom runtime lambda

所以我复制了 this project,它使用 swift 作为自定义 lambda 运行时,使用 makefile 作为构建方法。

现在我创建了一个 AWS CodePipeline,它使用 sam package 使用 CodeBuild 打包我的项目,最后通过 CloudFormation 部署它。

我的 lambda 的 codeUri 设置在根文件夹中,就像您在我上面链接的 repo 中看到的那样。我认为这就是我在自定义运行时部分下的 sam 文档中看到的那样。问题是 sam package 打包了我的整个项目,而 lambda 在部署时抱怨 zip 太大。

如何设置 makefiletemplate.yml 以便 sam package 只打包我的 lambda?

所以我让它以稍微不同的策略工作。这适用于发现自己处于相同情况的任何人。

1。不要使用 sam 来构建您的 lambda 函数。

我正在 运行使用 shell 脚本来启动 /scripts 文件夹中的 swift build

.
├── Package.resolved
├── Package.swift
├── README.md
├── Sources
│   └── YourFirstLambda
│       ├── main.swift
│       └── requirements.txt
├── buildspec.yml
├── samconfig.toml
├── scripts
│   ├── build-and-package-all.sh
│   ├── build-and-package.sh
│   └── package.sh
└── template.yml

build-and-package-all.sh scripts 文件夹 中启动此 shell 脚本。如果更改所有目录路径,则可以更改此行为。

这会为数组 lambdas 中定义的每个函数启动 build-and-packange.sh 脚本。

declare -a lambdas=("YourFirstLambda" "YourSeconLambda")
workspace="$(pwd)/.."

## now loop through the above array

if [ -f /.dockerenv ]; then
    # This is executed if run inside docker
    echo "I'm inside matrix ;(";
    for lambda in "${lambdas[@]}"
        do 
            # Second parameter is wheather we are inside a docker container or not
            ./build-and-package.sh $lambda "FALSE"
    done
else
    echo "I'm living in real world!";
    for lambda in "${lambdas[@]}"
        do
            # Second parameter is wheather we are inside a docker container or not
            ./build-and-package.sh $lambda "TRUE"
    done
fi

build-and-package.sh

这个脚本运行s

  • swift build
  • package.sh
如果 build-and-package-all.sh 在裸机上执行,则

在 docker 容器上。这很有用,因为您可以在未安装 swift 的计算机上 运行。

另一方面,如果我们已经在 docker 容器中,我们将在裸机上 运行 swift build。当您想使用 AWS CodeBuild 构建函数时,这可能就像我遇到的情况一样。他们还使用 docker 容器,因此无需在 docker 容器内启动 docker 容器。

set -eu

executable=
isBareMetal=
workspace="$(pwd)/.."
if [ $isBareMetal == "TRUE" ]; then
       echo "-------------------------------------------------------------------------"
       echo "building \"$executable\" lambda"
       echo "-------------------------------------------------------------------------"
              docker run --rm -v "$workspace":/workspace -w /workspace/ codebuild-swift \
                     bash -cl "swift build --product $executable -c release"
       echo "done"

       echo "-------------------------------------------------------------------------"
       echo "packaging \"$executable\" lambda"
       echo "-------------------------------------------------------------------------"
              docker run --rm -v "$workspace":/workspace -w /workspace/ codebuild-swift \
                     bash -cl "sh scripts/package.sh $executable"
       echo "done"
else
       echo "-------------------------------------------------------------------------"
       echo "building \"$executable\" lambda"
       echo "-------------------------------------------------------------------------"
              cd $workspace
              swift build --product $executable -c release  
       echo "done"

       echo "-------------------------------------------------------------------------"
       echo "packaging \"$executable\" lambda"
       echo "-------------------------------------------------------------------------"
              sh $workspace/scripts/package.sh $executable
       echo "done"
fi

最后我们将 swift lambda 打包成 .zip。 package.sh

set -eu
executable=
target=".build/lambda/$executable"
rm -rf "$target"
mkdir -p "$target"
cp ".build/release/$executable" "$target/"
# add the target deps based on ldd
ldd ".build/release/$executable" | grep swift | cut -d' ' -f3 | xargs cp -Lv -t "$target"
cd "$target"
ln -s "$executable" "bootstrap"
zip --symlinks lambda.zip *

2。告诉 sam 在哪里可以找到压缩的 lambda

template.yml 中,您应该有一个部分描述您的 lambda:

...
YourLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      Timeout: 5
      Handler: Provided
      Runtime: provided
      MemorySize: 128
      Description: Test Lambda
      Role: !GetAtt Role.Arn
      CodeUri: .build/lambda/YourLambdaFunction/lambda.zip
...

您现在可以使用 sam buildsam deploysam package。 Sam 只会上传应该在 30Mb 范围内的压缩 lambda。如果你没有很多依赖项,对你来说可能更少。

旁注。

您将需要一个安装了 swift 的 docker 容器。我的 docker 图像被标记为 codebuild-swift 并使用以下 docker 文件。如果您以不同的方式命名 docker 图片,则必须更新 build-and-package.sh:

FROM swift:5.2-amazonlinux2

RUN yum -y install \
    git \
    libuuid-devel \
    libicu-devel \
    libedit-devel \
    libxml2-devel \
    sqlite-devel \
    python-devel \
    ncurses-devel \
    curl-devel \
    openssl-devel \
    tzdata \
    libtool \
    gcc-c++ \
    jq \
    tar \
    zip \
    glibc-static

上面的shell脚本都是基于这个站点的: Getting started with sift AWS Lambda runtime