How to package AWS CDK into Lambda layer?

后端 未结 1 2018
感动是毒
感动是毒 2021-01-24 08:38

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 N

相关标签:
1条回答
  • 2021-01-24 09:13

    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() won't accept tar files.

    0 讨论(0)
提交回复
热议问题