11""" SAM macro definitions """
22
33import copy
4+ import re
45from contextlib import suppress
56from typing import Any , Callable , Dict , List , Literal , Optional , Tuple , Union , cast
67
@@ -238,7 +239,6 @@ class SamFunction(SamResourceMacro):
238239
239240 # DeadLetterQueue
240241 dead_letter_queue_policy_actions = {"SQS" : "sqs:SendMessage" , "SNS" : "sns:Publish" }
241- #
242242
243243 # Conditions
244244 conditions : Dict [str , Any ] = {} # TODO: Replace `Any` with something more specific
@@ -325,7 +325,7 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] # noqa: P
325325 resources .append (url_permission )
326326
327327 self ._validate_deployment_preference_and_add_update_policy (
328- kwargs .get ("deployment_preference_collection" , None ),
328+ kwargs .get ("deployment_preference_collection" ),
329329 lambda_alias ,
330330 intrinsics_resolver ,
331331 cast (IntrinsicsResolver , mappings_resolver ), # TODO: better handle mappings_resolver's Optional
@@ -1002,7 +1002,22 @@ def _construct_alias(self, name: str, function: LambdaFunction, version: LambdaV
10021002 if not name :
10031003 raise InvalidResourceException (self .logical_id , "Alias name is required to create an alias" )
10041004
1005- logical_id = f"{ function .logical_id } Alias{ name } "
1005+ # Validate alias name against the required pattern: (?!^[0-9]+$)([a-zA-Z0-9-_]+)
1006+ # This ensures the alias name:
1007+ # 1. Contains only alphanumeric characters, hyphens, and underscores
1008+ # 2. Is not purely numeric
1009+ ALIAS_REGEX = r"(?!^[0-9]+$)([a-zA-Z0-9\-_]+)$"
1010+ if not re .match (ALIAS_REGEX , name ):
1011+ raise InvalidResourceException (
1012+ self .logical_id ,
1013+ f"AutoPublishAlias name ('{ name } ') must contain only alphanumeric characters, hyphens, or underscores matching (?!^[0-9]+$)([a-zA-Z0-9-_]+) pattern." ,
1014+ )
1015+
1016+ # Strip hyphens and underscores from the alias name for the logical ID
1017+ # This ensures the logical ID contains only alphanumeric characters
1018+ alias_alphanumeric_name = name .replace ("-" , "D" ).replace ("_" , "U" )
1019+
1020+ logical_id = f"{ function .logical_id } Alias{ alias_alphanumeric_name } "
10061021 alias = LambdaAlias (logical_id = logical_id , attributes = self .get_passthrough_resource_attributes ())
10071022 alias .Name = name
10081023 alias .FunctionName = function .get_runtime_attr ("name" )
@@ -1014,7 +1029,7 @@ def _construct_alias(self, name: str, function: LambdaFunction, version: LambdaV
10141029
10151030 def _validate_deployment_preference_and_add_update_policy ( # noqa: PLR0913
10161031 self ,
1017- deployment_preference_collection : DeploymentPreferenceCollection ,
1032+ deployment_preference_collection : Optional [ DeploymentPreferenceCollection ] ,
10181033 lambda_alias : Optional [LambdaAlias ],
10191034 intrinsics_resolver : IntrinsicsResolver ,
10201035 mappings_resolver : IntrinsicsResolver ,
0 commit comments