feat(core): weak cross environment references#37800
Conversation
Introduce a context key `@aws-cdk/core:crossStackReferenceStrength` that lets users choose between strong references (producer cannot be deleted while consumers exist) and weak references (producer can be deleted independently). Users set the context key in `cdk.json` to one of three values: - `"strong"` (default): ExportWriter/ExportReader via SSM — producer cannot be deleted while consumers exist. - `"weak"`: `Fn::GetStackOutput` — simpler, no extra infrastructure, but producer can be deleted independently. - `"both"`: Transitional — producer keeps writing to SSM *and* exposes an Output; consumer reads via `Fn::GetStackOutput`. This allows removing the ExportReader without breaking anything.
|
PRs without a linked issue will receive lower priority for review and merging. Please update the description to follow the PR template and include a line like |
|
|
||||||||||||||
|
|
||||||||||||||
| const stack = Stack.of(this); | ||
| const parameterName = `/${SSM_EXPORT_PATH_PREFIX}${exportName}`; | ||
|
|
||
| this._references.put(parameterName, stack.resolve(reference.toString())); |
There was a problem hiding this comment.
Make this logic shared with exportValue()?
|
|
||
| export const STRING_LIST_REFERENCE_DELIMITER = '||'; | ||
|
|
||
| type CrossStackReferenceStrength = 'strong' | 'weak' | 'both'; |
There was a problem hiding this comment.
Here's a trick so we can't accidentally make typoes:
const CROSS_STACK_REFERENCE_VALUES = ['strong', 'weak', 'both'] as const;
type CrossStackReferenceStrength = (typeof CROSS_STACK_REFERENCE_VALUES)[number];
function crossStackReferenceStrength(scope: IConstruct): CrossStackReferenceStrength {
// ...
if (CROSS_STACK_REFERENCE_VALUES.includes(value)) {
return value;
}
}| `Stack "${consumer.node.path}" cannot reference ${renderReference(reference)} in stack "${producer.node.path}". ` + | ||
| 'Cross stack references are only supported for stacks deployed to the same account or between nested stacks and their parent stack'); | ||
| } | ||
| const strength = crossStackReferenceStrength(consumer); |
There was a problem hiding this comment.
This is worth documenting in the feature flag documentation: if this feature flag is flipped inside the construct tree, it's the scope of the consumer that counts, not the producer.
| 'Strong cross-account references are not supported. Set the context key ' + | ||
| `"${cxapi.CROSS_STACK_REFERENCE_STRENGTH}" to "weak" or "both" to use Fn::GetStackOutput for cross-account references.`, |
There was a problem hiding this comment.
The mitigation seems to imply a difference in behavior that doens't actually exist. Also "not supported" is true but we can make it sound nicer 😉 .
How about something like:
Strong references requested, but cross-account references can only be weak. Acknowledge this warning or locally set the ${CROSS_STACK_REFERENCE_STRENGTH} flag to 'weak' to remove this message.
|
|
||
| if (strength === 'strong') { | ||
| Annotations.of(consumer).addWarningV2( | ||
| '@aws-cdk/core:crossAccountStrongRefsNotSupported', |
There was a problem hiding this comment.
| '@aws-cdk/core:crossAccountStrongRefsNotSupported', | |
| '@aws-cdk/core:crossAccountRefsAreAlwaysWeak', |
| 'Cross stack references are only supported for stacks deployed to the same environment or between nested stacks and their parent stack. ' + | ||
| 'Set crossRegionReferences=true to enable cross region references'); | ||
| // "weak" or "both" fallback — use Fn::GetStackOutput with cross-account role | ||
| if (consumer.synthesizer.cloudFormationExecutionRole == null) { |
There was a problem hiding this comment.
Not enjoying this limitation but I guess we can always remove it later.
|
|
||
| Migration path: set to \`"both"\` and deploy, then set to \`"weak"\` and deploy again.`, | ||
| introducedIn: { v2: 'V2NEXT' }, | ||
| recommendedValue: 'weak', |
There was a problem hiding this comment.
One more thing: I think we definitely want weak as the recommended value eventually, but do we want to recommend this right now? Especially because in-env references will be far and away the most common, and each of them will cause a warning with this config.
|
➡️ PR build request submitted to A maintainer must now check the pipeline and add the |
|
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Merge Queue Status
This pull request spent 44 minutes 11 seconds in the queue, including 43 minutes 53 seconds running CI. Required conditions to merge
|
|
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
|
Comments on closed issues and PRs are hard for our team to see. |
Reason for this change
With the introduction of the CloudFormation intrinsic
Fn::GetStackOutput, we can provide users with the ability to create weak references between resources in different regions. The function also allows cross-account references, which are currently not supported by the CDK.Description of changes
Introduce a context key
@aws-cdk/core:crossStackReferenceStrengththat lets users choose between strong references (producer cannot be deleted while consumers exist) and weak references (producer can be deleted independently). Users set the context key incdk.jsonto one of three values:"strong"(default): ExportWriter/ExportReader via SSM — producer cannot be deleted while consumers exist."weak":Fn::GetStackOutput— simpler, no extra infrastructure, but producer can be deleted independently."both": Transitional — producer keeps writing to SSM and exposes an Output; consumer reads viaFn::GetStackOutput. This allows removing the ExportReader without breaking anything.Describe any new or updated permissions being added
For cross-account references, the producer stack gets an AWS::IAM::Role with a trust policy allowing the consumer's CloudFormation execution role to sts:AssumeRole, and an AWS::IAM::Policy granting cloudformation:DescribeStacks on the producer stack ARN.
Description of how you validated changes
Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license