Skip to content
This repository was archived by the owner on Oct 10, 2025. It is now read-only.

Commit 0168785

Browse files
committed
Ensure CfnParameter ordering is respected
Fixes an issue where CloudFormation parameter group ordering was not guaranteed
1 parent a9e4a47 commit 0168785

File tree

4 files changed

+92
-6
lines changed

4 files changed

+92
-6
lines changed

source/cdk_solution_helper_py/helpers_cdk/aws_solutions/cdk/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,13 @@ class CDKSolution:
2929
"""
3030

3131
def __init__(self, cdk_json_path: Path, qualifier="hnb659fds"):
32+
self.qualifier = qualifier
3233
self.context = SolutionContext(cdk_json_path=cdk_json_path)
33-
self.synthesizer = SolutionStackSubstitions(qualifier=qualifier)
34+
self.synthesizer = SolutionStackSubstitions(qualifier=self.qualifier)
35+
36+
def reset(self) -> None:
37+
"""
38+
Get a new synthesizer for this CDKSolution - useful for testing
39+
:return: None
40+
"""
41+
self.synthesizer = SolutionStackSubstitions(qualifier=self.qualifier)

source/cdk_solution_helper_py/helpers_cdk/aws_solutions/cdk/interfaces.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,12 @@ def metadata(self) -> dict:
7777
return self._metadata
7878

7979
def _get_metadata(self) -> dict:
80-
parameter_groups = list(
81-
set([parameter.group for parameter in self._parameters])
82-
)
80+
pgs = set()
81+
parameter_groups = [
82+
p.group
83+
for p in self._parameters
84+
if p.group not in pgs and not pgs.add(p.group)
85+
]
8386
metadata = {
8487
"AWS::CloudFormation::Interface": {
8588
"ParameterGroups": [

source/tests/cdk_solution_helper/test_stack.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import re
1515

1616
import pytest
17-
from aws_cdk.core import App
17+
from aws_cdk.core import App, CfnParameter
1818

1919
from aws_solutions.cdk.stack import (
2020
SolutionStack,
@@ -113,3 +113,39 @@ def test_solution_stack():
113113
]
114114
}
115115
}
116+
117+
118+
@pytest.mark.parametrize("execution_number", range(5))
119+
def test_stack_parameter_ordering(execution_number):
120+
app = App(context={"SOLUTION_ID": "SO0123"})
121+
stack = SolutionStack(app, "stack", "test stack", "test-stack.template")
122+
123+
param_1 = CfnParameter(stack, "parameter1")
124+
param_2 = CfnParameter(stack, "parameter2")
125+
126+
stack.solutions_template_options.add_parameter(param_1, "parameter 1", "group 1")
127+
stack.solutions_template_options.add_parameter(param_2, "parameter 2", "group 2")
128+
129+
template = app.synth().stacks[0].template
130+
131+
assert (
132+
template["Metadata"]["AWS::CloudFormation::Interface"]["ParameterGroups"][0][
133+
"Label"
134+
]["default"]
135+
== "group 1"
136+
)
137+
assert template["Metadata"]["AWS::CloudFormation::Interface"]["ParameterGroups"][0][
138+
"Parameters"
139+
] == ["parameter1"]
140+
assert (
141+
template["Metadata"]["AWS::CloudFormation::Interface"]["ParameterLabels"][
142+
"parameter1"
143+
]["default"]
144+
== "parameter 1"
145+
)
146+
assert (
147+
template["Metadata"]["AWS::CloudFormation::Interface"]["ParameterLabels"][
148+
"parameter2"
149+
]["default"]
150+
== "parameter 2"
151+
)

source/tests/test_deploy.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ def cdk_entrypoint():
2525

2626

2727
def test_deploy(solution, cdk_entrypoint):
28-
from deploy import build_app
28+
from deploy import build_app, solution as cdk_solution
29+
30+
cdk_solution.reset()
2931

3032
extra_context = "EXTRA_CONTEXT"
3133
source_bucket = "SOURCE_BUCKET"
@@ -40,3 +42,40 @@ def test_deploy(solution, cdk_entrypoint):
4042
"Yes"
4143
== stack.template["Mappings"]["Solution"]["Data"]["SendAnonymousUsageData"]
4244
)
45+
assert stack.template["Outputs"]["PersonalizeBucketName"]
46+
assert stack.template["Outputs"]["SchedulerTableName"]
47+
assert stack.template["Outputs"]["SNSTopicArn"]
48+
49+
50+
def test_parameters(solution, cdk_entrypoint):
51+
"""Ensure parameter ordering is kept"""
52+
from deploy import build_app, solution as cdk_solution
53+
54+
cdk_solution.reset()
55+
56+
extra_context = "EXTRA_CONTEXT"
57+
source_bucket = "SOURCE_BUCKET"
58+
synth = build_app({extra_context: extra_context, "BUCKET_NAME": source_bucket})
59+
stack = synth.get_stack("PersonalizeStack").template
60+
61+
assert (
62+
stack["Metadata"]["AWS::CloudFormation::Interface"]["ParameterGroups"][0][
63+
"Label"
64+
]["default"]
65+
== "Solution Configuration"
66+
)
67+
assert stack["Metadata"]["AWS::CloudFormation::Interface"]["ParameterGroups"][0][
68+
"Parameters"
69+
] == ["Email"]
70+
assert (
71+
stack["Metadata"]["AWS::CloudFormation::Interface"]["ParameterLabels"]["Email"][
72+
"default"
73+
]
74+
== "Email"
75+
)
76+
assert (
77+
stack["Metadata"]["AWS::CloudFormation::Interface"]["ParameterLabels"][
78+
"PersonalizeKmsKeyArn"
79+
]["default"]
80+
== "(Optional) KMS key ARN used to encrypt Datasets managed by Amazon Personalize"
81+
)

0 commit comments

Comments
 (0)