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

标签 swift amazon-web-services aws-lambda aws-cloudformation aws-sam

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

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

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

如何设置 makefile 以及 template.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

该脚本运行

  • 快速构建
  • package.sh

如果 build-and-package-all.sh 在裸机上执行,则在 Docker 容器上。这很有用,因为您可以在未安装 swift 的计算机上运行它。

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

set -eu

executable=$1
isBareMetal=$2
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=$1
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 只会上传压缩的 lambda,其大小应在 30Mb 范围内。如果您没有很多依赖项,那么对您来说可能会更少。

旁注。

您将需要一个已安装 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

关于swift - 部署自定义运行时 lambda 时 sam 包太大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68008222/

相关文章:

ios - swift UITableView 滞后于图像

javascript - 使用 AJAX 从 CloudFront 加载文件会导致 403(禁止)错误

python-2.7 - 如何利用最小读/写单元执行 AWS DynamoDB 备份和还原操作?

amazon-web-services - AWS SNS 在一个 Lambda 中处理多条消息

aws-lambda - 如何在 cloudformation 中使用 !Sub 表示 arn 数组

android - 如何将aws api网关实现到android中?

ios - 如何在单独的自定义 View 中为按钮创建操作

ios - 从多个 View Controller 输入数据时如何更新核心数据

ios - 在动画其标题背景时单击 UIButton 显示错误行为

amazon-web-services - 如何从 AWS Lambda 函数 + 无服务器框架的 URL 中删除阶段?