Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the same DockerContext and Dockerfile paths as the CDK is using #4074

Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
a8a5775
Use the same DockerContext and Dockerfile paths as the CDK is using
i18n-tribe Jul 21, 2022
a142c25
Merge branch 'develop' into use_the_same_docker_context_and_dockerfil…
hawflau Jul 26, 2022
ec8d936
Add tests to ensure `Dockerfile` can be a path to a docker file via s…
i18n-tribe Sep 15, 2022
8cc2b5d
Merge branch 'develop' into use_the_same_docker_context_and_dockerfil…
moelasmar Sep 16, 2022
178ddb9
Add tests to ensure SAM supports CDK apps where Docker image asset `f…
i18n-tribe Oct 11, 2022
04a53ba
Merge branch 'develop' into use_the_same_docker_context_and_dockerfil…
i18n-tribe Oct 12, 2022
5fcfdd6
Merge branch 'develop' into use_the_same_docker_context_and_dockerfil…
moelasmar Oct 13, 2022
1080378
Merge branch 'develop' into use_the_same_docker_context_and_dockerfil…
moelasmar Oct 13, 2022
af2834c
Merge branch 'develop' into use_the_same_docker_context_and_dockerfil…
moelasmar Oct 14, 2022
06d5f45
Merge branch 'develop' into use_the_same_docker_context_and_dockerfil…
moelasmar Oct 14, 2022
15d9f4e
Merge branch 'develop' into use_the_same_docker_context_and_dockerfil…
moelasmar Oct 16, 2022
1dbd4d2
Merge branch 'develop' into use_the_same_docker_context_and_dockerfil…
moelasmar Oct 21, 2022
447e939
Merge branch 'develop' into use_the_same_docker_context_and_dockerfil…
mndeveci Oct 25, 2022
7527fd7
Merge branch 'develop' into use_the_same_docker_context_and_dockerfil…
mndeveci Nov 1, 2022
88092f0
Merge branch 'develop' into use_the_same_docker_context_and_dockerfil…
hawflau Nov 3, 2022
b36eaa0
Fixed failing test after merge conflict with commit fa26bff1415485e36…
i18n-tribe Nov 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions samcli/lib/samlib/resource_metadata_normalizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,9 @@ def _extract_image_asset_metadata(metadata):
"""
asset_path = Path(metadata.get(ASSET_PATH_METADATA_KEY, ""))
dockerfile_path = Path(metadata.get(ASSET_DOCKERFILE_PATH_KEY), "")
dockerfile, path_from_asset = dockerfile_path.stem, dockerfile_path.parent
dockerfile_context = str(Path(asset_path.joinpath(path_from_asset)))
return {
SAM_METADATA_DOCKERFILE_KEY: dockerfile,
SAM_METADATA_DOCKER_CONTEXT_KEY: dockerfile_context,
SAM_METADATA_DOCKERFILE_KEY: str(dockerfile_path),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit concerned about this change since this will break the current code behaviour, might need to investigate on the current usage volume to decide if we can change this part.

Copy link
Contributor Author

@i18n-tribe i18n-tribe Jul 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might need to investigate on the current usage volume to decide if we can change this part.

Sounds like a good move 👍

this change... will break the current code behaviour

As noted, I think it's good to investigate this.

From our own investigation...

I would not describe this as breaking any current behavior.

It does change the current behavior.

But a change is only a breaking if it causes something to stop working.

So - would this change cause any currently working code to break?

We do not think it will.

To illustrate...

Say your CDK code looks like this:

code = aws_lambda.DockerImageCode.from_image_asset(
    directory="/Users/john/PycharmProjects/project-root/application/runtime/",
    file="Dockerfile",
)

docker_lambda = aws_lambda.DockerImageFunction(code=code)

This works with the current code.

And this will still work after this PR is merged.

Currently - the SAM CLI only works with CDK code where file is just the Dockerfile and directory is the full path to the Dockerfile.

In contrast, CDK code like this...

code = aws_lambda.DockerImageCode.from_image_asset(
    directory="/Users/john/PycharmProjects/project-root",
    file="./application/runtime/Dockerfile",
)

docker_lambda = aws_lambda.DockerImageFunction(code=code)

...does not currently work with the SAM CLI. But it will work when this PR is merged.

An important question would be –

Why was the code written like this to begin with?

In the PR where this code was introduced – this does not seem to have been discussed in the comments.

What this code behaviour specified in your internal tools e.g. Jira? If so, what were the reasons given?

The goal of this feature is to be compatible with the CDK.

But currently, the code is not supporting an important capability of the CDK - the ability to control the directory that assets are built from.

Both cdk deploy and sam build work fine with metadata like:

DockerContext ="/Users/john/PycharmProjects/project-root",
Dockerfile ="./application/runtime/Dockerfile",

So it is not clear to us why the code in the PR was been written to ensure sam cli always works with metadata like:

DockerContext ="/Users/john/PycharmProjects/project-root/application/runtime",
Dockerfile ="Dockerfile",

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it is not clear to us why the code in the PR was been written to ensure sam cli always works with metadata like

This is how SAM CLI handles it. So it was written to match SAM CLI expectations.

Copy link
Contributor Author

@i18n-tribe i18n-tribe Sep 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jfuss apologies for the slow reply, I was on vacation.

So I had a look at the SAM CLI code to see how DockerContext and Dockerfile metadata are used by the SAM CLI.

I found 4 other usages.

Just one usage is relevant to this PR:

In this code block in samcli/lib/build/app_builder.py

We read the metadata properties:

dockerfile = cast(str, metadata.get("Dockerfile"))
docker_context = cast(str, metadata.get("DockerContext"))

Then we make docker_context into an absolute path:

docker_context_dir = pathlib.Path(self._base_dir, docker_context).resolve()

Then we call docker build using the python docker client, passing the properties as arguments:

build_args = {
    "path": str(docker_context_dir),
    "dockerfile": dockerfile,
}
build_logs = self._docker_client.api.build(**build_args)

So in summary -

  • Dockerfile is passed without modification to _docker_client.api.build as the dockerfile argument
  • DockerContext is converted to an absolute path, and passed to _docker_client.api.build as the path argument

Here is the documentation for '_docker_client.api.build'

And those arguments are:

path (str) – Path to the directory containing the Dockerfile
dockerfile (str) – path within the build context to the Dockerfile

In my opinion, the documentation for path is a little bit ambiguous.

Does this mean that path is:

  1. the immediate parent directory containing the Dockerfile?
  2. a directory that ultimately contains the dockerfile, which might be nested in child folder(s)?

I would completely understand if something thinks it means 1. - this is what I thought at first.

But if we look at the documentation for dockerfile - it says path within the build context to the Dockerfile

Because dockerfile can be a path within the build context - it can be a path (potentially via subfolders) to the Dockerfile.

So in fact, 2. is the correct interpretation.

This interpretation is reinforced by the docker cli documentation for docker build

Usage is:

docker build [OPTIONS] PATH 

Where PATH will be DockerContext in the SAM CLI.

And the option --file will be Dockerfile in the SAM CLI.

In the docker cli documentation, they refer to something called the build context.

The build context is very similar to PATH (AKA DockerContext).

The build context is a copy of the folder specified in PATH (DockerContext), excluding files specified in .dockerignore.

So --file (AKA Dockerfile) is a path to a docker file within the build context (usually a relative path is used).

There is no requirement for the docker file to be in the root of the build context.

I.E. --file (Dockerfile) can be a path via subfolders to the docker file.

Here's the documentation for --file.

The documentation has examples where --file is a path via subfolders to the docker file like:

docker build --file dockerfiles/Dockerfile.debug .
docker build --file dockerfiles/Dockerfile.prod .

In the example above, PATH is . - the current directory.

And there's a quote in this section of the docs.

By default the docker build command will look for a Dockerfile at the root of the build context. 
The -f, --file, option lets you specify the path to an alternative file to use instead. 
This is useful in cases where the same set of files are used for multiple builds. 

The use case where the same set of files are used for multiple builds is exactly what this PR is trying to solve.

This is the use case described in the PR description.

This use-case is supported by the AWS CDK.

This use-case is also - in fact - already supported by the SAM CLI.

The AWS CDK docs support this use-case explicitly:

directory (str) – the directory from which the asset must be created.
file (Optional[str]) – Path to the Dockerfile (relative to the directory). Default: ‘Dockerfile’

The SAM CLI developer guide docs do not support this use-case explicitly:

Dockerfile - The name of the Dockerfile associated with the Lambda function.
DockerContext - The location of the Dockerfile.

The SAM CLI developer guide sound like interpretation 1. of the documentation for '_docker_client.api.build'.

But in fact, the SAM CLI code works perfectly well if Dockerfile is a path via subfolders to the docker file.

And I've personally used this 'undocumented feature' in multiple SAM projects I have worked on.

In other words -

What seems to have happened is...

  • Someone thought that in SAM projects, Dockerfile must be a direct child of DockerContext
  • SAM developer guide documented this limitation
  • When SAM was integrated with CDK, somebody wrote code to enforce this limitation

The code to enforce this supposed limitation means SAM is not fully compatible with CDK.

So this PR is removing that code, to improve support for the CDK.

Also - it seems likely the supposed limitation never in fact existed, and it's always been possible in SAM for Dockerfile to be a path via subfolders to the docker file.

So I've created a PR to update the SAM CLI developer guide, so people will be aware of this capability of the SAM CLI.

I've also created a PR to update the documentation for the Docker Python Client to be more clear.

It may be possible that unclear documentation in docker-py is the original source of the belief that SAM CLI requires Dockerfile to be a direct child of DockerContext.


A further note -

Above there is a link do documentation for the docker cli.

The python docker SDK doesn't use the docker cli, it uses the docker api.

So I checked the docker API documentation for build

It takes an argument:

dockerfile - Path within the build context to the Dockerfile.

It also takes a tar archive which contains the build context - documented as:

Build an image from a tar archive with a Dockerfile in it.

The Dockerfile specifies how the image is built from the tar archive.
It is typically in the archive's root, but can be at a different path or have a different name by specifying the dockerfile parameter.

I.e. dockerfile 'is typically in the archive's root' - but it can be a path to a dockerfile in a subfolder.

And I checked the source code of the docker python sdk, to see how it's interacting with the docker API.

Here's the code where it creates the build context tar archive.

This is a copy of the folder specified in path (AKA DockerContext), excluding files specified in .dockerignore.

And on this line it passes Dockerfile to the docker API as dockerfile.


For reference, here are the 3 other usages of DockerContext metadata, which are not relevant to this PR:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @i18n-tribe for your contribution and your very detailed explanation. I think you have a point regarding this change, I think we miss understood the DockerContext and DockerFile properties and we assumed that the DockerFile should be a file in the DockerContext directory path. I did some investigations to make sure that this change will not break any customer. I think it will work as expected, and fix this bug.

my only request is to add some integration testing to cover this case

SAM_METADATA_DOCKER_CONTEXT_KEY: str(asset_path),
SAM_METADATA_DOCKER_BUILD_ARGS_KEY: metadata.get(ASSET_DOCKERFILE_BUILD_ARGS_KEY, {}),
}

Expand Down
10 changes: 10 additions & 0 deletions tests/iac_integration/cdk/test_sam_cdk_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@ def random_port():
("/restapis/normal/functionGoRuntime", "Hello World from function construct with go runtime"),
("/restapis/normal/dockerImageFunction", "Hello World from docker image function construct"),
("/restapis/normal/functionImageAsset", "Hello World from function construct with image asset"),
(
"/restapis/normal/dockerImageFunctionWithSharedCode",
"Hello World from docker image function construct "
"with a Dockerfile that shares code with another Dockerfile",
),
(
"/restapis/normal/functionImageAssetWithSharedCode",
"Hello World from function construct with image asset "
"with a Dockerfile that shares code with another Dockerfile",
),
]
)
@pytest.mark.flaky(reruns=3)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,23 @@ public JavaStack(final Construct scope, final String id, final StackProps props)
.tracing(Tracing.ACTIVE)
.build();

// both ways work when 'file' is a path via subfolders to the Dockerfile
// this is useful when multiple docker images share some common code
DockerImageFunction dockerImageFunctionWithSharedCode = DockerImageFunction.Builder.create(this, "DockerImageFunctionWithSharedCode")
.code(DockerImageCode.fromImageAsset("../../src/docker/ImagesWithSharedCode",
AssetImageCodeProps.builder().file("DockerImageFunctionWithSharedCode/Dockerfile").build()
)
).tracing(Tracing.ACTIVE)
.build();

Function functionImageAssetWithSharedCode = Function.Builder.create(this, "FunctionImageAssetWithSharedCode")
.code(Code.fromAssetImage("../../src/docker/ImagesWithSharedCode",
AssetImageCodeProps.builder().file("FunctionImageAssetWithSharedCode/Dockerfile").build()))
.handler(Handler.FROM_IMAGE)
.runtime(Runtime.FROM_IMAGE)
.tracing(Tracing.ACTIVE)
.build();

//Rest APIs

// Spec Rest Api
Expand Down Expand Up @@ -239,6 +256,10 @@ public JavaStack(final Construct scope, final String id, final StackProps props)
.addMethod("GET", new LambdaIntegration(dockerImageFunction));
normalRootResource.addResource("functionImageAsset")
.addMethod("GET", new LambdaIntegration(functionImageAsset));
normalRootResource.addResource("dockerImageFunctionWithSharedCode")
.addMethod("GET", new LambdaIntegration(dockerImageFunctionWithSharedCode));
normalRootResource.addResource("functionImageAssetWithSharedCode")
.addMethod("GET", new LambdaIntegration(functionImageAssetWithSharedCode));

// Nested Stack
new NestedStack1(this, "NestedStack");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
self,
"DockerImageFunction",
code=lambda1.DockerImageCode.from_image_asset(
"../../src/docker/DockerImageFunctionConstruct",
directory="../../src/docker/DockerImageFunctionConstruct",
file="Dockerfile",
),
tracing=lambda1.Tracing.ACTIVE,
Expand All @@ -228,14 +228,38 @@ def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
self,
"FunctionImageAsset",
code=lambda1.Code.from_asset_image(
"../../src/docker/FunctionConstructWithImageAssetCode",
directory="../../src/docker/FunctionConstructWithImageAssetCode",
file="Dockerfile",
),
handler=lambda1.Handler.FROM_IMAGE,
runtime=lambda1.Runtime.FROM_IMAGE,
tracing=lambda1.Tracing.ACTIVE,
)

# both ways work when 'file' is a path via subfolders to the Dockerfile
# this is useful when multiple docker images share some common code
docker_image_function_with_shared_code = lambda1.DockerImageFunction(
self,
"DockerImageFunctionWithSharedCode",
code=lambda1.DockerImageCode.from_image_asset(
directory="../../src/docker/ImagesWithSharedCode",
file="DockerImageFunctionWithSharedCode/Dockerfile",
),
tracing=lambda1.Tracing.ACTIVE,
)

function_image_asset_with_shared_code = lambda1.Function(
self,
"FunctionImageAssetWithSharedCode",
code=lambda1.Code.from_asset_image(
directory="../../src/docker/ImagesWithSharedCode",
file="FunctionImageAssetWithSharedCode/Dockerfile",
),
handler=lambda1.Handler.FROM_IMAGE,
runtime=lambda1.Runtime.FROM_IMAGE,
tracing=lambda1.Tracing.ACTIVE,
)

# Rest APIs

# Spec Rest Api
Expand Down Expand Up @@ -287,6 +311,12 @@ def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
normal_root_resource.add_resource("functionImageAsset").add_method(
"GET", LambdaIntegration(function_image_asset)
)
normal_root_resource.add_resource("dockerImageFunctionWithSharedCode").add_method(
"GET", LambdaIntegration(docker_image_function_with_shared_code)
)
normal_root_resource.add_resource("functionImageAssetWithSharedCode").add_method(
"GET", LambdaIntegration(function_image_asset_with_shared_code)
)

# Nested Stack
NestedStack1(self, "NestedStack")
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,25 @@ export class CDKSupportDemoRootStack extends cdk.Stack {
tracing: lambda.Tracing.ACTIVE,
});

// both ways work when 'file' is a path via subfolders to the Dockerfile
// this is useful when multiple docker images share some common code
const dockerImageFunctionWithSharedCode = new lambda.DockerImageFunction(this, "DockerImageFunctionWithSharedCode", {
code: lambda.DockerImageCode.fromImageAsset("../../src/docker/ImagesWithSharedCode", {
file: "DockerImageFunctionWithSharedCode/Dockerfile",
}),
tracing: lambda.Tracing.ACTIVE,
});

// another way
const functionImageAssetWithSharedCode = new lambda.Function(this, "FunctionImageAssetWithSharedCode", {
code: lambda.Code.fromAssetImage("../../src/docker/ImagesWithSharedCode", {
file: "FunctionImageAssetWithSharedCode/Dockerfile",
}),
handler: lambda.Handler.FROM_IMAGE,
runtime: lambda.Runtime.FROM_IMAGE,
tracing: lambda.Tracing.ACTIVE,
});


//Rest APIs

Expand Down Expand Up @@ -246,6 +265,12 @@ export class CDKSupportDemoRootStack extends cdk.Stack {

normalRootResource.addResource('functionImageAsset')
.addMethod('GET', new LambdaIntegration(functionImageAsset));

normalRootResource.addResource('dockerImageFunctionWithSharedCode')
.addMethod('GET', new LambdaIntegration(dockerImageFunctionWithSharedCode));

normalRootResource.addResource('functionImageAssetWithSharedCode')
.addMethod('GET', new LambdaIntegration(functionImageAssetWithSharedCode));

// Nested Stack
new NestedStack1(this, 'NestedStack' ,{});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,23 @@ public JavaStack(final Construct scope, final String id, final StackProps props)
.tracing(Tracing.ACTIVE)
.build();

// both ways work when 'file' is a path via subfolders to the Dockerfile
// this is useful when multiple docker images share some common code
DockerImageFunction dockerImageFunctionWithSharedCode = DockerImageFunction.Builder.create(this, "DockerImageFunctionWithSharedCode")
.code(DockerImageCode.fromImageAsset("../../src/docker/ImagesWithSharedCode",
AssetImageCodeProps.builder().file("DockerImageFunctionWithSharedCode/Dockerfile").build()
)
).tracing(Tracing.ACTIVE)
.build();

Function functionImageAssetWithSharedCode = Function.Builder.create(this, "FunctionImageAssetWithSharedCode")
.code(Code.fromAssetImage("../../src/docker/ImagesWithSharedCode",
AssetImageCodeProps.builder().file("FunctionImageAssetWithSharedCode/Dockerfile").build()))
.handler(Handler.FROM_IMAGE)
.runtime(Runtime.FROM_IMAGE)
.tracing(Tracing.ACTIVE)
.build();

//Rest APIs

// Spec Rest Api
Expand Down Expand Up @@ -240,6 +257,11 @@ public JavaStack(final Construct scope, final String id, final StackProps props)
.addMethod("GET", new LambdaIntegration(dockerImageFunction));
normalRootResource.addResource("functionImageAsset")
.addMethod("GET", new LambdaIntegration(functionImageAsset));
normalRootResource.addResource("dockerImageFunctionWithSharedCode")
.addMethod("GET", new LambdaIntegration(dockerImageFunctionWithSharedCode));
normalRootResource.addResource("functionImageAssetWithSharedCode")
.addMethod("GET", new LambdaIntegration(functionImageAssetWithSharedCode));

// Nested Stack
new NestedStack1(this, "NestedStack");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
self,
"DockerImageFunction",
code=lambda1.DockerImageCode.from_image_asset(
"../../src/docker/DockerImageFunctionConstruct",
directory="../../src/docker/DockerImageFunctionConstruct",
file="Dockerfile",
),
tracing=lambda1.Tracing.ACTIVE,
Expand All @@ -228,14 +228,38 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
self,
"FunctionImageAsset",
code=lambda1.Code.from_asset_image(
"../../src/docker/FunctionConstructWithImageAssetCode",
directory="../../src/docker/FunctionConstructWithImageAssetCode",
file="Dockerfile",
),
handler=lambda1.Handler.FROM_IMAGE,
runtime=lambda1.Runtime.FROM_IMAGE,
tracing=lambda1.Tracing.ACTIVE,
)

# both ways work when 'file' is a path via subfolders to the Dockerfile
# this is useful when multiple docker images share some common code
docker_image_function_with_shared_code = lambda1.DockerImageFunction(
self,
"DockerImageFunctionWithSharedCode",
code=lambda1.DockerImageCode.from_image_asset(
directory="../../src/docker/ImagesWithSharedCode",
file="DockerImageFunctionWithSharedCode/Dockerfile",
),
tracing=lambda1.Tracing.ACTIVE,
)

function_image_asset_with_shared_code = lambda1.Function(
self,
"FunctionImageAssetWithSharedCode",
code=lambda1.Code.from_asset_image(
directory="../../src/docker/ImagesWithSharedCode",
file="FunctionImageAssetWithSharedCode/Dockerfile",
),
handler=lambda1.Handler.FROM_IMAGE,
runtime=lambda1.Runtime.FROM_IMAGE,
tracing=lambda1.Tracing.ACTIVE,
)

# Rest APIs

# Spec Rest Api
Expand Down Expand Up @@ -287,6 +311,12 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
normal_root_resource.add_resource("functionImageAsset").add_method(
"GET", LambdaIntegration(function_image_asset)
)
normal_root_resource.add_resource("dockerImageFunctionWithSharedCode").add_method(
"GET", LambdaIntegration(docker_image_function_with_shared_code)
)
normal_root_resource.add_resource("functionImageAssetWithSharedCode").add_method(
"GET", LambdaIntegration(function_image_asset_with_shared_code)
)

# Nested Stack
NestedStack1(self, "NestedStack")
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,25 @@ export class CDKSupportDemoRootStack extends cdk.Stack {
tracing: lambda.Tracing.ACTIVE,
});

// both ways work when 'file' is a path via subfolders to the Dockerfile
// this is useful when multiple docker images share some common code
const dockerImageFunctionWithSharedCode = new lambda.DockerImageFunction(this, "DockerImageFunctionWithSharedCode", {
code: lambda.DockerImageCode.fromImageAsset("../../src/docker/ImagesWithSharedCode", {
file: "DockerImageFunctionWithSharedCode/Dockerfile",
}),
tracing: lambda.Tracing.ACTIVE,
});

// another way
const functionImageAssetWithSharedCode = new lambda.Function(this, "FunctionImageAssetWithSharedCode", {
code: lambda.Code.fromAssetImage("../../src/docker/ImagesWithSharedCode", {
file: "FunctionImageAssetWithSharedCode/Dockerfile",
}),
handler: lambda.Handler.FROM_IMAGE,
runtime: lambda.Runtime.FROM_IMAGE,
tracing: lambda.Tracing.ACTIVE,
});


//Rest APIs

Expand Down Expand Up @@ -246,6 +265,12 @@ export class CDKSupportDemoRootStack extends cdk.Stack {
normalRootResource.addResource('functionImageAsset')
.addMethod('GET', new LambdaIntegration(functionImageAsset));

normalRootResource.addResource('dockerImageFunctionWithSharedCode')
.addMethod('GET', new LambdaIntegration(dockerImageFunctionWithSharedCode));

normalRootResource.addResource('functionImageAssetWithSharedCode')
.addMethod('GET', new LambdaIntegration(functionImageAssetWithSharedCode));

// Nested Stack
new NestedStack1(this, 'NestedStack' ,{});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM public.ecr.aws/lambda/nodejs:14

# Add the lambda handler for this feature
COPY DockerImageFunctionWithSharedCode/app.js ./

# Add the shared code
COPY SharedCode/ ./SharedCode

# Add the shared dependencies
COPY package.json ./

# Install the dependencies
RUN npm install

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "app.lambdaHandler" ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
var gen = require('unique-names-generator');
const {sayHelloWorld} = require("./SharedCode/shared");

const colorName = gen.uniqueNamesGenerator({
dictionaries: [gen.colors]
});


exports.lambdaHandler = async(event, context) => {
let response;

try {
response = {
'statusCode': 200,
'body': JSON.stringify({
message: sayHelloWorld("docker image function construct"),
}),
};
} catch (err) {
console.log(err);
return err;
}
return response;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM public.ecr.aws/lambda/nodejs:14

# Add the lambda handler for this feature
COPY FunctionImageAssetWithSharedCode/app.js ./

# Add the shared code
COPY SharedCode/ ./SharedCode

# Add the shared dependencies
COPY package.json ./

# Install the dependencies
RUN npm install

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "app.lambdaHandler" ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
var gen = require('unique-names-generator');
const {sayHelloWorld} = require("./SharedCode/shared");

const colorName = gen.uniqueNamesGenerator({
dictionaries: [gen.colors]
});


exports.lambdaHandler = async(event, context) => {
let response;

try {
response = {
'statusCode': 200,
'body': JSON.stringify({
message: sayHelloWorld("function construct with image asset"),
}),
};
} catch (err) {
console.log(err);
return err;
}
return response;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

exports.sayHelloWorld = (from) => {
return `Hello World from ${from} with a Dockerfile that shares code with another Dockerfile`;
}
Loading