所以我让它采用了稍微不同的策略。这适用于任何发现自己处于相同情况的人。
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 脚本。如果更改所有 dir 路径,则可以更改此行为。
这将为数组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
此脚本运行
如果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 build、sam deploy 或sam 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