From d8316dc897cd240ea3e87dde040e5dbbe2904187 Mon Sep 17 00:00:00 2001 From: Cristopher Pinzon Date: Mon, 16 Jun 2025 13:38:54 -0500 Subject: [PATCH 1/4] re-implement --- .../engine/v2/change_set_model_executor.py | 113 +++++++++++------- .../services/cloudformation/v2/entities.py | 41 ++++++- .../services/cloudformation/v2/provider.py | 27 ++++- 3 files changed, 138 insertions(+), 43 deletions(-) diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py index 96c936a3cf037..8c93552cbe7f3 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py @@ -36,6 +36,8 @@ LOG = logging.getLogger(__name__) +EventOperationFromAction = {"Add": "CREATE", "Modify": "UPDATE", "Remove": "DELETE"} + @dataclass class ChangeSetModelExecutorResult: @@ -86,6 +88,47 @@ def visit_node_parameter(self, node_parameter: NodeParameter) -> PreprocEntityDe self.resolved_parameters[node_parameter.name] = delta.after return delta + def _get_physical_id(self, logical_resource_id, strict: bool = True) -> str: + physical_resource_id = None + try: + physical_resource_id = self._after_resource_physical_id(logical_resource_id) + except RuntimeError: + # The physical id is missing or is set to None, which is invalid. + pass + if physical_resource_id is None: + # The physical resource id is None after an update that didn't rewrite the resource, the previous + # resource id is therefore the current physical id of this resource. + + try: + physical_resource_id = self._before_resource_physical_id(logical_resource_id) + except RuntimeError as e: + if strict: + raise e + return physical_resource_id + + def _add_resource_event( + self, + action: ChangeAction, + logical_resource_id, + event_status: OperationStatus, + special_action: str = None, + reason: str = None, + ): + status_from_action = special_action or EventOperationFromAction[action.value] + if event_status.value == OperationStatus.SUCCESS.value: + status = StackStatus(f"{status_from_action}_COMPLETE") + else: + status = StackStatus(f"{status_from_action}_{event_status.name}") + self._change_set.stack.add_resource_event( + logical_resource_id, + self._get_physical_id(logical_resource_id, False), + status=status, + status_reason=reason, + ) + + if event_status.value == OperationStatus.FAILED.value: + self._change_set.stack.set_stack_status(StackStatus(status)) + def _after_deployed_property_value_of( self, resource_logical_id: str, property_name: str ) -> str: @@ -173,20 +216,25 @@ def _execute_resource_change( # XXX hacky, stick the previous resources' properties into the payload before_properties = self._merge_before_properties(name, before) - self._execute_resource_action( + self._add_resource_event(ChangeAction.Modify, name, OperationStatus.IN_PROGRESS) + event = self._execute_resource_action( action=ChangeAction.Modify, logical_resource_id=name, resource_type=before.resource_type, before_properties=before_properties, after_properties=after.properties, ) + self._add_resource_event( + ChangeAction.Modify, name, event.status, reason=event.message + ) # Case: type migration. # TODO: Add test to assert that on type change the resources are replaced. else: # XXX hacky, stick the previous resources' properties into the payload before_properties = self._merge_before_properties(name, before) # Register a Removed for the previous type. - self._execute_resource_action( + + event = self._execute_resource_action( action=ChangeAction.Remove, logical_resource_id=name, resource_type=before.resource_type, @@ -194,35 +242,44 @@ def _execute_resource_change( after_properties=None, ) # Register a Create for the next type. - self._execute_resource_action( + self._add_resource_event( + ChangeAction.Modify, name, event.status, reason=event.message + ) + event = self._execute_resource_action( action=ChangeAction.Add, logical_resource_id=name, resource_type=after.resource_type, before_properties=None, after_properties=after.properties, ) + self._add_resource_event( + ChangeAction.Modify, name, event.status, reason=event.message + ) elif not is_nothing(before): # Case: removal # XXX hacky, stick the previous resources' properties into the payload # XXX hacky, stick the previous resources' properties into the payload before_properties = self._merge_before_properties(name, before) - - self._execute_resource_action( + self._add_resource_event(ChangeAction.Remove, name, OperationStatus.IN_PROGRESS) + event = self._execute_resource_action( action=ChangeAction.Remove, logical_resource_id=name, resource_type=before.resource_type, before_properties=before_properties, after_properties=None, ) + self._add_resource_event(ChangeAction.Remove, name, event.status, reason=event.message) elif not is_nothing(after): # Case: addition - self._execute_resource_action( + self._add_resource_event(ChangeAction.Add, name, OperationStatus.IN_PROGRESS) + event = self._execute_resource_action( action=ChangeAction.Add, logical_resource_id=name, resource_type=after.resource_type, before_properties=None, after_properties=after.properties, ) + self._add_resource_event(ChangeAction.Add, name, event.status, reason=event.message) def _merge_before_properties( self, name: str, preproc_resource: PreprocResource @@ -242,7 +299,7 @@ def _execute_resource_action( resource_type: str, before_properties: Optional[PreprocProperties], after_properties: Optional[PreprocProperties], - ) -> None: + ) -> ProgressEvent: LOG.debug("Executing resource action: %s for resource '%s'", action, logical_resource_id) resource_provider_executor = ResourceProviderExecutor( stack_name=self._change_set.stack.stack_name, stack_id=self._change_set.stack.stack_id @@ -272,16 +329,6 @@ def _execute_resource_action( exc_info=LOG.isEnabledFor(logging.DEBUG), ) stack = self._change_set.stack - match stack.status: - case StackStatus.CREATE_IN_PROGRESS: - stack.set_stack_status(StackStatus.CREATE_FAILED, reason=reason) - case StackStatus.UPDATE_IN_PROGRESS: - stack.set_stack_status(StackStatus.UPDATE_FAILED, reason=reason) - case StackStatus.DELETE_IN_PROGRESS: - stack.set_stack_status(StackStatus.DELETE_FAILED, reason=reason) - case _: - raise NotImplementedError(f"Unexpected stack status: {stack.status}") - # update resource status stack.set_resource_status( logical_resource_id=logical_resource_id, # TODO, @@ -292,7 +339,11 @@ def _execute_resource_action( else ResourceStatus.UPDATE_FAILED, resource_status_reason=reason, ) - return + event = ProgressEvent( + OperationStatus.FAILED, + resource_model={}, + message=f"Resource provider operation failed: {reason}", + ) self.resources.setdefault(logical_resource_id, {"Properties": {}}) match event.status: @@ -313,19 +364,8 @@ def _execute_resource_action( self.resources[logical_resource_id]["LogicalResourceId"] = logical_resource_id self.resources[logical_resource_id]["Type"] = resource_type - # TODO: review why the physical id is returned as None during updates - # TODO: abstract this in member function of resource classes instead - physical_resource_id = None - try: - physical_resource_id = self._after_resource_physical_id(logical_resource_id) - except RuntimeError: - # The physical id is missing or is set to None, which is invalid. - pass - if physical_resource_id is None: - # The physical resource id is None after an update that didn't rewrite the resource, the previous - # resource id is therefore the current physical id of this resource. - physical_resource_id = self._before_resource_physical_id(logical_resource_id) - self.resources[logical_resource_id]["PhysicalResourceId"] = physical_resource_id + physical_resource_id = self._get_physical_id(logical_resource_id) + self.resources[logical_resource_id]["PhysicalResourceId"] = physical_resource_id self._change_set.stack.set_resource_status( logical_resource_id=logical_resource_id, @@ -343,16 +383,6 @@ def _execute_resource_action( reason, ) # TODO: duplication - stack = self._change_set.stack - match stack.status: - case StackStatus.CREATE_IN_PROGRESS: - stack.set_stack_status(StackStatus.CREATE_FAILED, reason=reason) - case StackStatus.UPDATE_IN_PROGRESS: - stack.set_stack_status(StackStatus.UPDATE_FAILED, reason=reason) - case StackStatus.DELETE_IN_PROGRESS: - stack.set_stack_status(StackStatus.DELETE_FAILED, reason=reason) - case _: - raise NotImplementedError(f"Unhandled stack status: '{stack.status}'") stack.set_resource_status( logical_resource_id=logical_resource_id, # TODO @@ -365,6 +395,7 @@ def _execute_resource_action( ) case other: raise NotImplementedError(f"Event status '{other}' not handled") + return event def create_resource_provider_payload( self, diff --git a/localstack-core/localstack/services/cloudformation/v2/entities.py b/localstack-core/localstack/services/cloudformation/v2/entities.py index 111a29a6dfa37..0b442fc97e989 100644 --- a/localstack-core/localstack/services/cloudformation/v2/entities.py +++ b/localstack-core/localstack/services/cloudformation/v2/entities.py @@ -11,6 +11,7 @@ ResourceStatus, StackDriftInformation, StackDriftStatus, + StackEvent, StackResource, StackStatus, StackStatusReason, @@ -26,7 +27,8 @@ NodeTemplate, ) from localstack.utils.aws import arns -from localstack.utils.strings import short_uid +from localstack.utils.strings import long_uid, short_uid +from localstack.utils.time import timestamp_millis class ResolvedResource(TypedDict): @@ -43,6 +45,7 @@ class Stack: stack_id: str creation_time: datetime deletion_time: datetime | None + events = list[StackEvent] # state after deploy resolved_parameters: dict[str, str] @@ -89,12 +92,48 @@ def __init__( self.resolved_resources = {} self.resolved_outputs = {} self.resource_states = {} + self.events = [] def set_stack_status(self, status: StackStatus, reason: StackStatusReason | None = None): self.status = status if reason: self.status_reason = reason + self.add_resource_event( + self.stack_name, self.stack_id, status.value, status_reason=reason or "" + ) + + def add_resource_event( + self, + resource_id: str = None, + physical_res_id: str = None, + status: str = "", + status_reason: str = "", + ): + resource_id = resource_id or self.stack_name + physical_res_id = physical_res_id or self.stack_id + resource_type = ( + self.template.get("Resources", {}) + .get(resource_id, {}) + .get("Type", "AWS::CloudFormation::Stack") + ) + + event: StackEvent = { + "EventId": long_uid(), + "Timestamp": timestamp_millis(), + "StackId": self.stack_id, + "StackName": self.stack_name, + "LogicalResourceId": resource_id, + "PhysicalResourceId": physical_res_id, + "ResourceStatus": status, + "ResourceType": resource_type, + } + + if status_reason: + event["ResourceStatusReason"] = status_reason + + self.events.insert(0, event) + def set_resource_status( self, *, diff --git a/localstack-core/localstack/services/cloudformation/v2/provider.py b/localstack-core/localstack/services/cloudformation/v2/provider.py index 4b3d06877fe94..e5ab9a731a295 100644 --- a/localstack-core/localstack/services/cloudformation/v2/provider.py +++ b/localstack-core/localstack/services/cloudformation/v2/provider.py @@ -472,7 +472,32 @@ def describe_stack_events( next_token: NextToken = None, **kwargs, ) -> DescribeStackEventsOutput: - return DescribeStackEventsOutput(StackEvents=[]) + state = get_cloudformation_store(context.account_id, context.region) + if stack_name: + if is_stack_arn(stack_name): + stack = state.stacks_v2[stack_name] + else: + stack_candidates = [] + for stack in state.stacks_v2.values(): + if ( + stack.stack_name == stack_name + and stack.status != StackStatus.DELETE_COMPLETE + ): + stack_candidates.append(stack) + if len(stack_candidates) == 0: + raise ValidationError(f"No stack with name {stack_name} found") + elif len(stack_candidates) > 1: + raise RuntimeError("Programing error, duplicate stacks found") + else: + stack = stack_candidates[0] + else: + raise NotImplementedError + + if not stack: + # aws will silently ignore invalid stack names - we should do the same + return + + return DescribeStackEventsOutput(StackEvents=stack.events) @handler("DeleteStack") def delete_stack( From fe7bf7b7add2f8268c5157959316e381f3db92ad Mon Sep 17 00:00:00 2001 From: Cristopher Pinzon Date: Mon, 16 Jun 2025 14:04:05 -0500 Subject: [PATCH 2/4] test passes with skips and integrates marcos changes --- .../engine/v2/change_set_model_executor.py | 76 ++++++++++++------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py index 8c93552cbe7f3..39317e0395ab2 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py @@ -113,18 +113,27 @@ def _add_resource_event( event_status: OperationStatus, special_action: str = None, reason: str = None, + resource_type=None, ): status_from_action = special_action or EventOperationFromAction[action.value] if event_status.value == OperationStatus.SUCCESS.value: status = StackStatus(f"{status_from_action}_COMPLETE") else: status = StackStatus(f"{status_from_action}_{event_status.name}") + self._change_set.stack.add_resource_event( logical_resource_id, self._get_physical_id(logical_resource_id, False), status=status, status_reason=reason, ) + self._change_set.stack.set_resource_status( + logical_resource_id=logical_resource_id, + physical_resource_id=self._get_physical_id(logical_resource_id, False), + resource_type=resource_type, + status=ResourceStatus(status), + resource_status_reason=reason, + ) if event_status.value == OperationStatus.FAILED.value: self._change_set.stack.set_stack_status(StackStatus(status)) @@ -225,7 +234,11 @@ def _execute_resource_change( after_properties=after.properties, ) self._add_resource_event( - ChangeAction.Modify, name, event.status, reason=event.message + ChangeAction.Modify, + name, + event.status, + reason=event.message, + resource_type=before.resource_type, ) # Case: type migration. # TODO: Add test to assert that on type change the resources are replaced. @@ -243,7 +256,11 @@ def _execute_resource_change( ) # Register a Create for the next type. self._add_resource_event( - ChangeAction.Modify, name, event.status, reason=event.message + ChangeAction.Modify, + name, + event.status, + reason=event.message, + resource_type=before.resource_type, ) event = self._execute_resource_action( action=ChangeAction.Add, @@ -253,14 +270,23 @@ def _execute_resource_change( after_properties=after.properties, ) self._add_resource_event( - ChangeAction.Modify, name, event.status, reason=event.message + ChangeAction.Modify, + name, + event.status, + reason=event.message, + resource_type=before.resource_type, ) elif not is_nothing(before): # Case: removal # XXX hacky, stick the previous resources' properties into the payload # XXX hacky, stick the previous resources' properties into the payload before_properties = self._merge_before_properties(name, before) - self._add_resource_event(ChangeAction.Remove, name, OperationStatus.IN_PROGRESS) + self._add_resource_event( + ChangeAction.Remove, + name, + OperationStatus.IN_PROGRESS, + resource_type=before.resource_type, + ) event = self._execute_resource_action( action=ChangeAction.Remove, logical_resource_id=name, @@ -268,10 +294,21 @@ def _execute_resource_change( before_properties=before_properties, after_properties=None, ) - self._add_resource_event(ChangeAction.Remove, name, event.status, reason=event.message) + self._add_resource_event( + ChangeAction.Remove, + name, + event.status, + reason=event.message, + resource_type=before.resource_type, + ) elif not is_nothing(after): # Case: addition - self._add_resource_event(ChangeAction.Add, name, OperationStatus.IN_PROGRESS) + self._add_resource_event( + ChangeAction.Add, + name, + OperationStatus.IN_PROGRESS, + resource_type=after.resource_type, + ) event = self._execute_resource_action( action=ChangeAction.Add, logical_resource_id=name, @@ -279,7 +316,13 @@ def _execute_resource_change( before_properties=None, after_properties=after.properties, ) - self._add_resource_event(ChangeAction.Add, name, event.status, reason=event.message) + self._add_resource_event( + ChangeAction.Add, + name, + event.status, + reason=event.message, + resource_type=after.resource_type, + ) def _merge_before_properties( self, name: str, preproc_resource: PreprocResource @@ -367,15 +410,6 @@ def _execute_resource_action( physical_resource_id = self._get_physical_id(logical_resource_id) self.resources[logical_resource_id]["PhysicalResourceId"] = physical_resource_id - self._change_set.stack.set_resource_status( - logical_resource_id=logical_resource_id, - physical_resource_id=physical_resource_id, - resource_type=resource_type, - status=ResourceStatus.CREATE_COMPLETE - if action == ChangeAction.Add - else ResourceStatus.UPDATE_COMPLETE, - ) - case OperationStatus.FAILED: reason = event.message LOG.warning( @@ -383,16 +417,6 @@ def _execute_resource_action( reason, ) # TODO: duplication - stack.set_resource_status( - logical_resource_id=logical_resource_id, - # TODO - physical_resource_id="", - resource_type=resource_type, - status=ResourceStatus.CREATE_FAILED - if action == ChangeAction.Add - else ResourceStatus.UPDATE_FAILED, - resource_status_reason=reason, - ) case other: raise NotImplementedError(f"Event status '{other}' not handled") return event From 3bb8b7d6705bba4e7ea573b503e31e661a12ee5b Mon Sep 17 00:00:00 2001 From: Cristopher Pinzon Date: Mon, 16 Jun 2025 17:26:29 -0500 Subject: [PATCH 3/4] new per-resource-event function --- .../testing/pytest/cloudformation/fixtures.py | 29 +++- .../cloudformation/v2/test_change_sets.py | 5 +- .../v2/test_change_sets.snapshot.json | 150 ++++-------------- .../v2/test_change_sets.validation.json | 8 +- 4 files changed, 63 insertions(+), 129 deletions(-) diff --git a/localstack-core/localstack/testing/pytest/cloudformation/fixtures.py b/localstack-core/localstack/testing/pytest/cloudformation/fixtures.py index 99ce1673259a5..bfd7b95efa383 100644 --- a/localstack-core/localstack/testing/pytest/cloudformation/fixtures.py +++ b/localstack-core/localstack/testing/pytest/cloudformation/fixtures.py @@ -4,26 +4,43 @@ import pytest -from localstack.aws.api.cloudformation import DescribeChangeSetOutput, StackEvent +from localstack.aws.api.cloudformation import DescribeChangeSetOutput from localstack.aws.connect import ServiceLevelClientFactory from localstack.utils.functions import call_safe from localstack.utils.strings import short_uid -PerResourceStackEvents = dict[str, list[StackEvent]] + +def normalize_event(event): + """Simplify the event and skip DELETE_* events.""" + status = event.get("ResourceStatus") + + return { + "LogicalResourceId": event.get("LogicalResourceId"), + "ResourceType": event.get("ResourceType"), + "ResourceStatus": status, + "Timestamp": event.get("Timestamp"), + } @pytest.fixture def capture_per_resource_events( aws_client: ServiceLevelClientFactory, -) -> Callable[[str], PerResourceStackEvents]: - def capture(stack_name: str) -> PerResourceStackEvents: +) -> Callable[[str], dict]: + def capture(stack_name: str) -> dict: events = aws_client.cloudformation.describe_stack_events(StackName=stack_name)[ "StackEvents" ] - per_resource_events = defaultdict(list) + per_resource_events = defaultdict(dict) for event in events: if logical_resource_id := event.get("LogicalResourceId"): - per_resource_events[logical_resource_id].append(event) + resource_name = ( + logical_resource_id if logical_resource_id != stack_name else "Stack" + ) + normalized_event = normalize_event(event) + per_resource_events[resource_name][normalized_event["ResourceStatus"]] = ( + normalized_event + ) + return per_resource_events return capture diff --git a/tests/aws/services/cloudformation/v2/test_change_sets.py b/tests/aws/services/cloudformation/v2/test_change_sets.py index 2bc1ebff01866..d818f30e547aa 100644 --- a/tests/aws/services/cloudformation/v2/test_change_sets.py +++ b/tests/aws/services/cloudformation/v2/test_change_sets.py @@ -21,7 +21,6 @@ ) @markers.snapshot.skip_snapshot_verify( paths=[ - "per-resource-events..*", "delete-describe..*", # # Before/After Context @@ -34,6 +33,10 @@ "$..Replacement", "$..PolicyAction", "$..PhysicalResourceId", + # Unsupported events + "$..DELETE_COMPLETE", + "$..DELETE_IN_PROGRESS", + "$..UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", ] ) class TestCaptureUpdateProcess: diff --git a/tests/aws/services/cloudformation/v2/test_change_sets.snapshot.json b/tests/aws/services/cloudformation/v2/test_change_sets.snapshot.json index d799e38efd682..41bde15184ef2 100644 --- a/tests/aws/services/cloudformation/v2/test_change_sets.snapshot.json +++ b/tests/aws/services/cloudformation/v2/test_change_sets.snapshot.json @@ -95,7 +95,7 @@ } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_direct_update": { - "recorded-date": "24-04-2025, 17:00:59", + "recorded-date": "16-06-2025, 22:25:10", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -323,174 +323,82 @@ "Tags": [] }, "per-resource-events": { - "Foo": [ - { - "EventId": "Foo-8fa001c0-096c-4f9e-9aed-0c31f45ded09", + "Foo": { + "CREATE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceStatus": "DELETE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-57ec24a9-92bd-4f31-8d36-972323072283", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceStatus": "DELETE_IN_PROGRESS", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_COMPLETE-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-2", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-2", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", + "DELETE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Requested update requires the creation of a new physical resource; hence creating one.", + "ResourceStatus": "DELETE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_COMPLETE-date", + "DELETE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "DELETE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_IN_PROGRESS-date", + "UPDATE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_IN_PROGRESS-date", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "": [ - { - "EventId": "", + }, + "Stack": { + "CREATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "REVIEW_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ] + } }, "delete-describe": { "CreationTime": "datetime", diff --git a/tests/aws/services/cloudformation/v2/test_change_sets.validation.json b/tests/aws/services/cloudformation/v2/test_change_sets.validation.json index c54186e955aea..ca3dd6c689085 100644 --- a/tests/aws/services/cloudformation/v2/test_change_sets.validation.json +++ b/tests/aws/services/cloudformation/v2/test_change_sets.validation.json @@ -12,7 +12,13 @@ "last_validated_date": "2025-04-24T17:54:44+00:00" }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_direct_update": { - "last_validated_date": "2025-04-24T17:00:59+00:00" + "last_validated_date": "2025-06-16T22:25:10+00:00", + "durations_in_seconds": { + "setup": 0.24, + "call": 116.21, + "teardown": 0.14, + "total": 116.59 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_dynamic_update": { "last_validated_date": "2025-04-24T17:02:59+00:00" From e2b760a4622c3ba463d6931b3af64eea5ed57bca Mon Sep 17 00:00:00 2001 From: Cristopher Pinzon Date: Tue, 17 Jun 2025 11:01:10 -0500 Subject: [PATCH 4/4] updated snapshots --- .../v2/test_change_sets.snapshot.json | 1459 ++++------------- .../v2/test_change_sets.validation.json | 82 +- 2 files changed, 361 insertions(+), 1180 deletions(-) diff --git a/tests/aws/services/cloudformation/v2/test_change_sets.snapshot.json b/tests/aws/services/cloudformation/v2/test_change_sets.snapshot.json index 41bde15184ef2..c3a4b82904be4 100644 --- a/tests/aws/services/cloudformation/v2/test_change_sets.snapshot.json +++ b/tests/aws/services/cloudformation/v2/test_change_sets.snapshot.json @@ -95,7 +95,7 @@ } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_direct_update": { - "recorded-date": "16-06-2025, 22:25:10", + "recorded-date": "17-06-2025, 15:48:17", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -418,7 +418,7 @@ } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_dynamic_update": { - "recorded-date": "24-04-2025, 17:02:59", + "recorded-date": "17-06-2025, 15:50:21", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -608,9 +608,8 @@ }, "Details": [ { - "CausingEntity": "Foo.TopicName", - "ChangeSource": "ResourceAttribute", - "Evaluation": "Static", + "ChangeSource": "DirectModification", + "Evaluation": "Dynamic", "Target": { "AfterValue": "{{changeSet:KNOWN_AFTER_APPLY}}", "Attribute": "Properties", @@ -622,8 +621,9 @@ } }, { - "ChangeSource": "DirectModification", - "Evaluation": "Dynamic", + "CausingEntity": "Foo.TopicName", + "ChangeSource": "ResourceAttribute", + "Evaluation": "Static", "Target": { "AfterValue": "{{changeSet:KNOWN_AFTER_APPLY}}", "Attribute": "Properties", @@ -636,7 +636,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-b4xwNWwXL1pX", + "PhysicalResourceId": "CFN-Parameter-MV9j0kT1pZVw", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -705,7 +705,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-b4xwNWwXL1pX", + "PhysicalResourceId": "CFN-Parameter-MV9j0kT1pZVw", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -751,247 +751,108 @@ "Tags": [] }, "per-resource-events": { - "Foo": [ - { - "EventId": "Foo-33c3e9d2-d059-45a8-a51e-33eaf1f08abc", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceStatus": "DELETE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-5160f677-0c84-41ba-ab19-45a474a4b7bf", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceStatus": "DELETE_IN_PROGRESS", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_COMPLETE-date", + "Foo": { + "CREATE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-2", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-2", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", + "DELETE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Requested update requires the creation of a new physical resource; hence creating one.", + "ResourceStatus": "DELETE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_COMPLETE-date", + "DELETE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "DELETE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_IN_PROGRESS-date", + "UPDATE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_IN_PROGRESS-date", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "Parameter": [ - { - "EventId": "Parameter-UPDATE_COMPLETE-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-b4xwNWwXL1pX", - "ResourceProperties": { - "Type": "String", - "Value": "topic-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-UPDATE_IN_PROGRESS-date", + }, + "Parameter": { + "CREATE_COMPLETE": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-b4xwNWwXL1pX", - "ResourceProperties": { - "Type": "String", - "Value": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_COMPLETE-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-b4xwNWwXL1pX", - "ResourceProperties": { - "Type": "String", - "Value": "topic-1" - }, - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", + "UPDATE_COMPLETE": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-b4xwNWwXL1pX", - "ResourceProperties": { - "Type": "String", - "Value": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "": [ - { - "EventId": "", + }, + "Stack": { + "CREATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "REVIEW_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ] + } }, "delete-describe": { "CreationTime": "datetime", @@ -1011,7 +872,7 @@ } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_parameter_changes": { - "recorded-date": "24-04-2025, 17:38:55", + "recorded-date": "17-06-2025, 15:52:26", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -1178,8 +1039,9 @@ }, "Details": [ { - "ChangeSource": "DirectModification", - "Evaluation": "Dynamic", + "CausingEntity": "TopicName", + "ChangeSource": "ParameterReference", + "Evaluation": "Static", "Target": { "AfterValue": "topic-2", "Attribute": "Properties", @@ -1191,9 +1053,8 @@ } }, { - "CausingEntity": "TopicName", - "ChangeSource": "ParameterReference", - "Evaluation": "Static", + "ChangeSource": "DirectModification", + "Evaluation": "Dynamic", "Target": { "AfterValue": "topic-2", "Attribute": "Properties", @@ -1233,8 +1094,9 @@ }, "Details": [ { - "ChangeSource": "DirectModification", - "Evaluation": "Dynamic", + "CausingEntity": "Foo.TopicName", + "ChangeSource": "ResourceAttribute", + "Evaluation": "Static", "Target": { "AfterValue": "{{changeSet:KNOWN_AFTER_APPLY}}", "Attribute": "Properties", @@ -1246,9 +1108,8 @@ } }, { - "CausingEntity": "Foo.TopicName", - "ChangeSource": "ResourceAttribute", - "Evaluation": "Static", + "ChangeSource": "DirectModification", + "Evaluation": "Dynamic", "Target": { "AfterValue": "{{changeSet:KNOWN_AFTER_APPLY}}", "Attribute": "Properties", @@ -1261,7 +1122,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-59wvoXl3mFfy", + "PhysicalResourceId": "CFN-Parameter-aauza4UeZvlW", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -1346,7 +1207,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-59wvoXl3mFfy", + "PhysicalResourceId": "CFN-Parameter-aauza4UeZvlW", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -1404,247 +1265,108 @@ "Tags": [] }, "per-resource-events": { - "Foo": [ - { - "EventId": "Foo-da242d34-1619-4128-b9a1-24ae25f05899", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceStatus": "DELETE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-8aa7df32-a61d-4794-9f57-c33004142e46", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceStatus": "DELETE_IN_PROGRESS", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_COMPLETE-date", + "Foo": { + "CREATE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-2", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-2", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", + "DELETE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Requested update requires the creation of a new physical resource; hence creating one.", + "ResourceStatus": "DELETE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_COMPLETE-date", + "DELETE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "DELETE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_IN_PROGRESS-date", + "UPDATE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_IN_PROGRESS-date", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "Parameter": [ - { - "EventId": "Parameter-UPDATE_COMPLETE-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-59wvoXl3mFfy", - "ResourceProperties": { - "Type": "String", - "Value": "topic-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-UPDATE_IN_PROGRESS-date", + }, + "Parameter": { + "CREATE_COMPLETE": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-59wvoXl3mFfy", - "ResourceProperties": { - "Type": "String", - "Value": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_COMPLETE-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-59wvoXl3mFfy", - "ResourceProperties": { - "Type": "String", - "Value": "topic-1" - }, - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", + "UPDATE_COMPLETE": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-59wvoXl3mFfy", - "ResourceProperties": { - "Type": "String", - "Value": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "": [ - { - "EventId": "", + }, + "Stack": { + "CREATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "REVIEW_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ] + } }, "delete-describe": { "CreationTime": "datetime", @@ -1670,7 +1392,7 @@ } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_mappings_with_static_fields": { - "recorded-date": "24-04-2025, 17:40:57", + "recorded-date": "17-06-2025, 15:54:31", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -1888,7 +1610,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-U4lqVSH21TIK", + "PhysicalResourceId": "CFN-Parameter-Bg9tRBFfL6b9", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -1957,7 +1679,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-U4lqVSH21TIK", + "PhysicalResourceId": "CFN-Parameter-Bg9tRBFfL6b9", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -2003,247 +1725,108 @@ "Tags": [] }, "per-resource-events": { - "Foo": [ - { - "EventId": "Foo-19d3838e-f734-4c47-bbc3-ed5ce898ae7f", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceStatus": "DELETE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-1d67606c-91cd-478e-aa7f-bb5f79834fe4", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceStatus": "DELETE_IN_PROGRESS", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_COMPLETE-date", + "Foo": { + "CREATE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", - "ResourceProperties": { - "TopicName": "topic-name-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", - "ResourceProperties": { - "TopicName": "topic-name-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", + "DELETE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceProperties": { - "TopicName": "topic-name-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Requested update requires the creation of a new physical resource; hence creating one.", + "ResourceStatus": "DELETE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_COMPLETE-date", + "DELETE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceProperties": { - "TopicName": "topic-name-1" - }, - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "DELETE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_IN_PROGRESS-date", + "UPDATE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceProperties": { - "TopicName": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_IN_PROGRESS-date", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "", - "ResourceProperties": { - "TopicName": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "Parameter": [ - { - "EventId": "Parameter-UPDATE_COMPLETE-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-U4lqVSH21TIK", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-UPDATE_IN_PROGRESS-date", + }, + "Parameter": { + "CREATE_COMPLETE": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-U4lqVSH21TIK", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_COMPLETE-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-U4lqVSH21TIK", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-1" - }, - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", + "UPDATE_COMPLETE": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-U4lqVSH21TIK", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "": [ - { - "EventId": "", + }, + "Stack": { + "CREATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "REVIEW_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ] + } }, "delete-describe": { "CreationTime": "datetime", @@ -2263,7 +1846,7 @@ } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_mappings_with_parameter_lookup": { - "recorded-date": "24-04-2025, 17:42:57", + "recorded-date": "17-06-2025, 15:56:35", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -2430,8 +2013,9 @@ }, "Details": [ { - "ChangeSource": "DirectModification", - "Evaluation": "Dynamic", + "CausingEntity": "TopicName", + "ChangeSource": "ParameterReference", + "Evaluation": "Static", "Target": { "AfterValue": "topic-name-2", "Attribute": "Properties", @@ -2443,9 +2027,8 @@ } }, { - "CausingEntity": "TopicName", - "ChangeSource": "ParameterReference", - "Evaluation": "Static", + "ChangeSource": "DirectModification", + "Evaluation": "Dynamic", "Target": { "AfterValue": "topic-name-2", "Attribute": "Properties", @@ -2485,8 +2068,9 @@ }, "Details": [ { - "ChangeSource": "DirectModification", - "Evaluation": "Dynamic", + "CausingEntity": "Foo.TopicName", + "ChangeSource": "ResourceAttribute", + "Evaluation": "Static", "Target": { "AfterValue": "{{changeSet:KNOWN_AFTER_APPLY}}", "Attribute": "Properties", @@ -2498,9 +2082,8 @@ } }, { - "CausingEntity": "Foo.TopicName", - "ChangeSource": "ResourceAttribute", - "Evaluation": "Static", + "ChangeSource": "DirectModification", + "Evaluation": "Dynamic", "Target": { "AfterValue": "{{changeSet:KNOWN_AFTER_APPLY}}", "Attribute": "Properties", @@ -2513,7 +2096,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-ir98heGTa0zR", + "PhysicalResourceId": "CFN-Parameter-dzDuhAbUJEPp", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -2598,7 +2181,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-ir98heGTa0zR", + "PhysicalResourceId": "CFN-Parameter-dzDuhAbUJEPp", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -2656,247 +2239,108 @@ "Tags": [] }, "per-resource-events": { - "Foo": [ - { - "EventId": "Foo-4f6c54a4-1549-4bd7-97c4-dd0ecca23860", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceStatus": "DELETE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-53ede9ba-f993-45dd-9b68-e31f406d95c2", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceStatus": "DELETE_IN_PROGRESS", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_COMPLETE-date", + "Foo": { + "CREATE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", - "ResourceProperties": { - "TopicName": "topic-name-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", - "ResourceProperties": { - "TopicName": "topic-name-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", + "DELETE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceProperties": { - "TopicName": "topic-name-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Requested update requires the creation of a new physical resource; hence creating one.", + "ResourceStatus": "DELETE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_COMPLETE-date", + "DELETE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceProperties": { - "TopicName": "topic-name-1" - }, - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "DELETE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_IN_PROGRESS-date", + "UPDATE_COMPLETE": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceProperties": { - "TopicName": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Foo-CREATE_IN_PROGRESS-date", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "Foo", - "PhysicalResourceId": "", - "ResourceProperties": { - "TopicName": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "Parameter": [ - { - "EventId": "Parameter-UPDATE_COMPLETE-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-ir98heGTa0zR", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-UPDATE_IN_PROGRESS-date", + }, + "Parameter": { + "CREATE_COMPLETE": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-ir98heGTa0zR", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_COMPLETE-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-ir98heGTa0zR", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-1" - }, - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", + "UPDATE_COMPLETE": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-ir98heGTa0zR", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "": [ - { - "EventId": "", + }, + "Stack": { + "CREATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "REVIEW_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ] + } }, "delete-describe": { "CreationTime": "datetime", @@ -2922,7 +2366,7 @@ } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_conditions": { - "recorded-date": "24-04-2025, 17:54:44", + "recorded-date": "17-06-2025, 15:57:14", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -3146,152 +2590,72 @@ "Tags": [] }, "per-resource-events": { - "Bucket": [ - { - "EventId": "Bucket-CREATE_COMPLETE-date", + "Bucket": { + "CREATE_COMPLETE": { "LogicalResourceId": "Bucket", - "PhysicalResourceId": "-bucket-lrfokvsfgf0f", - "ResourceProperties": {}, "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::S3::Bucket", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Bucket-CREATE_IN_PROGRESS-date", - "LogicalResourceId": "Bucket", - "PhysicalResourceId": "-bucket-lrfokvsfgf0f", - "ResourceProperties": {}, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", - "ResourceType": "AWS::S3::Bucket", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Bucket-CREATE_IN_PROGRESS-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "Bucket", - "PhysicalResourceId": "", - "ResourceProperties": {}, "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::S3::Bucket", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "Parameter": [ - { - "EventId": "Parameter-CREATE_COMPLETE-date", + }, + "Parameter": { + "CREATE_COMPLETE": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-XN7hqAZ0p5We", - "ResourceProperties": { - "Type": "String", - "Value": "test" - }, "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-XN7hqAZ0p5We", - "ResourceProperties": { - "Type": "String", - "Value": "test" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "test" - }, "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "": [ - { - "EventId": "", + }, + "Stack": { + "CREATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "REVIEW_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ] + } }, "delete-describe": { "CreationTime": "datetime", @@ -3317,7 +2681,7 @@ } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_dynamic]": { - "recorded-date": "24-04-2025, 17:55:06", + "recorded-date": "17-06-2025, 15:57:39", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -3489,7 +2853,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-UlYVEyGMt3Hh", + "PhysicalResourceId": "CFN-Parameter-B3JQENmH8XiB", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -3548,7 +2912,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-UlYVEyGMt3Hh", + "PhysicalResourceId": "CFN-Parameter-B3JQENmH8XiB", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -3606,144 +2970,70 @@ "Tags": [] }, "per-resource-events": { - "Parameter": [ - { - "EventId": "Parameter-UPDATE_COMPLETE-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-UlYVEyGMt3Hh", - "ResourceProperties": { - "Type": "String", - "Value": "value-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-UPDATE_IN_PROGRESS-date", + "Parameter": { + "CREATE_COMPLETE": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-UlYVEyGMt3Hh", - "ResourceProperties": { - "Type": "String", - "Value": "value-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_COMPLETE-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-UlYVEyGMt3Hh", - "ResourceProperties": { - "Type": "String", - "Value": "value-1" - }, - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", + "UPDATE_COMPLETE": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-UlYVEyGMt3Hh", - "ResourceProperties": { - "Type": "String", - "Value": "value-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "value-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "": [ - { - "EventId": "", + }, + "Stack": { + "CREATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "REVIEW_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ] + } }, "delete-describe": { "CreationTime": "datetime", @@ -3769,15 +3059,15 @@ } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_unrelated_property]": { - "recorded-date": "24-04-2025, 17:55:06", + "recorded-date": "17-06-2025, 15:57:39", "recorded-content": {} }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_unrelated_property_not_create_only]": { - "recorded-date": "24-04-2025, 17:55:06", + "recorded-date": "17-06-2025, 15:57:39", "recorded-content": {} }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_parameter_for_condition_create_resource]": { - "recorded-date": "24-04-2025, 17:55:28", + "recorded-date": "17-06-2025, 15:58:04", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -4004,161 +3294,72 @@ "Tags": [] }, "per-resource-events": { - "SSMParameter1": [ - { - "EventId": "SSMParameter1-CREATE_COMPLETE-date", + "SSMParameter1": { + "CREATE_COMPLETE": { "LogicalResourceId": "SSMParameter1", - "PhysicalResourceId": "CFN-SSMParameter1-qGQrGgGvuC42", - "ResourceProperties": { - "Type": "String", - "Value": "first" - }, "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "SSMParameter1-CREATE_IN_PROGRESS-date", - "LogicalResourceId": "SSMParameter1", - "PhysicalResourceId": "CFN-SSMParameter1-qGQrGgGvuC42", - "ResourceProperties": { - "Type": "String", - "Value": "first" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "SSMParameter1-CREATE_IN_PROGRESS-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "SSMParameter1", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "first" - }, "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "SSMParameter2": [ - { - "EventId": "SSMParameter2-CREATE_COMPLETE-date", + }, + "SSMParameter2": { + "CREATE_COMPLETE": { "LogicalResourceId": "SSMParameter2", - "PhysicalResourceId": "CFN-SSMParameter2-9KvTVovmiPsN", - "ResourceProperties": { - "Type": "String", - "Value": "first" - }, "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "SSMParameter2-CREATE_IN_PROGRESS-date", - "LogicalResourceId": "SSMParameter2", - "PhysicalResourceId": "CFN-SSMParameter2-9KvTVovmiPsN", - "ResourceProperties": { - "Type": "String", - "Value": "first" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "SSMParameter2-CREATE_IN_PROGRESS-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "SSMParameter2", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "first" - }, "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "": [ - { - "EventId": "", + }, + "Stack": { + "CREATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "REVIEW_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ] + } }, "delete-describe": { "CreationTime": "datetime", @@ -4184,14 +3385,14 @@ } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_execute_with_ref": { - "recorded-date": "24-04-2025, 17:55:57", + "recorded-date": "17-06-2025, 15:58:38", "recorded-content": { "before-value": "", "after-value": "" } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_mapping_scenarios[update_string_referencing_resource]": { - "recorded-date": "24-04-2025, 17:56:19", + "recorded-date": "17-06-2025, 15:59:04", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -4331,7 +3532,7 @@ } ], "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "CFN-MySSMParameter-sK4jajBbVCXk", + "PhysicalResourceId": "CFN-MySSMParameter-cI5TOEuueEDD", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -4374,7 +3575,7 @@ } ], "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "CFN-MySSMParameter-sK4jajBbVCXk", + "PhysicalResourceId": "CFN-MySSMParameter-cI5TOEuueEDD", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -4420,144 +3621,70 @@ "Tags": [] }, "per-resource-events": { - "MySSMParameter": [ - { - "EventId": "MySSMParameter-UPDATE_COMPLETE-date", - "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "CFN-MySSMParameter-sK4jajBbVCXk", - "ResourceProperties": { - "Type": "String", - "Value": "value-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "MySSMParameter-UPDATE_IN_PROGRESS-date", + "MySSMParameter": { + "CREATE_COMPLETE": { "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "CFN-MySSMParameter-sK4jajBbVCXk", - "ResourceProperties": { - "Type": "String", - "Value": "value-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "MySSMParameter-CREATE_COMPLETE-date", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "CFN-MySSMParameter-sK4jajBbVCXk", - "ResourceProperties": { - "Type": "String", - "Value": "value-1" - }, - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "MySSMParameter-CREATE_IN_PROGRESS-date", + "UPDATE_COMPLETE": { "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "CFN-MySSMParameter-sK4jajBbVCXk", - "ResourceProperties": { - "Type": "String", - "Value": "value-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "MySSMParameter-CREATE_IN_PROGRESS-date", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "value-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ], - "": [ - { - "EventId": "", + }, + "Stack": { + "CREATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "CREATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "REVIEW_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_COMPLETE", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, - { - "EventId": "", + "UPDATE_IN_PROGRESS": { "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } - ] + } }, "delete-describe": { "CreationTime": "datetime", diff --git a/tests/aws/services/cloudformation/v2/test_change_sets.validation.json b/tests/aws/services/cloudformation/v2/test_change_sets.validation.json index ca3dd6c689085..f76c3fdae07dc 100644 --- a/tests/aws/services/cloudformation/v2/test_change_sets.validation.json +++ b/tests/aws/services/cloudformation/v2/test_change_sets.validation.json @@ -1,39 +1,93 @@ { "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_dynamic]": { - "last_validated_date": "2025-04-24T17:55:06+00:00" + "last_validated_date": "2025-06-17T15:57:39+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 25.01, + "teardown": 0.15, + "total": 25.16 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_parameter_for_condition_create_resource]": { - "last_validated_date": "2025-04-24T17:55:28+00:00" + "last_validated_date": "2025-06-17T15:58:04+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 24.98, + "teardown": 0.14, + "total": 25.12 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_mapping_scenarios[update_string_referencing_resource]": { - "last_validated_date": "2025-04-24T17:56:19+00:00" + "last_validated_date": "2025-06-17T15:59:04+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 26.25, + "teardown": 0.14, + "total": 26.39 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_conditions": { - "last_validated_date": "2025-04-24T17:54:44+00:00" + "last_validated_date": "2025-06-17T15:57:14+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 38.17, + "teardown": 0.15, + "total": 38.32 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_direct_update": { - "last_validated_date": "2025-06-16T22:25:10+00:00", + "last_validated_date": "2025-06-17T15:48:17+00:00", "durations_in_seconds": { - "setup": 0.24, - "call": 116.21, - "teardown": 0.14, - "total": 116.59 + "setup": 0.22, + "call": 116.43, + "teardown": 0.15, + "total": 116.8 } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_dynamic_update": { - "last_validated_date": "2025-04-24T17:02:59+00:00" + "last_validated_date": "2025-06-17T15:50:21+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 123.39, + "teardown": 0.14, + "total": 123.53 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_execute_with_ref": { - "last_validated_date": "2025-04-24T17:55:52+00:00" + "last_validated_date": "2025-06-17T15:58:38+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 27.0, + "teardown": 6.57, + "total": 33.57 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_mappings_with_parameter_lookup": { - "last_validated_date": "2025-04-24T17:42:57+00:00" + "last_validated_date": "2025-06-17T15:56:35+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 124.37, + "teardown": 0.15, + "total": 124.52 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_mappings_with_static_fields": { - "last_validated_date": "2025-04-24T17:40:56+00:00" + "last_validated_date": "2025-06-17T15:54:31+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 124.47, + "teardown": 0.14, + "total": 124.61 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_parameter_changes": { - "last_validated_date": "2025-04-24T17:38:55+00:00" + "last_validated_date": "2025-06-17T15:52:26+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 125.38, + "teardown": 0.14, + "total": 125.52 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::test_single_resource_static_update": { "last_validated_date": "2025-03-18T16:52:35+00:00"