Skip to content

Commit 4715a1d

Browse files
refactor: getLambdasInStack returns lambdas in nested stack
1 parent 999bb8b commit 4715a1d

File tree

3 files changed

+63
-109
lines changed

3 files changed

+63
-109
lines changed

src/cloudFormation.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,24 +139,48 @@ async function getLambdasInStack(
139139
Array<{
140140
lambdaName: string;
141141
logicalId: string;
142+
stackName: string;
142143
}>
143144
> {
144145
const response = await getCloudFormationResources(
145146
stackName,
146147
awsConfiguration,
147148
);
149+
148150
const lambdaResources = response?.filter(
149151
(resource) => resource.ResourceType === 'AWS::Lambda::Function',
150152
);
151153

152-
return (
154+
const nestedStacks = response?.filter(
155+
(resource) => resource.ResourceType === 'AWS::CloudFormation::Stack',
156+
);
157+
158+
const lambdas =
153159
lambdaResources?.map((resource) => {
154160
return {
155161
lambdaName: resource.PhysicalResourceId!,
156162
logicalId: resource.LogicalResourceId!,
163+
stackName: stackName,
157164
};
158-
}) ?? []
165+
}) ?? [];
166+
167+
const lambdasInNestedStacks = await Promise.all(
168+
(nestedStacks ?? []).map(async (nestedStack) => {
169+
if (!nestedStack.PhysicalResourceId) return [];
170+
171+
const lambdasInNestedStack = await getLambdasInStack(
172+
nestedStack.PhysicalResourceId,
173+
awsConfiguration,
174+
);
175+
176+
return lambdasInNestedStack;
177+
}),
159178
);
179+
180+
const flattenedLambdasInNestedStacks = lambdasInNestedStacks.flat();
181+
182+
const allLambdas = [...lambdas, ...flattenedLambdasInNestedStacks];
183+
return allLambdas;
160184
}
161185

162186
/**

src/frameworks/cdkFramework.ts

Lines changed: 37 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -71,83 +71,66 @@ export class CdkFramework implements IFramework {
7171
);
7272

7373
const cdkTokenRegex = /^\${Token\[TOKEN\.\d+\]}$/;
74-
const stackTokensCdkPathMappings = Object.fromEntries(
75-
lambdasInCdk
76-
.filter((lambda) => cdkTokenRegex.test(lambda.stackName))
77-
.map((lambda) => [lambda.stackName, lambda.stackCdkPath]),
78-
);
79-
const realStackNames = [
80-
...new Set(
81-
lambdasInCdk.map((lambda) => {
82-
return lambda.rootStackName;
83-
}),
84-
),
85-
];
8674

87-
const unresolvedTokens = new Set(Object.keys(stackTokensCdkPathMappings));
88-
const resolvedTokenizedStackNames = new Set<string>();
89-
90-
if (Object.keys(stackTokensCdkPathMappings).length) {
91-
Logger.verbose(
92-
`[CDK] Found tokenized stackNames: ${[...unresolvedTokens].join(', ')}`,
93-
);
94-
Logger.verbose(
95-
`[CDK] Will look for tokenized stackNames in ${realStackNames.join(
96-
', ',
97-
)}`,
98-
);
99-
for (const realStackName of realStackNames) {
100-
if (!unresolvedTokens.size) break;
101-
await this.resolveTokenizedStackNames(
102-
unresolvedTokens,
103-
resolvedTokenizedStackNames,
104-
stackTokensCdkPathMappings,
105-
awsConfiguration,
106-
realStackName,
107-
);
75+
const stackNamesDuplicated = lambdasInCdk.map((lambda) => {
76+
if (cdkTokenRegex.test(lambda.stackName)) {
77+
return lambda.rootStackName;
78+
} else {
79+
return lambda.stackName;
10880
}
109-
}
81+
});
82+
83+
const stackNames = [...new Set(stackNamesDuplicated)];
11084

111-
//get all stack names
112-
const stackNames = [
113-
...new Set(realStackNames.concat([...resolvedTokenizedStackNames])), // unique
114-
];
11585
Logger.verbose(
11686
`[CDK] Found the following stacks in CDK: ${stackNames.join(', ')}`,
11787
);
11888

11989
const lambdasDeployed = (
12090
await Promise.all(
12191
stackNames.map(async (stackName) => {
122-
const lambdasInStackPromise = CloudFormation.getLambdasInStack(
92+
const lambdasInStack = await CloudFormation.getLambdasInStack(
12393
stackName,
12494
awsConfiguration,
12595
);
126-
const lambdasMetadataPromise =
127-
this.getLambdaCdkPathFromTemplateMetadata(
128-
stackName,
129-
awsConfiguration,
130-
);
13196

132-
const lambdasInStack = await lambdasInStackPromise;
97+
const stackAndNestedStackNames = [
98+
...new Set(lambdasInStack.map((l) => l.stackName)),
99+
];
100+
101+
const lambdasMetadata = (
102+
await Promise.all(
103+
stackAndNestedStackNames.map((stackOrNestedStackName) =>
104+
this.getLambdaCdkPathFromTemplateMetadata(
105+
stackOrNestedStackName,
106+
awsConfiguration,
107+
),
108+
),
109+
)
110+
).flat();
111+
133112
Logger.verbose(
134113
`[CDK] Found Lambda functions in the stack ${stackName}:`,
135114
JSON.stringify(lambdasInStack, null, 2),
136115
);
137-
const lambdasMetadata = await lambdasMetadataPromise;
116+
138117
Logger.verbose(
139118
`[CDK] Found Lambda functions in the stack ${stackName} in the template metadata:`,
140119
JSON.stringify(lambdasMetadata, null, 2),
141120
);
142121

143-
return lambdasInStack.map((lambda) => {
122+
const lambdasPhysicalResourceIds = lambdasInStack.map((lambda) => {
144123
return {
145124
lambdaName: lambda.lambdaName,
146125
cdkPath: lambdasMetadata.find(
147-
(lm) => lm.logicalId === lambda.logicalId,
126+
(lm) =>
127+
lm.logicalId === lambda.logicalId &&
128+
lm.stackName === lambda.stackName,
148129
)?.cdkPath,
149130
};
150131
});
132+
133+
return lambdasPhysicalResourceIds;
151134
}),
152135
)
153136
).flat();
@@ -204,61 +187,6 @@ export class CdkFramework implements IFramework {
204187
return lambdasDiscovered;
205188
}
206189

207-
protected async resolveTokenizedStackNames(
208-
unresolvedTokens: Set<string>,
209-
resolvedTokenizedStackNames: Set<string>,
210-
stackTokensCdkPathMappings: Record<string, string>,
211-
awsConfiguration: AwsConfiguration,
212-
stackName: string,
213-
): Promise<void> {
214-
if (!unresolvedTokens.size) {
215-
return;
216-
}
217-
218-
const cfTemplate = await CloudFormation.getCloudFormationStackTemplate(
219-
stackName,
220-
awsConfiguration,
221-
);
222-
223-
if (cfTemplate) {
224-
const nestedStacks = Object.entries(cfTemplate.Resources)
225-
.filter(
226-
([, resource]: [string, any]) =>
227-
resource.Type === 'AWS::CloudFormation::Stack',
228-
)
229-
.map(([key, resource]: [string, any]) => {
230-
return {
231-
logicalId: key,
232-
cdkPath: resource.Metadata['aws:cdk:path'],
233-
};
234-
});
235-
236-
for (const nestedStack of nestedStacks) {
237-
const mapping = Object.entries(stackTokensCdkPathMappings).find(
238-
(f) => f[1] === nestedStack.cdkPath,
239-
);
240-
241-
if (mapping) {
242-
unresolvedTokens.delete(mapping[0]);
243-
const physicalResourceId =
244-
await CloudFormation.getStackResourcePhysicalResourceId(
245-
stackName,
246-
nestedStack.logicalId,
247-
awsConfiguration,
248-
);
249-
resolvedTokenizedStackNames.add(physicalResourceId);
250-
await this.resolveTokenizedStackNames(
251-
unresolvedTokens,
252-
resolvedTokenizedStackNames,
253-
stackTokensCdkPathMappings,
254-
awsConfiguration,
255-
physicalResourceId,
256-
);
257-
}
258-
}
259-
}
260-
}
261-
262190
/**
263191
* Getz Lambda functions from the CloudFormation template metadata
264192
* @param stackName
@@ -272,6 +200,7 @@ export class CdkFramework implements IFramework {
272200
Array<{
273201
logicalId: string;
274202
cdkPath: string;
203+
stackName: string;
275204
}>
276205
> {
277206
const cfTemplate = await CloudFormation.getCloudFormationStackTemplate(
@@ -289,8 +218,10 @@ export class CdkFramework implements IFramework {
289218
return {
290219
logicalId: key,
291220
cdkPath: resource.Metadata['aws:cdk:path'],
221+
stackName: stackName,
292222
};
293223
});
224+
294225
return lambdas;
295226
}
296227

@@ -399,12 +330,13 @@ export class CdkFramework implements IFramework {
399330
400331
let rootStack = this.stack;
401332
while (rootStack.nestedStackParent) {
402-
rootStack = rootStack.nestedStackParent;
333+
rootStack = rootStack.nestedStackParent;
403334
}
404335
const lambdaInfo = {
405336
//cdkPath: this.node.defaultChild?.node.path ?? this.node.path,
406-
stackCdkPath: this.stack.node.defaultChild?.node.path ?? this.stack.node.path,
407337
stackName: this.stack.stackName,
338+
stack: this.stack,
339+
rootStack: rootStack,
408340
rootStackName: rootStack.stackName,
409341
codePath: props.entry,
410342
code: props.code,
@@ -415,7 +347,6 @@ export class CdkFramework implements IFramework {
415347
416348
// console.log("CDK INFRA: ", {
417349
// stackName: lambdaInfo.stackName,
418-
// stackCdkPath: lambdaInfo.stackCdkPath,
419350
// rootStackName: lambdaInfo.rootStackName,
420351
// codePath: lambdaInfo.codePath,
421352
// code: lambdaInfo.code,

src/frameworks/cdkFrameworkWorker.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ parentPort.on('message', async (data) => {
2525
handler: lambda.handler,
2626
stackName: lambda.stackName,
2727
codePath: lambda.codePath,
28-
stackCdkPath: lambda.stackCdkPath,
2928
rootStackName: lambda.rootStackName,
3029
code: {
3130
path: lambda.code?.path,

0 commit comments

Comments
 (0)