Skip to content

Conversation

pinzon
Copy link
Member

@pinzon pinzon commented Jul 24, 2025

Motivation

This PR enables the functionality of Exports/Imports in CFn v2

Changes

  • Implement ListExports operation
  • ChangeSetModelExecutor stores output values that also define an Export name.
  • ChangeSetPreproc is able to resolve imports

Testing

  • Unskipped tests

Todo

  • 2 exports cannot use the same name in the same template
  • An export cannot be registered if the name already exists in the exports store.

@pinzon pinzon marked this pull request as ready for review July 24, 2025 21:56
@pinzon pinzon added the semver: minor Non-breaking changes which can be included in minor releases, but not in patch releases label Jul 24, 2025
Copy link

github-actions bot commented Jul 24, 2025

Test Results - Preflight, Unit

22 063 tests  ±0   20 329 ✅ ±0   6m 14s ⏱️ -11s
     1 suites ±0    1 734 💤 ±0 
     1 files   ±0        0 ❌ ±0 

Results for commit d33106a. ± Comparison against base commit 6e03b92.

♻️ This comment has been updated with latest results.

Copy link

github-actions bot commented Jul 24, 2025

LocalStack Community integration with Pro

  2 files    2 suites   22m 29s ⏱️
541 tests 329 ✅ 212 💤 0 ❌
543 runs  329 ✅ 214 💤 0 ❌

Results for commit d33106a.

♻️ This comment has been updated with latest results.

Copy link

github-actions bot commented Jul 24, 2025

Test Results (amd64) - Acceptance

7 tests  ±0   5 ✅ ±0   3m 6s ⏱️ -12s
1 suites ±0   2 💤 ±0 
1 files   ±0   0 ❌ ±0 

Results for commit d33106a. ± Comparison against base commit 6e03b92.

♻️ This comment has been updated with latest results.

Copy link

github-actions bot commented Jul 24, 2025

Test Results (amd64) - Integration, Bootstrap

  5 files    5 suites   33m 18s ⏱️
565 tests 354 ✅ 211 💤 0 ❌
571 runs  354 ✅ 217 💤 0 ❌

Results for commit d33106a.

♻️ This comment has been updated with latest results.

Copy link
Contributor

@simonrw simonrw left a comment

Choose a reason for hiding this comment

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

Thanks for adding these changes. The blocker is filtering the stacks by status. Perhaps we can add a test for this case as well, i.e. create two stacks with exports, delete one stack then call list_exports?

@pinzon pinzon force-pushed the cp/cfn/v2/import-exports branch from 42c4e41 to 2e34cb0 Compare July 25, 2025 15:52
@pinzon
Copy link
Member Author

pinzon commented Jul 25, 2025

Thanks for the comments. after implementing the changes the feature code feels much better 👍

@pinzon pinzon requested a review from simonrw July 25, 2025 15:53
@pinzon pinzon added this to the Playground milestone Jul 28, 2025
@simonrw simonrw modified the milestones: Playground, 4.8 Jul 29, 2025
Copy link
Contributor

@simonrw simonrw left a comment

Choose a reason for hiding this comment

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

Thanks for taking another stab at this, I think we have to move the behaviour of the ImportValue implementation to the executor, and I really think we should make the exports in the store consistent with other fields there (add a _v2 dictionary).

Comment on lines 907 to 929
def visit_node_intrinsic_function_fn_import_value(
self, node_intrinsic_function: NodeIntrinsicFunction
) -> PreprocEntityDelta:
def _compute_fn_import_value(string) -> str:
if not isinstance(string, str):
raise RuntimeError(f"Invalid parameter for import: '{string}'")

exports = exports_map(
account_id=self._change_set.account_id, region_name=self._change_set.region_name
)
if not exports.get(string):
raise RuntimeError(f"Value not found for import: '{string}'")

return exports.get(string)["Value"]

arguments_delta = self.visit(node_intrinsic_function.arguments)
delta = self._cached_apply(
scope=node_intrinsic_function.scope,
arguments_delta=arguments_delta,
resolver=_compute_fn_import_value,
)
return delta

Copy link
Contributor

@simonrw simonrw Jul 29, 2025

Choose a reason for hiding this comment

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

issue: I think this lookup happens only in the executor. For example when describing a change set, the import is not retrieved.

I can reproduce this by

  • creating a change set including an ImportValue, e.g.
Resources:
  MyFoo:
    Type: AWS::SSM::Parameter
    Properties:
      Type: String
      Value: !ImportValue MyGlobalExportValue
  • describing the change set with aws describe-change-set ... --include-property-values
    On AWS the Value field is KNOWN_AFTER_APPLY, but on LocalStack this code crashes because the export is fetched (but doesn't exist).

Can we add a test to cover this behaviour and implement the correct behaviour in the executor only.

Copy link
Member Author

Choose a reason for hiding this comment

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

I added a test and it passes with the functionality in the Preproc. maybe I'm not understanding correctly the issue.

@pinzon pinzon force-pushed the cp/cfn/v2/import-exports branch from 2e34cb0 to d7de3b3 Compare July 29, 2025 19:01
@pinzon pinzon requested a review from simonrw July 29, 2025 21:01
@localstack-bot
Copy link
Contributor

Currently, only patch changes are allowed on main. Your PR labels (semver: minor) indicate that it cannot be merged into the main at this time.

@coveralls
Copy link

coveralls commented Jul 31, 2025

Coverage Status

coverage: 66.357% (-20.5%) from 86.885%
when pulling 5234e4e on cp/cfn/v2/import-exports
into f5d850d on main.

@pinzon pinzon force-pushed the cp/cfn/v2/import-exports branch from b0acf1b to 3cce2cb Compare August 1, 2025 15:43
Copy link
Contributor

@simonrw simonrw left a comment

Choose a reason for hiding this comment

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

I have reviewed the tests again and think we are missing a scenario that I encountered that this test does not cover. It also explains my reasoning in this message: what if the export does not exist?

I had deployed a stack and the export did not exist. The change set was still created but there were the following differences:

  • in the Changes array the after context was a stringified JSON object including {{changeSet:KNOWN_AFTER_APPLY}} for the value
    "Changes": [
        {
            "Type": "Resource",
            "ResourceChange": {
                "Action": "Add",
                "LogicalResourceId": "MyFoo",
                "ResourceType": "AWS::SSM::Parameter",
                "Scope": [],
                "Details": [],
                "AfterContext": "{\"Properties\":{\"Value\":\"{{changeSet:KNOWN_AFTER_APPLY}}\",\"Type\":\"String\"}}"
            }
        }
    ],
  • The StatusReason contained the following message: [WARN] --include-property-values option can return incomplete ChangeSet data because: ChangeSet creation failed for resource [MyFoo] because: No export named MyGlobalExportValue

Actually there is another test case that would be interesting:

  1. create change set that imports from an export that does not exist
  2. deploy the stack with the export
  3. execute the first change set

I don't think we need 100% parity here, but it's certainly an interesting case.

So in summary:

  • it's ok to create and describe a change set that imports values that have not been exported
  • it's not ok to execute a change set that references exports that don't exist
  • it's possible imports are looked up both during the modelling phase and execution phase, depending on the results of adding my second test suggestion

@pinzon pinzon requested a review from simonrw August 4, 2025 23:10
@simonrw
Copy link
Contributor

simonrw commented Aug 5, 2025

@pinzon I have added a commit that includes both scenarios I was thinking of. Now we have coverage of:

  • create stack with export, create change set using export, describe change set, execute change set, describe stack
  • create change set using (missing) export, describe change set, execute change set (which fails), describe failed stack
  • create change set using (missing) export, describe change set, create stack with export, execute change set, describe (successful) stack using export
    I had to add some minor additional skips that I think are ok for now, and merged main into this branch to pick up add testing for Fn::Transform in CFn v2 #12689 that I merged this morning. If this PR is green I will approve and merge, thanks!

@simonrw simonrw merged commit b411538 into main Aug 5, 2025
39 checks passed
@simonrw simonrw deleted the cp/cfn/v2/import-exports branch August 5, 2025 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver: minor Non-breaking changes which can be included in minor releases, but not in patch releases
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants