@@ -118,7 +118,10 @@ def resources(self, stack: Stack) -> list[AWSObject | Construct]:
118118 # Add the parameter during template creation even if the S3 key may not
119119 # be known yet. This is useful if creating a stack from code, so that
120120 # the exported template contains the parameter
121- stack .add_parameter (self .s3_key_parameter )
121+ stack .add_parameter (
122+ self .s3_key_parameter ,
123+ update_if_exist = True ,
124+ )
122125 # Adding the Output can be useful for Lambda function with versioning.
123126 # The exported value can be retrieved by the lambda without the need to update
124127 # the lambda version.
@@ -128,7 +131,8 @@ def resources(self, stack: Stack) -> list[AWSObject | Construct]:
128131 Description = f"S3 URI for the Asset { self .name } " ,
129132 Export = Export (name = self .s3_uri_output_name ),
130133 Value = f"s3://{ stack .s3_bucket } /{ stack .s3_assets_key } { self .s3_key } " ,
131- )
134+ ),
135+ update_if_exist = True ,
132136 )
133137 return []
134138
@@ -276,7 +280,7 @@ def add(self, element: AWSObject | Construct | Stack) -> Stack:
276280 # Special case to keep track of Assets and generate parameters
277281 # for the S3 keys
278282 if isinstance (construct , Asset ):
279- self .add_parameter (construct .s3_key_parameter )
283+ self .add_parameter (construct .s3_key_parameter , update_if_exist = True )
280284 self .assets [construct .name ] = construct
281285
282286 constructs_to_objects .extend (construct .resources (stack = self ))
@@ -295,26 +299,41 @@ def extend(self, elements: Iterable[AWSObject | Construct | Stack]) -> Stack:
295299
296300 return self
297301
298- def add_parameter (self , parameter : Parameter | list [Parameter ]) -> None :
302+ def add_parameter (
303+ self , parameter : Parameter | list [Parameter ], update_if_exist : bool = False
304+ ) -> None :
299305 """Add parameters to stack template.
300306
301307 :param parameter: parameter to add to the template
308+ :param update_if_exist: update the parameter if already exists, avoiding
309+ the duplicate key exception
302310 """
303311 if not isinstance (parameter , list ):
304312 parameter = [parameter ]
305313
306314 for param in parameter :
307- if param .title in self .template .parameters :
315+ if update_if_exist and param .title in self .template .parameters :
308316 self .template .parameters [param .title ] = param
309317 else :
310318 self .template .add_parameter (param )
311319
312- def add_output (self , output : Output | list [Output ]) -> None :
320+ def add_output (
321+ self , output : Output | list [Output ], update_if_exist : bool = False
322+ ) -> None :
313323 """Add outputs to stack template.
314324
315325 :param output: output to add to the template
326+ :param update_if_exist: update the output if already exists, avoiding
327+ the duplicate key exception
316328 """
317- self .template .add_output (output )
329+ if not isinstance (output , list ):
330+ output = [output ]
331+
332+ for out in output :
333+ if update_if_exist and out .title in self .template .outputs :
334+ self .template .outputs [out .title ] = out
335+ else :
336+ self .template .add_output (out )
318337
319338 def add_condition (self , condition_name : str , condition : ConditionFunction ) -> None :
320339 """Add condition to stack template.
0 commit comments