Skip to content
This repository was archived by the owner on Mar 23, 2026. It is now read-only.

CFn: implement DeletionPolicy and UpdateReplacePolicy#13535

Merged
simonrw merged 6 commits intomainfrom
cfn/handle-policies
Feb 5, 2026
Merged

CFn: implement DeletionPolicy and UpdateReplacePolicy#13535
simonrw merged 6 commits intomainfrom
cfn/handle-policies

Conversation

@simonrw
Copy link
Copy Markdown
Contributor

@simonrw simonrw commented Dec 17, 2025

Motivation

A user has reported that setting policies is not only not implemented by our engigne, but actually incorrectly raises an error.

Changes

  • Don't raise error when modeling the policy fields
  • Skip deletion if UpdateReplacePolicy=Retain and a resource is updated
  • Skip deletion if DeletionPolicy=Retain and a resource is deleted

Related to

Resolves ENG-200

@simonrw simonrw added semver: patch Non-breaking changes which can be included in patch releases docs: skip Pull request does not require documentation changes notes: skip Pull request does not have to be mentioned in the release notes labels Dec 17, 2025
@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 17, 2025

Test Results - Preflight, Unit

23 114 tests  ±0   21 255 ✅ ±0   6m 25s ⏱️ +7s
     1 suites ±0    1 859 💤 ±0 
     1 files   ±0        0 ❌ ±0 

Results for commit 988559e. ± Comparison against base commit cf9a6fc.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 17, 2025

LocalStack Community integration with Pro

    2 files  ±0      2 suites  ±0   1h 58m 6s ⏱️ - 1m 6s
5 196 tests +4  4 845 ✅ +4  351 💤 ±0  0 ❌ ±0 
5 198 runs  +4  4 845 ✅ +4  353 💤 ±0  0 ❌ ±0 

Results for commit 988559e. ± Comparison against base commit cf9a6fc.

♻️ This comment has been updated with latest results.

@simonrw simonrw force-pushed the cfn/handle-policies branch from 2e205bc to 7c41c83 Compare December 17, 2025 10:21
@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 17, 2025

Test Results (amd64) - Acceptance

7 tests  ±0   5 ✅ ±0   3m 4s ⏱️ +3s
1 suites ±0   2 💤 ±0 
1 files   ±0   0 ❌ ±0 

Results for commit 988559e. ± Comparison against base commit cf9a6fc.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 17, 2025

Test Results - Alternative Providers

590 tests   323 ✅  17m 54s ⏱️
  1 suites  267 💤
  1 files      0 ❌

Results for commit 988559e.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 17, 2025

Test Results (amd64) - Integration, Bootstrap

    5 files      5 suites   2h 39m 46s ⏱️
5 617 tests 5 096 ✅ 521 💤 0 ❌
5 623 runs  5 096 ✅ 527 💤 0 ❌

Results for commit 988559e.

♻️ This comment has been updated with latest results.

@simonrw simonrw force-pushed the cfn/handle-policies branch from 7c41c83 to f53ac96 Compare December 18, 2025 20:26
@simonrw simonrw marked this pull request as ready for review December 18, 2025 22:20
Copy link
Copy Markdown
Member

@pinzon pinzon left a comment

Choose a reason for hiding this comment

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

Great PR.
The only blocking issues are the lack of cleanup of the retained parameters and the commented out code, feel free to ignore my suggestion on the snapshot skip if you deem it unimportant.

Comment on lines +36 to +37
# TODO: provider parity issue with error message
# snapshot.match("error", exc_info.value)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can't we add a snapshot skip so we can keep the snapshot?


stack.destroy()

value = aws_client.ssm.get_parameter(Name=parameter_name)["Parameter"]["Value"]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should add a cleanup for the parameter

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Great catch, thank you!

Comment on lines +119 to +120
with pytest.raises(ClientError):
aws_client.ssm.get_parameter(Name=parameter_name)["Parameter"]["Value"]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's also add the snapshot here

)

# check the previous parameter was not deleted
aws_client.ssm.get_parameter(Name=parameter_name)["Parameter"]["Value"]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here we should also add a cleanup for the retained parameter

Copy link
Copy Markdown
Member

@pinzon pinzon Dec 22, 2025

Choose a reason for hiding this comment

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

We should consider splitting this file in two files: test_deletion_policy.py and test_update_replace_policy.py.
So in the future we can cleanly expand to test the other policy configurations.

@simonrw simonrw modified the milestones: Playground, 4.13 Jan 23, 2026
@simonrw simonrw force-pushed the cfn/handle-policies branch from f53ac96 to e78199a Compare January 23, 2026 12:05
@simonrw simonrw requested a review from pinzon January 23, 2026 12:05
@simonrw
Copy link
Copy Markdown
Contributor Author

simonrw commented Jan 23, 2026

Thanks for the review @pinzon I've hopefully addressed your (very valid!) comments. Please take another look

Copy link
Copy Markdown
Member

@pinzon pinzon left a comment

Choose a reason for hiding this comment

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

Pretty good PR. The blocking issues are the comments in the tests and the templates.


@markers.aws.validated
@markers.snapshot.skip_snapshot_verify(
paths=[
Copy link
Copy Markdown
Member

@pinzon pinzon Jan 23, 2026

Choose a reason for hiding this comment

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

Change: we should transform the PhysicalResourceId

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Except this is a parameter that's not output by LocalStack. It's not just that the value is different.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Still the snapshot won't match even if we run the test against AWS again.


@markers.snapshot.skip_snapshot_verify(
paths=[
# our message is different. The AWS message does not seem to include the parameter
Copy link
Copy Markdown
Member

@pinzon pinzon Jan 23, 2026

Choose a reason for hiding this comment

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

Nit: I don't think this comment is necessary. Adding 'message' to the skips already tells us there is something to fix.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's more about the reason why this is skipped, which is that we output a value extra to AWS.


@markers.aws.validated
@markers.snapshot.skip_snapshot_verify(
paths=[
Copy link
Copy Markdown
Member

@pinzon pinzon Jan 23, 2026

Choose a reason for hiding this comment

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

Change: Same here. we should use a Regex transform even if the stack events are not in parity.

Resources:
MyParameter:
Type: AWS::SSM::Parameter
DeletionPolicy: !If [IsPermanentEnvironment, Retain, Delete]
Copy link
Copy Markdown
Member

@pinzon pinzon Jan 23, 2026

Choose a reason for hiding this comment

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

Change: It hides a bit what we're actually testing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

What is the alternative? AWS::NoValue? I don't think that's much clearer. Or do you mean creating more templates?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

My idea here was to have a different test for deletion policy behavior and support for intrinsic functions. But @nik-localstack recently closed his pr about the later. So let's ignore my comment here.

Comment on lines +1291 to +1303
deletion_policy_before = Nothing
deletion_policy_after = Nothing
if not is_nothing(node_resource.deletion_policy):
deletion_policy_delta = self.visit(node_resource.deletion_policy)
deletion_policy_before = deletion_policy_delta.before
deletion_policy_after = deletion_policy_delta.after

update_replace_policy_before = Nothing
update_replace_policy_after = Nothing
if not is_nothing(node_resource.update_replace_policy):
update_replace_policy_delta = self.visit(node_resource.update_replace_policy)
update_replace_policy_before = update_replace_policy_delta.before
update_replace_policy_after = update_replace_policy_delta.after
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: IMO, extracting the delta values here is unnecessary, you could just get the deltas here, and use the .before and .after when needed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately if the node_resource.*_policy is nothing then we get the 'NothingType' object has no attribute 'after' error.

# Motivation

A user has reported that setting policies is not only not implemented by our engigne, but actually incorrectly raises an error.

# Changes

* Don't raise error when modeling the policy fields
* Skip deletion if `UpdateReplacePolicy=Retain` and a resource is updated
* Skip deletion if `DeletionPolicy=Retain` and a resource is deleted


# Related to

Resolves ENG-200
@simonrw simonrw force-pushed the cfn/handle-policies branch from fd6db3a to 988559e Compare February 5, 2026 22:21
@simonrw simonrw merged commit d32e212 into main Feb 5, 2026
42 checks passed
@simonrw simonrw deleted the cfn/handle-policies branch February 5, 2026 23:58
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

docs: skip Pull request does not require documentation changes notes: skip Pull request does not have to be mentioned in the release notes semver: patch Non-breaking changes which can be included in patch releases

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants