Skip to content

Commit a95c522

Browse files
committed
Handle parameter conversions for different transforms
1 parent d61865f commit a95c522

File tree

2 files changed

+33
-19
lines changed

2 files changed

+33
-19
lines changed

localstack-core/localstack/services/cloudformation/engine/transformers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from localstack.aws.api import CommonServiceException
1616
from localstack.aws.connect import connect_to
17+
from localstack.services.cloudformation.engine.parameters import StackParameter
1718
from localstack.services.cloudformation.engine.policy_loader import create_policy_loader
1819
from localstack.services.cloudformation.engine.template_deployer import resolve_refs_recursively
1920
from localstack.services.cloudformation.engine.validations import ValidationError
@@ -39,7 +40,7 @@ class ResolveRefsRecursivelyContext:
3940
resources: dict
4041
mappings: dict
4142
conditions: dict
42-
parameters: dict
43+
parameters: dict[str, StackParameter]
4344

4445
def resolve(self, value: Any) -> Any:
4546
return resolve_refs_recursively(

localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_transform.py

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
from localstack.services.cloudformation.engine.validations import ValidationError
4343
from localstack.services.cloudformation.stores import get_cloudformation_store
4444
from localstack.services.cloudformation.v2.entities import ChangeSet
45-
from localstack.services.cloudformation.v2.types import engine_parameter_value
45+
from localstack.services.cloudformation.v2.types import EngineParameter, engine_parameter_value
4646
from localstack.utils import testutil
4747
from localstack.utils.strings import long_uid
4848

@@ -56,6 +56,20 @@
5656
_SCOPE_TRANSFORM_TEMPLATE_OUTCOME: Final[Scope] = Scope("TRANSFORM_TEMPLATE_OUTCOME")
5757

5858

59+
def engine_parameters_to_stack_parameters(
60+
engine_parameters: dict[str, EngineParameter],
61+
) -> dict[str, StackParameter]:
62+
out = {}
63+
for name, engine_param in engine_parameters.items():
64+
out[name] = StackParameter(
65+
ParameterKey=name,
66+
ParameterValue=engine_parameter_value(engine_param),
67+
ResolvedValue=engine_param.get("resolved_value"),
68+
ParameterType=engine_param["type_"],
69+
)
70+
return out
71+
72+
5973
# TODO: evaluate the use of subtypes to represent and validate types of transforms
6074
class GlobalTransform:
6175
name: str
@@ -74,8 +88,8 @@ class TransformPreprocParameter(TypedDict):
7488

7589

7690
class ChangeSetModelTransform(ChangeSetModelPreproc):
77-
_before_parameters: Final[dict]
78-
_after_parameters: Final[dict]
91+
_before_parameters: Final[dict[str, EngineParameter] | None]
92+
_after_parameters: Final[dict[str, EngineParameter] | None]
7993
_before_template: Final[Maybe[dict]]
8094
_after_template: Final[Maybe[dict]]
8195

@@ -153,7 +167,10 @@ def _compute_include_transform(self, parameters: dict, fragment: dict) -> dict:
153167
return {**fragment, **template_to_include}
154168

155169
def _apply_global_transform(
156-
self, global_transform: GlobalTransform, template: dict, parameters: dict
170+
self,
171+
global_transform: GlobalTransform,
172+
template: dict,
173+
parameters: dict[str, EngineParameter],
157174
) -> dict:
158175
transform_name = global_transform.name
159176
if transform_name == EXTENSIONS_TRANSFORM:
@@ -168,14 +185,20 @@ def _apply_global_transform(
168185
resources,
169186
mappings,
170187
conditions,
171-
parameters,
188+
parameters=engine_parameters_to_stack_parameters(parameters),
172189
)
173190
transformed_template = apply_language_extensions_transform(template, resolve_context)
174191
elif transform_name == SERVERLESS_TRANSFORM:
192+
# serverless transform just requires the key/value pairs
193+
serverless_parameters = {}
194+
for name, param in parameters.items():
195+
serverless_parameters[name] = param.get("resolved_value") or engine_parameter_value(
196+
param
197+
)
175198
transformed_template = self._apply_global_serverless_transformation(
176199
region_name=self._change_set.region_name,
177200
template=template,
178-
parameters=parameters,
201+
parameters=serverless_parameters,
179202
)
180203
elif transform_name == SECRETSMANAGER_TRANSFORM:
181204
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-aws-secretsmanager.html
@@ -217,11 +240,9 @@ def _execute_global_transforms(self) -> tuple[dict, dict]:
217240
else:
218241
for before_global_transform in transform_before:
219242
if not is_nothing(before_global_transform.name):
220-
before_parameters = {}
221-
222243
transformed_before_template = self._apply_global_transform(
223244
global_transform=before_global_transform,
224-
parameters=before_parameters,
245+
parameters=self._before_parameters,
225246
template=transformed_before_template,
226247
)
227248

@@ -235,17 +256,9 @@ def _execute_global_transforms(self) -> tuple[dict, dict]:
235256
transformed_after_template = self._after_template
236257
for after_global_transform in transform_after:
237258
if not is_nothing(after_global_transform.name):
238-
after_parameters: dict[str, StackParameter] = {}
239-
for name, engine_param in self._after_parameters.items():
240-
after_parameters[name] = StackParameter(
241-
ParameterKey=name,
242-
ParameterValue=engine_parameter_value(engine_param),
243-
ResolvedValue=engine_param.get("resolved_value"),
244-
ParameterType=engine_param["type_"],
245-
)
246259
transformed_after_template = self._apply_global_transform(
247260
global_transform=after_global_transform,
248-
parameters=after_parameters,
261+
parameters=self._after_parameters,
249262
template=transformed_after_template,
250263
)
251264
# Macro transformations won't remove the transform from the template

0 commit comments

Comments
 (0)