diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py index bd130e2046269..3db66e6895803 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py @@ -256,6 +256,7 @@ class NodeResource(ChangeSetNode): type_: Final[ChangeSetTerminal] condition_reference: Final[Optional[TerminalValue]] properties: Final[NodeProperties] + depends_on: Final[Optional[NodeDependsOn]] def __init__( self, @@ -263,14 +264,16 @@ def __init__( change_type: ChangeType, name: str, type_: ChangeSetTerminal, - condition_reference: TerminalValue, properties: NodeProperties, + condition_reference: Optional[TerminalValue], + depends_on: Optional[NodeDependsOn], ): super().__init__(scope=scope, change_type=change_type) self.name = name self.type_ = type_ - self.condition_reference = condition_reference self.properties = properties + self.condition_reference = condition_reference + self.depends_on = depends_on class NodeProperties(ChangeSetNode): @@ -281,6 +284,14 @@ def __init__(self, scope: Scope, change_type: ChangeType, properties: list[NodeP self.properties = properties +class NodeDependsOn(ChangeSetNode): + depends_on: Final[NodeArray] + + def __init__(self, scope: Scope, change_type: ChangeType, depends_on: NodeArray): + super().__init__(scope=scope, change_type=change_type) + self.depends_on = depends_on + + class NodeProperty(ChangeSetNode): name: Final[str] value: Final[ChangeSetEntity] @@ -365,6 +376,7 @@ def __init__(self, scope: Scope, value: Any): ValueKey: Final[str] = "Value" ExportKey: Final[str] = "Export" OutputsKey: Final[str] = "Outputs" +DependsOnKey: Final[str] = "DependsOn" # TODO: expand intrinsic functions set. RefKey: Final[str] = "Ref" FnIfKey: Final[str] = "Fn::If" @@ -770,12 +782,20 @@ def _visit_resource( scope_condition, (before_condition, after_condition) = self._safe_access_in( scope, ConditionKey, before_resource, after_resource ) - # TODO: condition references should be resolved for the condition's change_type? if before_condition or after_condition: condition_reference = self._visit_terminal_value( scope_condition, before_condition, after_condition ) + depends_on = None + scope_depends_on, (before_depends_on, after_depends_on) = self._safe_access_in( + scope, DependsOnKey, before_resource, after_resource + ) + if before_depends_on or after_depends_on: + depends_on = self._visit_depends_on( + scope_depends_on, before_depends_on, after_depends_on + ) + scope_properties, (before_properties, after_properties) = self._safe_access_in( scope, PropertiesKey, before_resource, after_resource ) @@ -793,8 +813,9 @@ def _visit_resource( change_type=change_type, name=resource_name, type_=terminal_value_type, - condition_reference=condition_reference, properties=properties, + condition_reference=condition_reference, + depends_on=depends_on, ) self._visited_scopes[scope] = node_resource return node_resource @@ -925,6 +946,38 @@ def _visit_parameters( self._visited_scopes[scope] = node_parameters return node_parameters + @staticmethod + def _normalise_depends_on_value(value: Maybe[str | list[str]]) -> Maybe[list[str]]: + # To simplify downstream logics, reduce the type options to array of strings. + # TODO: Add integrations tests for DependsOn validations (invalid types, duplicate identifiers, etc.) + if isinstance(value, NothingType): + return value + if isinstance(value, str): + value = [value] + elif isinstance(value, list): + value.sort() + else: + raise RuntimeError( + f"Invalid type for DependsOn, expected a String or Array of String, but got: '{value}'" + ) + return value + + def _visit_depends_on( + self, + scope: Scope, + before_depends_on: Maybe[str | list[str]], + after_depends_on: Maybe[str | list[str]], + ) -> NodeDependsOn: + before_depends_on = self._normalise_depends_on_value(value=before_depends_on) + after_depends_on = self._normalise_depends_on_value(value=after_depends_on) + node_array = self._visit_array( + scope=scope, before_array=before_depends_on, after_array=after_depends_on + ) + node_depends_on = NodeDependsOn( + scope=scope, change_type=node_array.change_type, depends_on=node_array + ) + return node_depends_on + def _visit_condition( self, scope: Scope, 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 8941d9e4bc1ea..eb63b968bc10b 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 @@ -7,6 +7,7 @@ from localstack.aws.api.cloudformation import ChangeAction, StackStatus from localstack.constants import INTERNAL_AWS_SECRET_ACCESS_KEY from localstack.services.cloudformation.engine.v2.change_set_model import ( + NodeDependsOn, NodeOutput, NodeParameter, NodeResource, @@ -77,6 +78,23 @@ def _after_resource_physical_id(self, resource_logical_id: str) -> str: logical_resource_id=resource_logical_id, resolved_resources=after_resolved_resources ) + def visit_node_depends_on(self, node_depends_on: NodeDependsOn) -> PreprocEntityDelta: + array_identifiers_delta = super().visit_node_depends_on(node_depends_on=node_depends_on) + + # Visit depends_on resources before returning. + depends_on_resource_logical_ids: set[str] = set() + if array_identifiers_delta.before: + depends_on_resource_logical_ids.update(array_identifiers_delta.before) + if array_identifiers_delta.after: + depends_on_resource_logical_ids.update(array_identifiers_delta.after) + for depends_on_resource_logical_id in depends_on_resource_logical_ids: + node_resource = self._get_node_resource_for( + resource_name=depends_on_resource_logical_id, node_template=self._node_template + ) + self.visit_node_resource(node_resource) + + return array_identifiers_delta + def visit_node_resource( self, node_resource: NodeResource ) -> PreprocEntityDelta[PreprocResource, PreprocResource]: diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py index 1ab31e15928df..a3eb266adf597 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py @@ -7,6 +7,7 @@ ChangeType, NodeArray, NodeCondition, + NodeDependsOn, NodeDivergence, NodeIntrinsicFunction, NodeMapping, @@ -81,6 +82,7 @@ class PreprocResource: condition: Optional[bool] resource_type: str properties: PreprocProperties + depends_on: Optional[list[str]] def __init__( self, @@ -89,12 +91,14 @@ def __init__( condition: Optional[bool], resource_type: str, properties: PreprocProperties, + depends_on: Optional[list[str]], ): self.logical_id = logical_id self.physical_resource_id = physical_resource_id self.condition = condition self.resource_type = resource_type self.properties = properties + self.depends_on = depends_on @staticmethod def _compare_conditions(c1: bool, c2: bool): @@ -533,6 +537,10 @@ def visit_node_parameter(self, node_parameter: NodeParameter) -> PreprocEntityDe return PreprocEntityDelta(before=before, after=after) + def visit_node_depends_on(self, node_depends_on: NodeDependsOn) -> PreprocEntityDelta: + array_identifiers_delta = self.visit(node_depends_on.depends_on) + return array_identifiers_delta + def visit_node_condition(self, node_condition: NodeCondition) -> PreprocEntityDelta: delta = self.visit(node_condition.body) return delta @@ -638,6 +646,13 @@ def visit_node_resource( condition_before = condition_delta.before condition_after = condition_delta.after + depends_on_before = None + depends_on_after = None + if node_resource.depends_on is not None: + depends_on_delta = self.visit_node_depends_on(node_resource.depends_on) + depends_on_before = depends_on_delta.before + depends_on_after = depends_on_delta.after + type_delta = self.visit(node_resource.type_) properties_delta: PreprocEntityDelta[PreprocProperties, PreprocProperties] = self.visit( node_resource.properties @@ -656,6 +671,7 @@ def visit_node_resource( condition=condition_before, resource_type=type_delta.before, properties=properties_delta.before, + depends_on=depends_on_before, ) if change_type != ChangeType.REMOVED and condition_after is None or condition_after: logical_resource_id = node_resource.name @@ -671,6 +687,7 @@ def visit_node_resource( condition=condition_after, resource_type=type_delta.after, properties=properties_delta.after, + depends_on=depends_on_after, ) return PreprocEntityDelta(before=before, after=after) diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_visitor.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_visitor.py index c1b09a82ef1f4..8f9121cf2c70d 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_visitor.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_visitor.py @@ -5,6 +5,7 @@ NodeArray, NodeCondition, NodeConditions, + NodeDependsOn, NodeDivergence, NodeIntrinsicFunction, NodeMapping, @@ -73,6 +74,9 @@ def visit_node_conditions(self, node_conditions: NodeConditions): def visit_node_condition(self, node_condition: NodeCondition): self.visit_children(node_condition) + def visit_node_depends_on(self, node_depends_on: NodeDependsOn): + self.visit_children(node_depends_on) + def visit_node_resources(self, node_resources: NodeResources): self.visit_children(node_resources) diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py index 77bc440910ee6..ce07d3206e676 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py @@ -59,7 +59,6 @@ """ -@pytest.mark.skip(reason="no support for DependsOn") # this is an `only_localstack` test because it makes use of _custom_id_ tag @markers.aws.only_localstack def test_cfn_apigateway_aws_integration(deploy_cfn_template, aws_client): @@ -143,7 +142,10 @@ def test_cfn_apigateway_swagger_import(deploy_cfn_template, echo_http_server_pos assert content["url"].endswith("/post") -@pytest.mark.skip(reason="No support for DependsOn") +@pytest.mark.skip( + reason="The v2 provider appears to instead return the correct url: " + "https://e1i3grfiws.execute-api.us-east-1.localhost.localstack.cloud/prod/" +) @markers.aws.only_localstack def test_url_output(httpserver, deploy_cfn_template): httpserver.expect_request("").respond_with_data(b"", 200) @@ -225,7 +227,7 @@ def test_cfn_with_apigateway_resources(deploy_cfn_template, aws_client, snapshot # assert not apis -@pytest.mark.skip(reason="DependsOn is unsupported") +@pytest.mark.skip(reason="NotFoundException Invalid Method identifier specified") @markers.aws.validated @markers.snapshot.skip_snapshot_verify( paths=[ @@ -279,7 +281,6 @@ def test_cfn_deploy_apigateway_models(deploy_cfn_template, snapshot, aws_client) assert result.status_code == 400 -@pytest.mark.skip(reason="DependsOn is unsupported") @markers.aws.validated def test_cfn_deploy_apigateway_integration(deploy_cfn_template, snapshot, aws_client): snapshot.add_transformer(snapshot.transform.key_value("cacheNamespace")) diff --git a/tests/aws/services/cloudformation/v2/test_change_set_conditions.py b/tests/aws/services/cloudformation/v2/test_change_set_conditions.py index 9967f6cf4b607..f6b5661736f37 100644 --- a/tests/aws/services/cloudformation/v2/test_change_set_conditions.py +++ b/tests/aws/services/cloudformation/v2/test_change_set_conditions.py @@ -15,7 +15,6 @@ "per-resource-events..*", "delete-describe..*", # - "$..ChangeSetId", # An issue for the WIP executor # Before/After Context "$..Capabilities", "$..NotificationARNs", diff --git a/tests/aws/services/cloudformation/v2/test_change_set_depends_on.py b/tests/aws/services/cloudformation/v2/test_change_set_depends_on.py new file mode 100644 index 0000000000000..e4f7545a5667d --- /dev/null +++ b/tests/aws/services/cloudformation/v2/test_change_set_depends_on.py @@ -0,0 +1,192 @@ +import pytest +from localstack_snapshot.snapshots.transformer import RegexTransformer + +from localstack.services.cloudformation.v2.utils import is_v2_engine +from localstack.testing.aws.util import is_aws_cloud +from localstack.testing.pytest import markers +from localstack.utils.strings import long_uid + + +@pytest.mark.skipif( + condition=not is_v2_engine() and not is_aws_cloud(), reason="Requires the V2 engine" +) +@markers.snapshot.skip_snapshot_verify( + paths=[ + "per-resource-events..*", + "delete-describe..*", + # + # Before/After Context + "$..Capabilities", + "$..NotificationARNs", + "$..IncludeNestedStacks", + "$..Scope", + "$..Details", + "$..Parameters", + "$..Replacement", + "$..PolicyAction", + ] +) +class TestChangeSetDependsOn: + @markers.aws.validated + def test_update_depended_resource( + self, + snapshot, + capture_update_process, + ): + name1 = f"topic-name-1-{long_uid()}" + name2 = f"topic-name-2-{long_uid()}" + snapshot.add_transformer(RegexTransformer(name1, "topic-name-1")) + snapshot.add_transformer(RegexTransformer(name2, "topic-name-2")) + template_1 = { + "Resources": { + "Topic1": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name1, "DisplayName": "display-value-1"}, + }, + "Topic2": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name2, "DisplayName": "display-value-2"}, + "DependsOn": "Topic1", + }, + } + } + template_2 = { + "Resources": { + "Topic1": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name1, "DisplayName": "display-value-1-updated"}, + }, + "Topic2": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name2, "DisplayName": "display-value-2"}, + "DependsOn": "Topic1", + }, + } + } + capture_update_process(snapshot, template_1, template_2) + + @markers.aws.validated + def test_update_depended_resource_list( + self, + snapshot, + capture_update_process, + ): + name1 = f"topic-name-1-{long_uid()}" + name2 = f"topic-name-2-{long_uid()}" + snapshot.add_transformer(RegexTransformer(name1, "topic-name-1")) + snapshot.add_transformer(RegexTransformer(name2, "topic-name-2")) + template_1 = { + "Resources": { + "Topic1": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name1, "DisplayName": "display-value-1"}, + }, + "Topic2": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name2, "DisplayName": "display-value-2"}, + "DependsOn": ["Topic1"], + }, + } + } + template_2 = { + "Resources": { + "Topic1": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name1, "DisplayName": "display-value-1-updated"}, + }, + "Topic2": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name2, "DisplayName": "display-value-2"}, + "DependsOn": ["Topic1"], + }, + } + } + capture_update_process(snapshot, template_1, template_2) + + @markers.aws.validated + def test_multiple_dependencies_addition( + self, + snapshot, + capture_update_process, + ): + name1 = f"topic-name-1-{long_uid()}" + name2 = f"topic-name-2-{long_uid()}" + namen = f"topic-name-n-{long_uid()}" + snapshot.add_transformer(RegexTransformer(name1, "topic-name-1")) + snapshot.add_transformer(RegexTransformer(name2, "topic-name-2")) + snapshot.add_transformer(RegexTransformer(namen, "topic-name-n")) + template_1 = { + "Resources": { + "Topic1": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name1, "DisplayName": "display-value-1"}, + }, + "Topicn": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": namen, "DisplayName": "display-value-n"}, + "DependsOn": ["Topic1"], + }, + } + } + template_2 = { + "Resources": { + "Topic1": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name1, "DisplayName": "display-value-1"}, + }, + "Topicn": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": namen, "DisplayName": "display-value-n"}, + "DependsOn": ["Topic1", "Topic2"], + }, + "Topic2": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name2, "DisplayName": "display-value-2"}, + }, + } + } + capture_update_process(snapshot, template_1, template_2) + + @markers.aws.validated + def test_multiple_dependencies_deletion( + self, + snapshot, + capture_update_process, + ): + name1 = f"topic-name-1-{long_uid()}" + name2 = f"topic-name-2-{long_uid()}" + namen = f"topic-name-n-{long_uid()}" + snapshot.add_transformer(RegexTransformer(name1, "topic-name-1")) + snapshot.add_transformer(RegexTransformer(name2, "topic-name-2")) + snapshot.add_transformer(RegexTransformer(namen, "topic-name-n")) + template_1 = { + "Resources": { + "Topic1": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name1, "DisplayName": "display-value-1"}, + }, + "Topic2": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name2, "DisplayName": "display-value-2"}, + }, + "Topicn": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": namen, "DisplayName": "display-value-n"}, + "DependsOn": ["Topic1", "Topic2"], + }, + } + } + template_2 = { + "Resources": { + "Topic1": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": name1, "DisplayName": "display-value-1"}, + }, + "Topicn": { + "Type": "AWS::SNS::Topic", + "Properties": {"TopicName": namen, "DisplayName": "display-value-n"}, + "DependsOn": ["Topic1"], + }, + } + } + capture_update_process(snapshot, template_1, template_2) diff --git a/tests/aws/services/cloudformation/v2/test_change_set_depends_on.snapshot.json b/tests/aws/services/cloudformation/v2/test_change_set_depends_on.snapshot.json new file mode 100644 index 0000000000000..1c31c72649fa4 --- /dev/null +++ b/tests/aws/services/cloudformation/v2/test_change_set_depends_on.snapshot.json @@ -0,0 +1,1838 @@ +{ + "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_update_depended_resource": { + "recorded-date": "19-05-2025, 12:55:10", + "recorded-content": { + "create-change-set-1": { + "Id": "arn::cloudformation::111111111111:changeSet/", + "StackId": "arn::cloudformation::111111111111:stack//", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-1-prop-values": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + } + }, + "Details": [], + "LogicalResourceId": "Topic1", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + }, + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + } + }, + "Details": [], + "LogicalResourceId": "Topic2", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-1": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "Details": [], + "LogicalResourceId": "Topic1", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + }, + { + "ResourceChange": { + "Action": "Add", + "Details": [], + "LogicalResourceId": "Topic2", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "execute-change-set-1": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "post-create-1-describe": { + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "CreationTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "EnableTerminationProtection": false, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "CREATE_COMPLETE", + "Tags": [] + }, + "create-change-set-2": { + "Id": "arn::cloudformation::111111111111:changeSet/", + "StackId": "arn::cloudformation::111111111111:stack//", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-2-prop-values": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Modify", + "AfterContext": { + "Properties": { + "DisplayName": "display-value-1-updated", + "TopicName": "topic-name-1" + } + }, + "BeforeContext": { + "Properties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + } + }, + "Details": [ + { + "ChangeSource": "DirectModification", + "Evaluation": "Static", + "Target": { + "AfterValue": "display-value-1-updated", + "Attribute": "Properties", + "AttributeChangeType": "Modify", + "BeforeValue": "display-value-1", + "Name": "DisplayName", + "Path": "/Properties/DisplayName", + "RequiresRecreation": "Never" + } + } + ], + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "Replacement": "False", + "ResourceType": "AWS::SNS::Topic", + "Scope": [ + "Properties" + ] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-2": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Modify", + "Details": [ + { + "ChangeSource": "DirectModification", + "Evaluation": "Static", + "Target": { + "Attribute": "Properties", + "Name": "DisplayName", + "RequiresRecreation": "Never" + } + } + ], + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "Replacement": "False", + "ResourceType": "AWS::SNS::Topic", + "Scope": [ + "Properties" + ] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "execute-change-set-2": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "post-create-2-describe": { + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "CreationTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "EnableTerminationProtection": false, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "UPDATE_COMPLETE", + "Tags": [] + }, + "per-resource-events": { + "Topic1": [ + { + "EventId": "Topic1-UPDATE_COMPLETE-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "ResourceProperties": { + "DisplayName": "display-value-1-updated", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "UPDATE_COMPLETE", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic1-UPDATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "ResourceProperties": { + "DisplayName": "display-value-1-updated", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "UPDATE_IN_PROGRESS", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic1-CREATE_COMPLETE-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "ResourceProperties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic1-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "ResourceProperties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "Resource creation Initiated", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic1-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "", + "ResourceProperties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ], + "Topic2": [ + { + "EventId": "Topic2-CREATE_COMPLETE-date", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "ResourceProperties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + }, + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic2-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "ResourceProperties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "Resource creation Initiated", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic2-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "", + "ResourceProperties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ], + "": [ + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_COMPLETE", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "REVIEW_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ] + }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + } + } + }, + "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_update_depended_resource_list": { + "recorded-date": "19-05-2025, 13:01:35", + "recorded-content": { + "create-change-set-1": { + "Id": "arn::cloudformation::111111111111:changeSet/", + "StackId": "arn::cloudformation::111111111111:stack//", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-1-prop-values": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + } + }, + "Details": [], + "LogicalResourceId": "Topic1", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + }, + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + } + }, + "Details": [], + "LogicalResourceId": "Topic2", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-1": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "Details": [], + "LogicalResourceId": "Topic1", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + }, + { + "ResourceChange": { + "Action": "Add", + "Details": [], + "LogicalResourceId": "Topic2", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "execute-change-set-1": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "post-create-1-describe": { + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "CreationTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "EnableTerminationProtection": false, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "CREATE_COMPLETE", + "Tags": [] + }, + "create-change-set-2": { + "Id": "arn::cloudformation::111111111111:changeSet/", + "StackId": "arn::cloudformation::111111111111:stack//", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-2-prop-values": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Modify", + "AfterContext": { + "Properties": { + "DisplayName": "display-value-1-updated", + "TopicName": "topic-name-1" + } + }, + "BeforeContext": { + "Properties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + } + }, + "Details": [ + { + "ChangeSource": "DirectModification", + "Evaluation": "Static", + "Target": { + "AfterValue": "display-value-1-updated", + "Attribute": "Properties", + "AttributeChangeType": "Modify", + "BeforeValue": "display-value-1", + "Name": "DisplayName", + "Path": "/Properties/DisplayName", + "RequiresRecreation": "Never" + } + } + ], + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "Replacement": "False", + "ResourceType": "AWS::SNS::Topic", + "Scope": [ + "Properties" + ] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-2": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Modify", + "Details": [ + { + "ChangeSource": "DirectModification", + "Evaluation": "Static", + "Target": { + "Attribute": "Properties", + "Name": "DisplayName", + "RequiresRecreation": "Never" + } + } + ], + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "Replacement": "False", + "ResourceType": "AWS::SNS::Topic", + "Scope": [ + "Properties" + ] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "execute-change-set-2": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "post-create-2-describe": { + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "CreationTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "EnableTerminationProtection": false, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "UPDATE_COMPLETE", + "Tags": [] + }, + "per-resource-events": { + "Topic1": [ + { + "EventId": "Topic1-UPDATE_COMPLETE-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "ResourceProperties": { + "DisplayName": "display-value-1-updated", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "UPDATE_COMPLETE", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic1-UPDATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "ResourceProperties": { + "DisplayName": "display-value-1-updated", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "UPDATE_IN_PROGRESS", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic1-CREATE_COMPLETE-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "ResourceProperties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic1-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "ResourceProperties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "Resource creation Initiated", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic1-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "", + "ResourceProperties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ], + "Topic2": [ + { + "EventId": "Topic2-CREATE_COMPLETE-date", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "ResourceProperties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + }, + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic2-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "ResourceProperties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "Resource creation Initiated", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic2-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "", + "ResourceProperties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ], + "": [ + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_COMPLETE", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "REVIEW_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ] + }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + } + } + }, + "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_multiple_dependencies_addition": { + "recorded-date": "19-05-2025, 18:10:11", + "recorded-content": { + "create-change-set-1": { + "Id": "arn::cloudformation::111111111111:changeSet/", + "StackId": "arn::cloudformation::111111111111:stack//", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-1-prop-values": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + } + }, + "Details": [], + "LogicalResourceId": "Topic1", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + }, + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "DisplayName": "display-value-n", + "TopicName": "topic-name-n" + } + }, + "Details": [], + "LogicalResourceId": "Topicn", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-1": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "Details": [], + "LogicalResourceId": "Topic1", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + }, + { + "ResourceChange": { + "Action": "Add", + "Details": [], + "LogicalResourceId": "Topicn", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "execute-change-set-1": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "post-create-1-describe": { + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "CreationTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "EnableTerminationProtection": false, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "CREATE_COMPLETE", + "Tags": [] + }, + "create-change-set-2": { + "Id": "arn::cloudformation::111111111111:changeSet/", + "StackId": "arn::cloudformation::111111111111:stack//", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-2-prop-values": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + } + }, + "Details": [], + "LogicalResourceId": "Topic2", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-2": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "Details": [], + "LogicalResourceId": "Topic2", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "execute-change-set-2": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "post-create-2-describe": { + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "CreationTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "EnableTerminationProtection": false, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "UPDATE_COMPLETE", + "Tags": [] + }, + "per-resource-events": { + "Topic1": [ + { + "EventId": "Topic1-CREATE_COMPLETE-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "ResourceProperties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic1-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "ResourceProperties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "Resource creation Initiated", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic1-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "", + "ResourceProperties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ], + "Topic2": [ + { + "EventId": "Topic2-CREATE_COMPLETE-date", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "ResourceProperties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + }, + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic2-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "ResourceProperties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "Resource creation Initiated", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic2-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "", + "ResourceProperties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ], + "Topicn": [ + { + "EventId": "Topicn-CREATE_COMPLETE-date", + "LogicalResourceId": "Topicn", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-n", + "ResourceProperties": { + "DisplayName": "display-value-n", + "TopicName": "topic-name-n" + }, + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topicn-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topicn", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-n", + "ResourceProperties": { + "DisplayName": "display-value-n", + "TopicName": "topic-name-n" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "Resource creation Initiated", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topicn-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topicn", + "PhysicalResourceId": "", + "ResourceProperties": { + "DisplayName": "display-value-n", + "TopicName": "topic-name-n" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ], + "": [ + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_COMPLETE", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "REVIEW_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ] + }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + } + } + }, + "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_multiple_dependencies_deletion": { + "recorded-date": "19-05-2025, 18:13:11", + "recorded-content": { + "create-change-set-1": { + "Id": "arn::cloudformation::111111111111:changeSet/", + "StackId": "arn::cloudformation::111111111111:stack//", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-1-prop-values": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + } + }, + "Details": [], + "LogicalResourceId": "Topic1", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + }, + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + } + }, + "Details": [], + "LogicalResourceId": "Topic2", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + }, + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "DisplayName": "display-value-n", + "TopicName": "topic-name-n" + } + }, + "Details": [], + "LogicalResourceId": "Topicn", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-1": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "Details": [], + "LogicalResourceId": "Topic1", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + }, + { + "ResourceChange": { + "Action": "Add", + "Details": [], + "LogicalResourceId": "Topic2", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + }, + { + "ResourceChange": { + "Action": "Add", + "Details": [], + "LogicalResourceId": "Topicn", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "execute-change-set-1": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "post-create-1-describe": { + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "CreationTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "EnableTerminationProtection": false, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "CREATE_COMPLETE", + "Tags": [] + }, + "create-change-set-2": { + "Id": "arn::cloudformation::111111111111:changeSet/", + "StackId": "arn::cloudformation::111111111111:stack//", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-2-prop-values": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Remove", + "BeforeContext": { + "Properties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + } + }, + "Details": [], + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "PolicyAction": "Delete", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-2": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Remove", + "Details": [], + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "PolicyAction": "Delete", + "ResourceType": "AWS::SNS::Topic", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "execute-change-set-2": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "post-create-2-describe": { + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "CreationTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "EnableTerminationProtection": false, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "UPDATE_COMPLETE", + "Tags": [] + }, + "per-resource-events": { + "Topic1": [ + { + "EventId": "Topic1-CREATE_COMPLETE-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "ResourceProperties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic1-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", + "ResourceProperties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "Resource creation Initiated", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic1-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic1", + "PhysicalResourceId": "", + "ResourceProperties": { + "DisplayName": "display-value-1", + "TopicName": "topic-name-1" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ], + "Topic2": [ + { + "EventId": "Topic2-ff127104-011d-4af1-9ed0-52ed22dff1b7", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "ResourceStatus": "DELETE_COMPLETE", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic2-4b69478e-eeb4-4f9b-8a8a-e6e94164ec5a", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "ResourceStatus": "DELETE_IN_PROGRESS", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic2-CREATE_COMPLETE-date", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "ResourceProperties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + }, + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic2-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "ResourceProperties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "Resource creation Initiated", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topic2-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topic2", + "PhysicalResourceId": "", + "ResourceProperties": { + "DisplayName": "display-value-2", + "TopicName": "topic-name-2" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ], + "Topicn": [ + { + "EventId": "Topicn-CREATE_COMPLETE-date", + "LogicalResourceId": "Topicn", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-n", + "ResourceProperties": { + "DisplayName": "display-value-n", + "TopicName": "topic-name-n" + }, + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topicn-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topicn", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-n", + "ResourceProperties": { + "DisplayName": "display-value-n", + "TopicName": "topic-name-n" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "Resource creation Initiated", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Topicn-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Topicn", + "PhysicalResourceId": "", + "ResourceProperties": { + "DisplayName": "display-value-n", + "TopicName": "topic-name-n" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceType": "AWS::SNS::Topic", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ], + "": [ + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_COMPLETE", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "REVIEW_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ] + }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + } + } + } +} diff --git a/tests/aws/services/cloudformation/v2/test_change_set_depends_on.validation.json b/tests/aws/services/cloudformation/v2/test_change_set_depends_on.validation.json new file mode 100644 index 0000000000000..6d50b4297ea1d --- /dev/null +++ b/tests/aws/services/cloudformation/v2/test_change_set_depends_on.validation.json @@ -0,0 +1,14 @@ +{ + "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_multiple_dependencies_addition": { + "last_validated_date": "2025-05-19T18:10:11+00:00" + }, + "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_multiple_dependencies_deletion": { + "last_validated_date": "2025-05-19T18:13:11+00:00" + }, + "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_update_depended_resource": { + "last_validated_date": "2025-05-19T12:55:09+00:00" + }, + "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_update_depended_resource_list": { + "last_validated_date": "2025-05-19T13:01:34+00:00" + } +} diff --git a/tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py b/tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py index 01719bdea7778..5255ff0704736 100644 --- a/tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py +++ b/tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py @@ -15,7 +15,6 @@ "per-resource-events..*", "delete-describe..*", # - "$..ChangeSetId", # An issue for the WIP executor # Before/After Context "$..Capabilities", "$..NotificationARNs", diff --git a/tests/aws/services/cloudformation/v2/test_change_set_fn_join.py b/tests/aws/services/cloudformation/v2/test_change_set_fn_join.py index 89ae48d6a3641..718f1a1181043 100644 --- a/tests/aws/services/cloudformation/v2/test_change_set_fn_join.py +++ b/tests/aws/services/cloudformation/v2/test_change_set_fn_join.py @@ -15,7 +15,6 @@ "per-resource-events..*", "delete-describe..*", # - "$..ChangeSetId", # An issue for the WIP executor # Before/After Context "$..Capabilities", "$..NotificationARNs", diff --git a/tests/aws/services/cloudformation/v2/test_change_set_mappings.py b/tests/aws/services/cloudformation/v2/test_change_set_mappings.py index 55c9d5d1b5197..05fa11a2cce80 100644 --- a/tests/aws/services/cloudformation/v2/test_change_set_mappings.py +++ b/tests/aws/services/cloudformation/v2/test_change_set_mappings.py @@ -15,7 +15,6 @@ "per-resource-events..*", "delete-describe..*", # - "$..ChangeSetId", # An issue for the WIP executor # Before/After Context "$..Capabilities", "$..NotificationARNs", diff --git a/tests/aws/services/cloudformation/v2/test_change_set_parameters.py b/tests/aws/services/cloudformation/v2/test_change_set_parameters.py index 50c371dad8186..ac04661b2ba8d 100644 --- a/tests/aws/services/cloudformation/v2/test_change_set_parameters.py +++ b/tests/aws/services/cloudformation/v2/test_change_set_parameters.py @@ -15,7 +15,6 @@ "per-resource-events..*", "delete-describe..*", # - "$..ChangeSetId", # An issue for the WIP executor # Before/After Context "$..Capabilities", "$..NotificationARNs", diff --git a/tests/aws/services/cloudformation/v2/test_change_set_ref.py b/tests/aws/services/cloudformation/v2/test_change_set_ref.py index 94113c52ca781..b743070ebbfad 100644 --- a/tests/aws/services/cloudformation/v2/test_change_set_ref.py +++ b/tests/aws/services/cloudformation/v2/test_change_set_ref.py @@ -15,7 +15,6 @@ "per-resource-events..*", "delete-describe..*", # - "$..ChangeSetId", # An issue for the WIP executor # Before/After Context "$..Capabilities", "$..NotificationARNs", diff --git a/tests/aws/services/cloudformation/v2/test_change_set_values.py b/tests/aws/services/cloudformation/v2/test_change_set_values.py index 70f23b3e0b01a..8a1c3b3b2588c 100644 --- a/tests/aws/services/cloudformation/v2/test_change_set_values.py +++ b/tests/aws/services/cloudformation/v2/test_change_set_values.py @@ -15,7 +15,6 @@ "per-resource-events..*", "delete-describe..*", # - "$..ChangeSetId", # An issue for the WIP executor # Before/After Context "$..Capabilities", "$..NotificationARNs",