Search code examples
aws-cdk

How can I tell CDK to bundle Lambda layer assets for x86_64 on an M1 Mac?


I'm struggling with our CDK snapshots tests computing different asset hash values locally on my M1 MacBook and remotely with GitHub actions. I stored the cdk.out directory created on GitHub as an action artifact and compared the contents of cdk.out to identify the difference. It boils down to the way we bundle our asset for the Lambda layer in generator.ts:

const lambdaLayer = new lambda.LayerVersion(this, 'layer', {
  code: Code.fromAsset(pathToLayerSource, {
    bundling: {
      image: cdk.DockerImage.fromBuild(pathToLayerSource, { file: 'Dockerfile' }),
      command: ['bash', '-c', 'rsync -a --exclude Pipfile /tmp/build/ /asset-output'],
      // platform: 'linux/amd64', // this didn't help, see below
    },
  }),
  description: `Layer for ${Generator.SERVICE_NAME} stack`,
  layerVersionName: commons.getIdentifierForStage(Generator.SERVICE_NAME),
});

Here is the Dockerfile:

FROM public.ecr.aws/sam/build-python3.10:latest

ARG TMP_BUILD=/tmp/build

RUN yum makecache fast; yum clean all && yum -y update && yum -y upgrade; yum clean all && \
    yum install -y yum-plugin-ovl; yum clean all && yum -y groupinstall "Development Tools"; yum clean all

RUN yum -y install postgresql-devel && pip install pipenv

WORKDIR ${TMP_BUILD}
COPY Pipfile .
COPY Pipfile.lock .

RUN pipenv requirements > requirements.txt && \
    pip install -r requirements.txt -t python --no-cache-dir

WORKDIR /var/task

When I build the asset locally, charset_normalizer is installed to the python directory of the layer with these files:

  • md.cpython-310-aarch64-linux-gnu.so
  • md__mypyc.cpython-310-aarch64-linux-gnu.so

However, the cdk.out of the GitHub action contains these files for the asset instead:

  • md.cpython-310-x86_64-linux-gnu.so
  • md__mypyc.cpython-310-x86_64-linux-gnu.so

I want to instruct CDK to bundle for linux/amd64 and specified the platform in the BundlingOptions but that didn't change that aarch64 CPython libraries are installed for charset_normalizer. Does anyone know how I can achieve my goal to compute the same asset hash values locally by instructing CDK to bundle for the x64_86 architecture?


Solution

  • Invoke it with

    DOCKER_DEFAULT_PLATFORM=linux/amd64 cdk deploy

    should work, given that the image building does work under emulation. Not all images run nicely with rosetta/qemu, but enabling rosetta emulation in docker desktop probably helps.

    There is another problem with docker (older versions, I think it fixed in the latest version), that if you once pulled an image for the wrong arch, it wont pull a new one when switching arch. Hence, you might need to purge the image before trying to switch to linux/amd64. But, in the later Docker Desktop this seems to have been fixed (at least 4.26.0)