Skip to content

feat(core): weak cross environment references#37800

Merged
mergify[bot] merged 6 commits into
mainfrom
otaviom/gso-weak-strong-refs
May 8, 2026
Merged

feat(core): weak cross environment references#37800
mergify[bot] merged 6 commits into
mainfrom
otaviom/gso-weak-strong-refs

Conversation

@otaviomacedo
Copy link
Copy Markdown
Contributor

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: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.

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

  • New unit and integration tests
  • For the cross-account scenario, and the migration path (strong -> both -> weak), the change was tested manually.

Checklist


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

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.
@otaviomacedo otaviomacedo requested a review from a team as a code owner May 8, 2026 09:21
@github-actions github-actions Bot added the p2 label May 8, 2026
@mergify mergify Bot added the contribution/core This is a PR that came from AWS. label May 8, 2026
@mergify mergify Bot temporarily deployed to automation May 8, 2026 09:22 Inactive
@mergify mergify Bot temporarily deployed to automation May 8, 2026 09:22 Inactive
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 8, 2026

⚠️ This pull request description does not follow the correct template structure.

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 Closes #123 in the Issue section. If no existing issue matches your change, create one first.

@mergify mergify Bot temporarily deployed to test-pipeline May 8, 2026 09:23 Inactive
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 8, 2026

⚠️ Experimental Feature: This security report is currently in experimental phase. Results may include false positives and the rules are being actively refined.
This security report is NOT a review blocker. Please try merge from main to avoid findings unrelated to the PR.
To suppress a specific rule, see Suppressing Rules.


TestsPassed ✅SkippedFailed
Security Guardian Results144 ran144 passed
TestResult
No test annotations available

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 8, 2026

⚠️ Experimental Feature: This security report is currently in experimental phase. Results may include false positives and the rules are being actively refined.
This security report is NOT a review blocker. Please try merge from main to avoid findings unrelated to the PR.
To suppress a specific rule, see Suppressing Rules.


TestsPassed ✅SkippedFailed
Security Guardian Results with resolved templates144 ran144 passed
TestResult
No test annotations available

@mergify mergify Bot temporarily deployed to automation May 8, 2026 09:25 Inactive
@aws-cdk-automation aws-cdk-automation added the pr/needs-further-review PR requires additional review from our team specialists due to the scope or complexity of changes. label May 8, 2026
Comment on lines +147 to +150
const stack = Stack.of(this);
const parameterName = `/${SSM_EXPORT_PATH_PREFIX}${exportName}`;

this._references.put(parameterName, stack.resolve(reference.toString()));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this logic shared with exportValue()?


export const STRING_LIST_REFERENCE_DELIMITER = '||';

type CrossStackReferenceStrength = 'strong' | 'weak' | 'both';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +98 to +99
'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.`,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'@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) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@aws-cdk-automation
Copy link
Copy Markdown
Collaborator

➡️ PR build request submitted to test-main-pipeline ⬅️

A maintainer must now check the pipeline and add the pr-linter/cli-integ-tested label once the pipeline succeeds.

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 8, 2026

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).

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 8, 2026

Merge Queue Status

  • Entered queue2026-05-08 12:13 UTC · Rule: default-squash
  • Checks passed · in-place
  • Merged2026-05-08 12:57 UTC · at 90cadd08fa2af6d677fe4fc7a7c9ac855093f90e · squash

This pull request spent 44 minutes 11 seconds in the queue, including 43 minutes 53 seconds running CI.

Required conditions to merge

@mergify mergify Bot temporarily deployed to automation May 8, 2026 12:13 Inactive
@mergify mergify Bot temporarily deployed to automation May 8, 2026 12:13 Inactive
@mergify mergify Bot requested a deployment to test-pipeline May 8, 2026 12:14 Waiting
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 8, 2026

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).

@mergify mergify Bot merged commit fe23dce into main May 8, 2026
22 of 24 checks passed
@mergify mergify Bot deleted the otaviom/gso-weak-strong-refs branch May 8, 2026 12:57
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 8, 2026

Comments on closed issues and PRs are hard for our team to see.
If you need help, please open a new issue that references this one.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators May 8, 2026
@aws-cdk-automation aws-cdk-automation removed the pr/needs-maintainer-review This PR needs a review from a Core Team Member label May 8, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

contribution/core This is a PR that came from AWS. p2 pr/needs-further-review PR requires additional review from our team specialists due to the scope or complexity of changes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants