-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhance CDK support with nested stack handling #295
Conversation
d48ac5e
to
2caf7b8
Compare
- Introduced `StackAddress` type to uniquely identify resources across nested stacks. - Updated `CloudFormationParameterWithId` to use `stackAddress` instead of `id`. - Added `NestedStackTemplate` interface and `isNestedStackTemplate` function for better nested stack management. - Modified various functions and interfaces to accommodate stack paths and addresses, improving resource mapping and retrieval. - Created `StackMap` class for efficient management of resources across stacks. - Updated tests to reflect changes in resource identification and nested stack handling. This update improves the overall structure and usability of arbitrary stacks in the cloud assembly.
2caf7b8
to
674ff01
Compare
This change is part of the following stack: Change managed by git-spice. |
@@ -367,10 +448,39 @@ export class StackConverter extends ArtifactConverter implements intrinsics.Intr | |||
/** @internal */ | |||
asOutputValue<T>(v: T): T { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cutting a follow up ticket for handling cases where multiple nested stacks have a resource with the same logical ID. The users could inform the converter about the right stack by passing it in as an optional argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awesome! My only minor comment is around adding some unit tests to the intrinsics and graph tests.
|
||
// resources of the nested stack should be mapped | ||
// this tests that properties are correctly passed to the nested stack | ||
const nestedBucket = converter.resources.get({ stackPath: `${manifest.id}/nesty`, id: 'bucket43879C71'})?.resource as native.s3.Bucket; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like NestedStack resources still have the cdk random suffix (no way around it). More reason not to use nested stacks!
@corymhall I think this is ready for another look |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀
* @param logicalId - The logicalId of the nested stack | ||
* @returns The path to the nested stack wrapper node in the construct tree | ||
*/ | ||
public static getNestedStackPath(nestedStackResourcePath: string, logicalId: string): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: type aliaseses instead of string
for these things can be helpful to clarify at type system level what's what.
readonly Metadata?: { [key: string]: any }; | ||
} | ||
|
||
export interface CloudFormationOutput { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this represent and what can we expect under Value: any?
@@ -95,9 +103,11 @@ export class AppConverter { | |||
* StackConverter converts all of the resources in a CDK stack to Pulumi resources | |||
*/ | |||
export class StackConverter extends ArtifactConverter implements intrinsics.IntrinsicContext { | |||
readonly parameters = new Map<CloudFormationParameterLogicalId, any>(); | |||
readonly resources = new Map<string, Mapping<pulumi.Resource>>(); | |||
readonly parameters = new StackMap<any>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat.
@@ -367,10 +448,44 @@ export class StackConverter extends ArtifactConverter implements intrinsics.Intr | |||
/** @internal */ | |||
asOutputValue<T>(v: T): T { | |||
const value = this.cdkStack.resolve(v); | |||
return this.processIntrinsics(value) as T; | |||
try { | |||
return this.processIntrinsics(value, this.stack.constructTree.path) as T; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this eventually become a single-pass processIntrinsics?
That is can processIntrinsics
absorb this.graph.nestedStackNodes parameter and just not fail but to the right thing.
@@ -85,22 +96,22 @@ export interface IntrinsicContext { | |||
* | |||
* See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html | |||
*/ | |||
findCondition(conditionName: string): Expression | undefined; | |||
findCondition(stackAddress: StackAddress): Expression | undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
* StackAddress uniquely identifies a resource in a cloud assembly | ||
* across several (nested) stacks. | ||
*/ | ||
export type StackAddress = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps ResourceAddress? StackAddress makes it sound like it identifies a Stack. Doc comments on props are also nice, with examples.
Very nice. Sorry for late review with some questions. Nothing blocking. |
This PR has been shipped in release v1.4.0. |
This change adds support for Nested Stacks to
pulumi-cdk
.In CDK, a nested stack is a CDK stack that you create inside another stack, known as the parent stack. Users create nested stacks using the NestedStack construct.
By using nested stacks, users can organize resources across multiple stacks. Nested stacks also offer a way around the AWS CloudFormation 500-resource limit for stacks. A nested stack counts as only one resource in the stack that contains it. However, it can contain up to 500 resources, including additional nested stacks.
While Pulumi doesn't have those limitations, many existing CDK constructs use nested stacks to get around the CloudFormation limitations. The EKS cluster construct is one of the most prominent ones that require nested stacks.
In detail, this change:
AssemblyManifestReader
to support reading nested stacks.StackAddress
for elements in the CloudFormation templates. It combines the stack path (tree path of the stack) and the stack-local logical ID in order to form an assembly wide unique address. This is necessary in order to represent a hierarchy of stacks in the same pulumi programNestedStackConstruct
component. It is used to namespace the resources of a NestedStack in order to not run into any issues with duplicate logical IDs. It achieves this by including the stack path in the pulumi resource type. The types of parent resources are included in URNs, meaning all resources parented under the nested stack have their own unique namespace.Integration tests and an example are part of #298 which is part of this PR stack.
Review Advice
I'd recommend first reviewing the changes to the code reading the cloud assembly (
src/assembly/manifest.ts
), then the GraphBuilder (src/graph.ts
) and lastly the app converter and intrinsics (src/converters/app-converter.ts
&src/converters/intrinsics.ts
). The other changes are in support for thoseFixes #80