Skip to content

Commit d06ad57

Browse files
authored
Support new language extension foreach capabilities (#3033)
1 parent ff1d1d5 commit d06ad57

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

src/cfnlint/template/transforms/_language_extensions.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,14 @@ def _walk(self, item: Any, params: MutableMapping[str, Any], cfn: Any):
195195
def _replace_string_params(
196196
self, s: str, params: Mapping[str, Any]
197197
) -> Tuple[bool, str]:
198-
pattern = r"\${[a-zA-Z0-9\.:]+}"
198+
pattern = r"(\$|&){[a-zA-Z0-9\.:]+}"
199199
if not re.search(pattern, s):
200200
return (True, s)
201201

202202
new_s = deepcopy(s)
203203
for k, v in params.items():
204204
new_s = re.sub(rf"\$\{{{k}\}}", v, new_s)
205+
new_s = re.sub(rf"\&\{{{k}\}}", re.sub("[^0-9a-zA-Z]+", "", v), new_s)
205206

206207
if isinstance(s, str_node):
207208
new_s = str_node(new_s, s.start_mark, s.end_mark)

test/unit/module/template/transforms/test_language_extensions.py

+29-2
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,21 @@ def setUp(self) -> None:
241241
},
242242
}
243243
},
244-
]
244+
],
245+
"Fn::ForEach::SpecialCharacters": [
246+
"Identifier",
247+
["a-b", "c-d"],
248+
{
249+
"S3Bucket&{Identifier}": {
250+
"Type": "AWS::S3::Bucket",
251+
"Properties": {
252+
"BucketName": {
253+
"Fn::Sub": "bucket-name-&{Identifier}"
254+
},
255+
},
256+
}
257+
},
258+
],
245259
},
246260
"Outputs": {
247261
"Fn::ForEach::BucketOutputs": [
@@ -318,6 +332,18 @@ def setUp(self) -> None:
318332
},
319333
"Type": "AWS::S3::Bucket",
320334
},
335+
"S3Bucketab": {
336+
"Properties": {
337+
"BucketName": "bucket-name-ab",
338+
},
339+
"Type": "AWS::S3::Bucket",
340+
},
341+
"S3Bucketcd": {
342+
"Properties": {
343+
"BucketName": "bucket-name-cd",
344+
},
345+
"Type": "AWS::S3::Bucket",
346+
},
321347
},
322348
"Transforms": ["AWS::LanguageExtensions"],
323349
}
@@ -331,6 +357,7 @@ def test_transform(self):
331357
self.assertDictEqual(
332358
template,
333359
self.result,
360+
template,
334361
)
335362

336363
def test_transform_findinmap_function(self):
@@ -373,7 +400,7 @@ def test_bad_collection_ref(self):
373400
cfn = Template(filename="", template=template_obj, regions=["us-east-1"])
374401
matches, template = language_extension(cfn)
375402
self.assertListEqual(matches, [])
376-
self.assertTrue(len(template["Resources"]) == 2)
403+
self.assertTrue(len(template["Resources"]) == 4)
377404
self.assertTrue("S3BucketA" in template["Resources"])
378405

379406
def test_duplicate_key(self):

0 commit comments

Comments
 (0)