Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 22 additions & 2 deletions samcli/lib/providers/sam_function_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,12 @@ def _extract_functions(
SamFunctionProvider._warn_code_extraction(resource_type, name, code_property_key)
continue

if resource_package_type == IMAGE and SamBaseProvider._is_ecr_uri(
resource_properties.get(image_property_key)
if (
resource_package_type == IMAGE
and SamBaseProvider._is_ecr_uri(resource_properties.get(image_property_key))
and not SamFunctionProvider._metadata_has_necessary_entries_for_image_function_to_be_built(
resource_metadata
)
):
# ImageUri can be an ECR uri, which is not supported
if not ignore_code_extraction_warnings:
Expand Down Expand Up @@ -460,3 +464,19 @@ def get_resources_by_stack_path(self, stack_path: str) -> Dict:
if not candidates:
raise RuntimeError(f"Cannot find resources with stack_path = {stack_path}")
return candidates[0]

@staticmethod
def _metadata_has_necessary_entries_for_image_function_to_be_built(metadata: Optional[Dict[str, Any]]) -> bool:
"""
> Note: If the PackageType property is set to Image, then either ImageUri is required,
or you must build your application with necessary Metadata entries in the AWS SAM template file.
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-function-imageuri

When ImageUri and Metadata are both provided, we will try to determine whether to treat the function
as to be built or to be skipped. When we skip it whenever "ImageUri" is provided,
we introduced a breaking change https://github.com/aws/aws-sam-cli/issues/3239

This function is used to check whether there are the customers have "intention" to
let AWS SAM CLI to build this image function.
"""
return isinstance(metadata, dict) and bool(metadata.get("DockerContext"))
74 changes: 74 additions & 0 deletions tests/unit/commands/local/lib/test_sam_function_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ class TestSamFunctionProviderEndToEnd(TestCase):
"PackageType": IMAGE,
},
},
"SamFuncWithImage4": {
# ImageUri is unsupported ECR location, but metadata is still provided, build
"Type": "AWS::Serverless::Function",
"Properties": {
"ImageUri": "123456789012.dkr.ecr.us-east-1.amazonaws.com/myrepo:myimage",
"PackageType": IMAGE,
},
"Metadata": {"DockerTag": "tag", "DockerContext": "./image", "Dockerfile": "Dockerfile"},
},
"LambdaFunc1": {
"Type": "AWS::Lambda::Function",
"Properties": {
Expand Down Expand Up @@ -126,6 +135,15 @@ class TestSamFunctionProviderEndToEnd(TestCase):
"PackageType": IMAGE,
},
},
"LambdaFuncWithImage4": {
# ImageUri is unsupported ECR location, but metadata is still provided, build
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {"ImageUri": "123456789012.dkr.ecr.us-east-1.amazonaws.com/myrepo"},
"PackageType": IMAGE,
},
"Metadata": {"DockerTag": "tag", "DockerContext": "./image", "Dockerfile": "Dockerfile"},
},
"LambdaFuncWithInlineCode": {
"Type": "AWS::Lambda::Function",
"Properties": {
Expand Down Expand Up @@ -337,6 +355,33 @@ def setUp(self):
),
),
("SamFuncWithImage3", None), # imageuri is ecr location, ignored
(
"SamFuncWithImage4", # despite imageuri is ecr location, the necessary metadata is still provided, build
Function(
name="SamFuncWithImage4",
functionname="SamFuncWithImage4",
runtime=None,
handler=None,
codeuri=".",
memory=None,
timeout=None,
environment=None,
rolearn=None,
layers=[],
events=None,
inlinecode=None,
imageuri="123456789012.dkr.ecr.us-east-1.amazonaws.com/myrepo:myimage",
imageconfig=None,
packagetype=IMAGE,
metadata={
"DockerTag": "tag",
"DockerContext": os.path.join("image"),
"Dockerfile": "Dockerfile",
},
codesign_config_arn=None,
stack_path="",
),
),
(
"SamFuncWithFunctionNameOverride-x",
Function(
Expand Down Expand Up @@ -416,6 +461,33 @@ def setUp(self):
),
),
("LambdaFuncWithImage3", None), # imageuri is a ecr location, ignored
(
"LambdaFuncWithImage4", # despite imageuri is ecr location, the necessary metadata is still provided, build
Function(
name="LambdaFuncWithImage4",
functionname="LambdaFuncWithImage4",
runtime=None,
handler=None,
codeuri=".",
memory=None,
timeout=None,
environment=None,
rolearn=None,
layers=[],
events=None,
metadata={
"DockerTag": "tag",
"DockerContext": os.path.join("image"),
"Dockerfile": "Dockerfile",
},
inlinecode=None,
imageuri="123456789012.dkr.ecr.us-east-1.amazonaws.com/myrepo",
imageconfig=None,
packagetype=IMAGE,
codesign_config_arn=None,
stack_path="",
),
),
(
"LambdaFuncWithInlineCode",
Function(
Expand Down Expand Up @@ -595,10 +667,12 @@ def test_get_all_must_return_all_functions(self):
"SamFunctions",
"SamFuncWithImage1",
"SamFuncWithImage2",
"SamFuncWithImage4",
"SamFuncWithInlineCode",
"SamFuncWithFunctionNameOverride",
"LambdaFuncWithImage1",
"LambdaFuncWithImage2",
"LambdaFuncWithImage4",
"LambdaFuncWithInlineCode",
"LambdaFuncWithLocalPath",
"LambdaFuncWithFunctionNameOverride",
Expand Down