How to package AWS CDK into Lambda layer?

我们两清 提交于 2020-03-24 09:43:08

问题


What is the best way to bundle up the AWS CDK as a Lambda layer please?

I need to call the CDK from a Java process, so wish to use the Java 11 runtime and then install Nodejs and the CDK as 2 separate layers. Currently I download the Nodejs binaries and then use something like the following:

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

then refer to the layer within the Lambda constructor / builder.

The CDK is installed as npm install -g aws-cdk, so I don't know how best to bundle this up in a similar fashion.


回答1:


I ended up using a Docker container to install the aws-cdk module into a specific path, then zip up the container and copying it to a bind-mounted directory so that it is available on the underlying host.

I built the project using Gradle and the gradle-docker-plugin by Ben Muschko. I have not spent time trying to use a smaller Node image to speed up builds.

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()
}

The zip file is available at ${buildDir}/docker/aws-cdk.zip.

Adding the CDK as a layer is as per the Nodejs example in my question, so something like this:

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

Points to watch out for:

  • if building on Windows, zipping up on Windows then unzipping on Linux will give issues with files that should be executable no longer being executable, i.e. cdk itself.
  • bind mounting directories seems to have issues when on Windows, hence the need to sanitize the filename.
  • when zipping, it's important to use the --symlinks option, otherwise the cdk executable will not be able to find the cdk.js file.

I would have preferred using tar to zip the file up, but fromAsset() wont accept tar files.



来源:https://stackoverflow.com/questions/60379916/how-to-package-aws-cdk-into-lambda-layer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!