Skip to content

Commit

Permalink
#3712 add --disable-rollback to aws cloudformation deploy
Browse files Browse the repository at this point in the history
  • Loading branch information
atheiman authored and stealthycoin committed Feb 4, 2022
1 parent 408c70a commit 4965818
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 8 deletions.
35 changes: 31 additions & 4 deletions awscli/customizations/cloudformation/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,31 @@ 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 '
'an operation fails.'
)
},
{
'name': 'no-disable-rollback',
'required': False,
'action': 'store_false',
'group_name': 'disable-rollback',
'dest': 'disable_rollback',
'default': True,
'help_text': (
'Causes CloudFormation to attempt to rollback resource changes '
'when an error is encountered creating or updating a stack '
'(this is the default behavior).'
)
},
{
'name': 'role-arn',
'required': False,
Expand Down Expand Up @@ -289,14 +314,15 @@ def _run_main(self, parsed_args, parsed_globals):
deployer = Deployer(cloudformation_client)
return self.deploy(deployer, stack_name, template_str,
parameters, parsed_args.capabilities,
parsed_args.execute_changeset, parsed_args.role_arn,
parsed_args.execute_changeset,
parsed_args.disable_rollback, parsed_args.role_arn,
parsed_args.notification_arns, s3_uploader,
tags,
parsed_args.fail_on_empty_changeset)

def deploy(self, deployer, stack_name, template_str,
parameters, capabilities, execute_changeset, role_arn,
notification_arns, s3_uploader, tags,
parameters, capabilities, execute_changeset, disable_rollback,
role_arn, notification_arns, s3_uploader, tags,
fail_on_empty_changeset=True):
try:
result = deployer.create_and_wait_for_changeset(
Expand All @@ -316,7 +342,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
6 changes: 4 additions & 2 deletions awscli/customizations/cloudformation/deployer.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ 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
Expand All @@ -187,7 +188,8 @@ def execute_changeset(self, changeset_id, stack_name):
"""
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 awscli/examples/cloudformation/deploy.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
Following command deploys template named ``template.json`` to a stack named
``my-new-stack``::


aws cloudformation deploy --template-file /path_to_template/template.json --stack-name my-new-stack --parameter-overrides Key1=Value1 Key2=Value2 --tags Key1=Value1 Key2=Value2

Following command deploys template named ``template.json`` to a stack named
``my-new-stack``. If an error is encountered, the deploy stops and a rollback is not triggered::

aws cloudformation deploy --template-file /path_to_template/template.json --stack-name my-new-stack --disable-rollback
2 changes: 2 additions & 0 deletions 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 @@ -115,6 +116,7 @@ def test_command_invoked(self, mock_yaml_parse):
fake_parameters,
None,
not self.parsed_args.no_execute_changeset,
True,
None,
[],
None,
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

0 comments on commit 4965818

Please sign in to comment.