Skip to content

Commit

Permalink
fix: correct status when updating an updated stack (#7272)
Browse files Browse the repository at this point in the history
* fix: correct status when updating an updated stack

* Implement snapshot test for new functionality
  • Loading branch information
simonrw committed Dec 2, 2022
1 parent 0bf2ae2 commit 732a8e7
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 2 deletions.
6 changes: 5 additions & 1 deletion localstack/utils/cloudformation/template_deployer.py
Expand Up @@ -1066,7 +1066,11 @@ def deploy_stack(self):
raise

def apply_change_set(self, change_set):
action = "UPDATE" if change_set.stack.status == "CREATE_COMPLETE" else "CREATE"
action = (
"UPDATE"
if change_set.stack.status in {"CREATE_COMPLETE", "UPDATE_COMPLETE"}
else "CREATE"
)
change_set.stack.set_stack_status(f"{action}_IN_PROGRESS")

# update attributes that the stack inherits from the changeset
Expand Down
75 changes: 75 additions & 0 deletions tests/integration/cloudformation/api/test_stacks.py
Expand Up @@ -426,3 +426,78 @@ def test_prevent_resource_deletion(deploy_cfn_template, cfn_client, sns_client,
cfn_client.delete_stack(StackName=stack.stack_name)

sns_client.get_topic_attributes(TopicArn=stack.outputs["TopicArn"])


@pytest.mark.aws_validated
@pytest.mark.skip_snapshot_verify(
paths=[
# parameters may be out of order
"$..Stacks..Parameters",
]
)
def test_updating_an_updated_stack_sets_status(deploy_cfn_template, cfn_client, snapshot):
"""
The status of a stack that has been updated twice should be "UPDATE_COMPLETE"
"""
snapshot.add_transformer(snapshot.transform.cloudformation_api())

# need multiple templates to support updates to the stack
template_1 = load_file(
os.path.join(os.path.dirname(__file__), "../../templates/stack_update_1.yaml")
)
template_2 = load_file(
os.path.join(os.path.dirname(__file__), "../../templates/stack_update_2.yaml")
)
template_3 = load_file(
os.path.join(os.path.dirname(__file__), "../../templates/stack_update_3.yaml")
)

topic_1_name = f"topic-1-{short_uid()}"
topic_2_name = f"topic-2-{short_uid()}"
topic_3_name = f"topic-3-{short_uid()}"
snapshot.add_transformers_list(
[
snapshot.transform.regex(topic_1_name, "topic-1"),
snapshot.transform.regex(topic_2_name, "topic-2"),
snapshot.transform.regex(topic_3_name, "topic-3"),
]
)

parameters = {
"Topic1Name": topic_1_name,
"Topic2Name": topic_2_name,
"Topic3Name": topic_3_name,
}

def wait_for(waiter_type: str) -> None:
cfn_client.get_waiter(waiter_type).wait(
StackName=stack.stack_name,
WaiterConfig={
"Delay": 5,
"MaxAttempts": 5,
},
)

stack = deploy_cfn_template(template=template_1, parameters=parameters)
wait_for("stack_create_complete")

# update the stack
deploy_cfn_template(
template=template_2,
is_update=True,
stack_name=stack.stack_name,
parameters=parameters,
)
wait_for("stack_update_complete")

# update the stack again
deploy_cfn_template(
template=template_3,
is_update=True,
stack_name=stack.stack_name,
parameters=parameters,
)
wait_for("stack_update_complete")

res = cfn_client.describe_stacks(StackName=stack.stack_name)
snapshot.match("describe-result", res)
50 changes: 49 additions & 1 deletion tests/integration/cloudformation/api/test_stacks.snapshot.json
Expand Up @@ -440,5 +440,53 @@
}
}
}
},
"tests/integration/cloudformation/api/test_stacks.py::test_updating_an_updated_stack_sets_status": {
"recorded-date": "02-12-2022, 11:19:41",
"recorded-content": {
"describe-result": {
"Stacks": [
{
"Capabilities": [
"CAPABILITY_AUTO_EXPAND",
"CAPABILITY_IAM",
"CAPABILITY_NAMED_IAM"
],
"ChangeSetId": "arn:aws:cloudformation:<region>:111111111111:changeSet/<resource:1>",
"CreationTime": "datetime",
"DisableRollback": false,
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
},
"EnableTerminationProtection": false,
"LastUpdatedTime": "datetime",
"NotificationARNs": [],
"Parameters": [
{
"ParameterKey": "Topic2Name",
"ParameterValue": "topic-2"
},
{
"ParameterKey": "Topic1Name",
"ParameterValue": "topic-1"
},
{
"ParameterKey": "Topic3Name",
"ParameterValue": "topic-3"
}
],
"RollbackConfiguration": {},
"StackId": "arn:aws:cloudformation:<region>:111111111111:stack/<stack-name:1>/<resource:2>",
"StackName": "<stack-name:1>",
"StackStatus": "UPDATE_COMPLETE",
"Tags": []
}
],
"ResponseMetadata": {
"HTTPHeaders": {},
"HTTPStatusCode": 200
}
}
}
}
}
}
15 changes: 15 additions & 0 deletions tests/integration/templates/stack_update_1.yaml
@@ -0,0 +1,15 @@
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Topic1Name:
Type: String
Topic2Name:
Type: String
Topic3Name:
Type: String
Resources:
topic1:
Type: AWS::SNS::Topic
Properties:
TopicName: !Ref Topic1Name
UpdateReplacePolicy: Delete
DeletionPolicy: Delete
21 changes: 21 additions & 0 deletions tests/integration/templates/stack_update_2.yaml
@@ -0,0 +1,21 @@
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Topic1Name:
Type: String
Topic2Name:
Type: String
Topic3Name:
Type: String
Resources:
topic1:
Type: AWS::SNS::Topic
Properties:
TopicName: !Ref Topic1Name
UpdateReplacePolicy: Delete
DeletionPolicy: Delete
topic2:
Type: AWS::SNS::Topic
Properties:
TopicName: !Ref Topic2Name
UpdateReplacePolicy: Delete
DeletionPolicy: Delete
27 changes: 27 additions & 0 deletions tests/integration/templates/stack_update_3.yaml
@@ -0,0 +1,27 @@
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Topic1Name:
Type: String
Topic2Name:
Type: String
Topic3Name:
Type: String
Resources:
topic1:
Type: AWS::SNS::Topic
Properties:
TopicName: !Ref Topic1Name
UpdateReplacePolicy: Delete
DeletionPolicy: Delete
topic2:
Type: AWS::SNS::Topic
Properties:
TopicName: !Ref Topic2Name
UpdateReplacePolicy: Delete
DeletionPolicy: Delete
topic3:
Type: AWS::SNS::Topic
Properties:
TopicName: !Ref Topic3Name
UpdateReplacePolicy: Delete
DeletionPolicy: Delete

0 comments on commit 732a8e7

Please sign in to comment.