Hiroaki
Hiroaki

Reputation: 77

How can you override "cmd" of docker for aws lambda in CDK?

I write CMD ["main.handler"] in Dockerfile, but I'm trying to change handler function for reusing same container image. How can you fix my CDK code? I found CodeImageConfig interface, but have no idea how to use this option.

CDK code

const fn = new lambda.Function(scope, `lambda-fn`, {
    code: new lambda.AssetImageCode("./lambda/myapp", {
        ignoreMode: IgnoreMode.DOCKER,
        file: "lambda.Dockerfile",
    }),
    handler: lambda.Handler.FROM_IMAGE,
    runtime: lambda.Runtime.FROM_IMAGE,
    tracing: lambda.Tracing.ACTIVE,
    environment: {
        SAMPLE_ENV_VAR: "sample_env_var",
    },
});

lambda.Dockerfile

FROM public.ecr.aws/lambda/python:3.9
COPY src/ /var/task/
CMD ["main.handler"]

Upvotes: 1

Views: 2799

Answers (2)

Wizard.Ritvik
Wizard.Ritvik

Reputation: 11612

Using CDK v2 with Python and DockerImageFunction for a project currently - the accepted answer did not work for me.

I am using an AWS managed image in my case - specifically, the public.ecr.aws/lambda/python image.

Dockerfile

This line is at the top of my Dockerfile (source):

FROM --platform=linux/amd64 public.ecr.aws/lambda/python:3.9

Note: I had added the --platform to work around local deployments with an M1 Mac in my case.

To be on the safe side, I also specified AMD64 as the platform in CDK code:

from aws_cdk.aws_ecr_assets import Platform

# needed for Mac M1 deployments
# noinspection PyTypeChecker
platform: Platform = Platform.LINUX_AMD64

function = lambda_.DockerImageFunction(
    self, 'MyFunction',
    code=lambda_.DockerImageCode.from_image_asset(
        str(work_dir),
        platform=platform,
        cmd=...,
    ),
)

CDK - Attempt #1

In my CDK code, the suggested syntax did not work for me.

cmd=['entrypoint', 'main.handler']

Error from CloudWatch logs:

entrypoint requires the handler name to be the first argument
Error: Runtime exited with error: exit status 142 Runtime.ExitError

CDK - Attempt #2

I also tried the following, after consulting from the official Dockerfile for the image:

cmd=['/lambda-entrypoint.sh', 'main.handler']

The same error was observed from the CloudWatch logs when attempting to run the affected AWS Lambda function.

CDK - Attempt #3

What did work, was just passing in cmd with the handler as the first argument, as I originally had in my Dockerfile:

cmd=['main.handler']

Tip: Use the dot . syntax all throughout. For example, if you have a directory called app under $LAMBDA_TASK_ROOT (/var/task) and within that a handlers.py file with a function my_handler, the following syntax will work:

cmd=['app.handlers.my_handler']

All works fine now. Everything is good :-)

Upvotes: 2

gshpychka
gshpychka

Reputation: 11512

You're using AssetImageCode, which has a cmd prop. From the docs:

cmd?

Type: string[] (optional, default: use the CMD specified in the docker image or Dockerfile.)

Specify or override the CMD on the specified Docker image or Dockerfile.

This needs to be in the 'exec form', viz., [ 'executable', 'param1', 'param2' ].
...
    code: new lambda.AssetImageCode("./lambda/myapp", {
        ignoreMode: IgnoreMode.DOCKER,
        file: "lambda.Dockerfile",
        cmd: ["entrypoint", "main.handler"],
    }),
...

Upvotes: 1

Related Questions