如何将AWS CDK打包到Lambda层?

How to package AWS CDK into Lambda layer?

请问将 AWS CDK 捆绑为 Lambda 层的最佳方法是什么?

我需要从 Java 进程调用 CDK,因此希望使用 Java 11 运行时,然后将 Nodejs 和 CDK 安装为两个单独的层。目前我下载了 Nodejs 二进制文件,然后使用如下内容:

    LayerVersion nodeLayer = LayerVersion.Builder.create(this, "node-layer")
            .description("Layer containing Node.js")
            .code(
                    Code.fromAsset(somePathToNodejs)
            )
            .build();

然后引用 Lambda 构造函数/构建器中的层。

CDK 安装为 npm install -g aws-cdk,所以我不知道如何以类似的方式最好地捆绑它。

我最终使用 Docker 容器将 aws-cdk 模块安装到特定路径,然后压缩容器并将其复制到绑定安装目录,以便它可以在底层主机。

我使用 Gradle 和 Ben Muschko 的 gradle-docker-plugin 构建了项目。我没有花时间尝试使用较小的节点图像来加速构建。

task createCdkDockerfile(type: Dockerfile) {
    from 'node:latest'
    defaultCommand('/bin/bash', '-c', "apt-get update && apt-get install -y zip && mkdir -p /nodejs && npm config set prefix /nodejs/bin && npm install -g aws-cdk && pushd /nodejs/bin && zip -r --symlinks /opt/aws-cdk.zip *")
}

task buildCdkImage(type:DockerBuildImage) {
    dependsOn createCdkDockerfile
    images.add('my-aws-cdk:latest')
}

ext.maybeConvertWindowsPath = { path ->
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        path = "/${path.replace("\", "/").replace(":", "")}"
    }
    return path
}

task createCdkContainer(type: DockerCreateContainer) {
    def dockerBindDir = new File(buildDir, "docker")
    dockerBindDir.mkdirs()
    dependsOn buildCdkImage
    targetImageId buildCdkImage.getImageId()
    hostConfig.autoRemove = true
    hostConfig.binds = ["${maybeConvertWindowsPath(buildDir.toString())}/docker" : "/opt"]
}

task startCdkContainer(type: DockerStartContainer) {
    dependsOn createCdkContainer
    targetContainerId createCdkContainer.getContainerId()
}

task waitCdkContainer(type: DockerWaitContainer) {
    dependsOn startCdkContainer
    targetContainerId createCdkContainer.getContainerId()
}

zip 文件位于 ${buildDir}/docker/aws-cdk.zip

按照我的问题中的 Nodejs 示例将 CDK 添加为层,所以像这样:

LayerVersion nodeLayer = LayerVersion.Builder.create(this, "aws-cdk-layer")
        .description("Layer containing AWS CDK")
        .code(
                Code.fromAsset(somePathTo-aws-cdk.zip)
        )
        .build();

注意事项:

  • 如果在 Windows 上构建,在 Windows 上压缩,然后在 Linux 上解压缩,将导致本应可执行的文件不再可执行,即 cdk本身。
  • 在 Windows 上绑定安装目录似乎有问题,因此需要清理文件名。
  • 压缩时,使用--symlinks选项很重要,否则cdk可执行文件将无法找到cdk.js文件。

我更喜欢使用 tar 来压缩文件,但是 fromAsset() 不接受 tar 文件。