Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions awscli/customizations/cloudformation/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,30 @@ class DeployCommand(BasicCommand):
' execute it to implement your changes.'
)
},
{
'name': 'disable-rollback',
'required': False,
'action': 'store_true',
'group_name': 'disable-rollback',
'dest': 'disable_rollback',
'default': False,
'help_text': (
'Preserve the state of previously provisioned resources when '
'the execute-change-set operation fails.'
)
},
{
'name': 'no-disable-rollback',
'required': False,
'action': 'store_false',
'group_name': 'disable-rollback',
'dest': 'disable_rollback',
'default': True,
'help_text': (
'Roll back all resource changes when the execute-change-set '
'operation fails.'
)
},
{
'name': 'role-arn',
'required': False,
Expand Down Expand Up @@ -291,13 +315,13 @@ def _run_main(self, parsed_args, parsed_globals):
parameters, parsed_args.capabilities,
parsed_args.execute_changeset, parsed_args.role_arn,
parsed_args.notification_arns, s3_uploader,
tags,
parsed_args.fail_on_empty_changeset)
tags, parsed_args.fail_on_empty_changeset,
parsed_args.disable_rollback)

def deploy(self, deployer, stack_name, template_str,
parameters, capabilities, execute_changeset, role_arn,
notification_arns, s3_uploader, tags,
fail_on_empty_changeset=True):
fail_on_empty_changeset=True, disable_rollback=False):
try:
result = deployer.create_and_wait_for_changeset(
stack_name=stack_name,
Expand All @@ -316,7 +340,8 @@ def deploy(self, deployer, stack_name, template_str,
return 0

if execute_changeset:
deployer.execute_changeset(result.changeset_id, stack_name)
deployer.execute_changeset(result.changeset_id, stack_name,
disable_rollback)
deployer.wait_for_execute(stack_name, result.changeset_type)
sys.stdout.write(self.MSG_EXECUTE_SUCCESS.format(
stack_name=stack_name))
Expand Down
7 changes: 5 additions & 2 deletions awscli/customizations/cloudformation/deployer.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,17 +177,20 @@ def wait_for_changeset(self, changeset_id, stack_name):
"Status: {1}. Reason: {2}"
.format(ex, status, reason))

def execute_changeset(self, changeset_id, stack_name):
def execute_changeset(self, changeset_id, stack_name,
disable_rollback=False):
"""
Calls CloudFormation to execute changeset

:param changeset_id: ID of the changeset
:param stack_name: Name or ID of the stack
:param disable_rollback: Disable rollback of all resource changes
:return: Response from execute-change-set call
"""
return self._client.execute_change_set(
ChangeSetName=changeset_id,
StackName=stack_name)
StackName=stack_name,
DisableRollback=disable_rollback)

def wait_for_execute(self, stack_name, changeset_type):

Expand Down
5 changes: 4 additions & 1 deletion tests/unit/customizations/cloudformation/test_deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def setUp(self):
"Key2=Value2"],
no_execute_changeset=False,
execute_changeset=True,
disable_rollback=True,
capabilities=None,
role_arn=None,
notification_arns=[],
Expand Down Expand Up @@ -119,6 +120,7 @@ def test_command_invoked(self, mock_yaml_parse):
[],
None,
fake_tags,
True,
True
)

Expand Down Expand Up @@ -205,6 +207,7 @@ def test_s3_uploader_is_configured_properly(self, s3UploaderMock,
[],
s3UploaderObject,
[{"Key": "tagkey1", "Value": "tagvalue1"}],
True,
True
)

Expand Down Expand Up @@ -257,7 +260,7 @@ def test_deploy_success(self):
tags=tags)

# since execute_changeset is set to True, deploy() will execute changeset
self.deployer.execute_changeset.assert_called_once_with(changeset_id, stack_name)
self.deployer.execute_changeset.assert_called_once_with(changeset_id, stack_name, False)
self.deployer.wait_for_execute.assert_called_once_with(stack_name, changeset_type)


Expand Down
19 changes: 18 additions & 1 deletion tests/unit/customizations/cloudformation/test_deployer.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,13 +261,30 @@ def test_execute_changeset(self):

expected_params = {
"ChangeSetName": changeset_id,
"StackName": stack_name
"StackName": stack_name,
"DisableRollback": False
}

self.stub_client.add_response("execute_change_set", {}, expected_params)
with self.stub_client:
self.deployer.execute_changeset(changeset_id, stack_name)

def test_execute_changeset_disable_rollback(self):
stack_name = "stack_name"
changeset_id = "changeset_id"
disable_rollback = True

expected_params = {
"ChangeSetName": changeset_id,
"StackName": stack_name,
"DisableRollback": disable_rollback
}

self.stub_client.add_response("execute_change_set", {}, expected_params)
with self.stub_client:
self.deployer.execute_changeset(changeset_id, stack_name,
disable_rollback)

def test_execute_changeset_exception(self):
stack_name = "stack_name"
changeset_id = "changeset_id"
Expand Down