Skip to content

Commit 0422f6c

Browse files
committed
Fix GetAtt to ForEach modules using identifiers
1 parent eefa26e commit 0422f6c

File tree

5 files changed

+38
-4
lines changed

5 files changed

+38
-4
lines changed

awscli/customizations/cloudformation/modules/maps.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
ORIGINAL_MAP_NAME = "OriginalMapName"
4141
VALUE = "Value"
4242
FOREACH_PREFIX = "Fn::ForEach::"
43+
MAP_NAME_IS_I = "map_name_is_i"
4344

4445

4546
def replace_str(s, m, i):
@@ -289,6 +290,7 @@ def vf(vis):
289290

290291
# Remember the original name for GetAtt resolution
291292
modules[module_id][ORIGINAL_MAP_NAME] = loop_name
293+
modules[module_id][MAP_NAME_IS_I] = False
292294

293295
# Remove the ForEach entry
294296
del modules[k]

awscli/customizations/cloudformation/modules/process.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
resolve_mapped_lists,
3737
getatt_map_list,
3838
ORIGINAL_MAP_NAME,
39+
MAP_NAME_IS_I,
3940
)
4041
from awscli.customizations.cloudformation.modules.read import (
4142
is_url,
@@ -146,6 +147,8 @@ def make_module(
146147
module_config[OVERRIDES] = config[OVERRIDES]
147148
if ORIGINAL_MAP_NAME in config:
148149
module_config[ORIGINAL_MAP_NAME] = config[ORIGINAL_MAP_NAME]
150+
if MAP_NAME_IS_I in config:
151+
module_config[MAP_NAME_IS_I] = config[MAP_NAME_IS_I]
149152
module_config[NO_SOURCE_MAP] = no_source_map
150153
return Module(template, module_config, parent_module, s3_client)
151154

@@ -283,6 +286,11 @@ def __init__(self, template, module_config, parent_module, s3_client=None):
283286
self.parent_path = module_config.get(PARENT_PATH, "")
284287
self.invoked = module_config.get(INVOKED, False)
285288

289+
# Default behavior for Map/ForEach is to use array indexes
290+
self.map_name_is_i = True
291+
if MAP_NAME_IS_I in module_config:
292+
self.map_name_is_i = module_config[MAP_NAME_IS_I]
293+
286294
if RESOURCES not in self.template:
287295
# The parent might only have Modules
288296
self.template[RESOURCES] = {}
@@ -700,14 +708,25 @@ def resolve_output_getatt(self, v, d, n):
700708
self.resolve_output_getatt_map(mapped, name, prop_name)
701709
return False
702710

711+
# index might be a number like 0: Content[0].Arn
712+
# or it might be a key like A: Content[A].Arn
713+
# The name of the mapped module might be Content0 or ContentA,
714+
# depending on if we used an Fn::ForEach identifier.
715+
703716
if index != -1:
704-
if num.isdigit():
717+
if isinstance(index, int):
705718
name = f"{name}{index}"
706719
else:
707720
# Find the array index for the key
708-
for i, k in enumerate(mapped[name]):
709-
if index == k:
710-
name = f"{name}{i}"
721+
if not self.map_name_is_i:
722+
# If Fn::ForEach was used with an identifier for
723+
# the logical id, we need to use that instead of the index
724+
name = f"{name}{index}"
725+
else:
726+
# The mapped name uses the array index
727+
for i, k in enumerate(mapped[name]):
728+
if index == k:
729+
name = f"{name}{i}"
711730

712731
reffed_prop = None
713732
if name == self.name:

tests/unit/customizations/cloudformation/modules/foreach-expect.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,8 @@ Resources:
2323
Type: A::B::C
2424
Properties:
2525
Name: b-C
26+
Outputs:
27+
TestGetAttA:
28+
Value: !GetAtt A0Foo.Arn
29+
TestGetAttB:
30+
Value: !GetAtt BBFoo.Arn

tests/unit/customizations/cloudformation/modules/foreach-module.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ Resources:
66
Type: A::B::C
77
Properties:
88
Name: !Ref Name
9+
Outputs:
10+
Out1:
11+
Value: !GetAtt Foo.Arn

tests/unit/customizations/cloudformation/modules/foreach-template.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ Modules:
1313
Source: foreach-module.yaml
1414
Properties:
1515
Name: b-${TheKey}
16+
Outputs:
17+
TestGetAttA:
18+
Value: !GetAtt A[0].Out1
19+
TestGetAttB:
20+
Value: !GetAtt B[B].Out1
1621

1722

1823

0 commit comments

Comments
 (0)