From b3eafc2dc61ed69de20196fa08a4df3c29ecc894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Israel=20Pe=C3=B1a?= Date: Tue, 14 Sep 2021 04:45:45 -0700 Subject: [PATCH] feat(lambda): configure workdir for docker image based functions (#16111) CloudFormation allows setting the [`WorkingDirectory`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-imageconfig.html#cfn-lambda-function-imageconfig-workingdirectory) property in `AWS::Lambda::Function.ImageConfig` to override the docker container's working directory, but this isn't currently exposed through CDK. Not sure if that was intentional. This PR wires that up. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-lambda/README.md | 3 +++ packages/@aws-cdk/aws-lambda/lib/code.ts | 26 +++++++++++++++++++ packages/@aws-cdk/aws-lambda/lib/function.ts | 1 + .../@aws-cdk/aws-lambda/test/code.test.ts | 4 +++ .../@aws-cdk/aws-lambda/test/function.test.ts | 2 ++ 5 files changed, 36 insertions(+) diff --git a/packages/@aws-cdk/aws-lambda/README.md b/packages/@aws-cdk/aws-lambda/README.md index d257bbd635df5..c6098ff19fe11 100644 --- a/packages/@aws-cdk/aws-lambda/README.md +++ b/packages/@aws-cdk/aws-lambda/README.md @@ -78,6 +78,9 @@ new DockerImageFunction(this, 'ECRFunction', { }); ``` +The props for these docker image resources allow overriding the image's `CMD`, `ENTRYPOINT`, and `WORKDIR` +configurations. See their docs for more information. + ## Execution Role Lambda functions assume an IAM role during execution. In CDK by default, Lambda diff --git a/packages/@aws-cdk/aws-lambda/lib/code.ts b/packages/@aws-cdk/aws-lambda/lib/code.ts index b78859bf3515c..293c91f1485d9 100644 --- a/packages/@aws-cdk/aws-lambda/lib/code.ts +++ b/packages/@aws-cdk/aws-lambda/lib/code.ts @@ -202,6 +202,14 @@ export interface CodeImageConfig { * @default - use the ENTRYPOINT in the docker image or Dockerfile. */ readonly entrypoint?: string[]; + + /** + * Specify or override the WORKDIR on the specified Docker image or Dockerfile. + * A WORKDIR allows you to configure the working directory the container will use. + * @see https://docs.docker.com/engine/reference/builder/#workdir + * @default - use the WORKDIR in the docker image or Dockerfile. + */ + readonly workingDirectory?: string; } /** @@ -435,6 +443,14 @@ export interface EcrImageCodeProps { */ readonly entrypoint?: string[]; + /** + * Specify or override the WORKDIR on the specified Docker image or Dockerfile. + * A WORKDIR allows you to configure the working directory the container will use. + * @see https://docs.docker.com/engine/reference/builder/#workdir + * @default - use the WORKDIR in the docker image or Dockerfile. + */ + readonly workingDirectory?: string; + /** * The image tag to use when pulling the image from ECR. * @default 'latest' @@ -460,6 +476,7 @@ export class EcrImageCode extends Code { imageUri: this.repository.repositoryUriForTag(this.props?.tag ?? 'latest'), cmd: this.props.cmd, entrypoint: this.props.entrypoint, + workingDirectory: this.props.workingDirectory, }, }; } @@ -485,6 +502,14 @@ export interface AssetImageCodeProps extends ecr_assets.DockerImageAssetOptions * @default - use the ENTRYPOINT in the docker image or Dockerfile. */ readonly entrypoint?: string[]; + + /** + * Specify or override the WORKDIR on the specified Docker image or Dockerfile. + * A WORKDIR allows you to configure the working directory the container will use. + * @see https://docs.docker.com/engine/reference/builder/#workdir + * @default - use the WORKDIR in the docker image or Dockerfile. + */ + readonly workingDirectory?: string; } /** @@ -510,6 +535,7 @@ export class AssetImageCode extends Code { imageUri: asset.imageUri, entrypoint: this.props.entrypoint, cmd: this.props.cmd, + workingDirectory: this.props.workingDirectory, }, }; } diff --git a/packages/@aws-cdk/aws-lambda/lib/function.ts b/packages/@aws-cdk/aws-lambda/lib/function.ts index 2d2fadc8d808b..9cd67a478f003 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function.ts @@ -675,6 +675,7 @@ export class Function extends FunctionBase { imageConfig: undefinedIfNoKeys({ command: code.image?.cmd, entryPoint: code.image?.entrypoint, + workingDirectory: code.image?.workingDirectory, }), kmsKeyArn: props.environmentEncryption?.keyArn, fileSystemConfigs, diff --git a/packages/@aws-cdk/aws-lambda/test/code.test.ts b/packages/@aws-cdk/aws-lambda/test/code.test.ts index ec9732baa9ea7..49e87cf220ebe 100644 --- a/packages/@aws-cdk/aws-lambda/test/code.test.ts +++ b/packages/@aws-cdk/aws-lambda/test/code.test.ts @@ -225,6 +225,7 @@ describe('code', () => { cmd: ['cmd', 'param1'], entrypoint: ['entrypoint', 'param2'], tag: 'mytag', + workingDirectory: '/some/path', }), handler: lambda.Handler.FROM_IMAGE, runtime: lambda.Runtime.FROM_IMAGE, @@ -238,6 +239,7 @@ describe('code', () => { ImageConfig: { Command: ['cmd', 'param1'], EntryPoint: ['entrypoint', 'param2'], + WorkingDirectory: '/some/path', }, }); }); @@ -315,6 +317,7 @@ describe('code', () => { code: lambda.Code.fromAssetImage(path.join(__dirname, 'docker-lambda-handler'), { cmd: ['cmd', 'param1'], entrypoint: ['entrypoint', 'param2'], + workingDirectory: '/some/path', }), handler: lambda.Handler.FROM_IMAGE, runtime: lambda.Runtime.FROM_IMAGE, @@ -325,6 +328,7 @@ describe('code', () => { ImageConfig: { Command: ['cmd', 'param1'], EntryPoint: ['entrypoint', 'param2'], + WorkingDirectory: '/some/path', }, }); }); diff --git a/packages/@aws-cdk/aws-lambda/test/function.test.ts b/packages/@aws-cdk/aws-lambda/test/function.test.ts index f86a3b6fb1ebb..b4f79aff6cc9e 100644 --- a/packages/@aws-cdk/aws-lambda/test/function.test.ts +++ b/packages/@aws-cdk/aws-lambda/test/function.test.ts @@ -2112,6 +2112,7 @@ describe('function', () => { imageUri: 'ecr image uri', cmd: ['cmd', 'param1'], entrypoint: ['entrypoint', 'param2'], + workingDirectory: '/some/path', }, }), handler: lambda.Handler.FROM_IMAGE, @@ -2122,6 +2123,7 @@ describe('function', () => { ImageConfig: { Command: ['cmd', 'param1'], EntryPoint: ['entrypoint', 'param2'], + WorkingDirectory: '/some/path', }, }); });