Skip to content

Commit 2a61360

Browse files
authored
Merge pull request #6453 from atheiman/cloudformation-deploy-disable-rollback
add --disable-rollback to `aws cloudformation deploy`
2 parents 408c70a + 365a789 commit 2a61360

4 files changed

Lines changed: 56 additions & 8 deletions

File tree

awscli/customizations/cloudformation/deploy.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,30 @@ class DeployCommand(BasicCommand):
169169
' execute it to implement your changes.'
170170
)
171171
},
172+
{
173+
'name': 'disable-rollback',
174+
'required': False,
175+
'action': 'store_true',
176+
'group_name': 'disable-rollback',
177+
'dest': 'disable_rollback',
178+
'default': False,
179+
'help_text': (
180+
'Preserve the state of previously provisioned resources when '
181+
'the execute-change-set operation fails.'
182+
)
183+
},
184+
{
185+
'name': 'no-disable-rollback',
186+
'required': False,
187+
'action': 'store_false',
188+
'group_name': 'disable-rollback',
189+
'dest': 'disable_rollback',
190+
'default': True,
191+
'help_text': (
192+
'Roll back all resource changes when the execute-change-set '
193+
'operation fails.'
194+
)
195+
},
172196
{
173197
'name': 'role-arn',
174198
'required': False,
@@ -291,13 +315,13 @@ def _run_main(self, parsed_args, parsed_globals):
291315
parameters, parsed_args.capabilities,
292316
parsed_args.execute_changeset, parsed_args.role_arn,
293317
parsed_args.notification_arns, s3_uploader,
294-
tags,
295-
parsed_args.fail_on_empty_changeset)
318+
tags, parsed_args.fail_on_empty_changeset,
319+
parsed_args.disable_rollback)
296320

297321
def deploy(self, deployer, stack_name, template_str,
298322
parameters, capabilities, execute_changeset, role_arn,
299323
notification_arns, s3_uploader, tags,
300-
fail_on_empty_changeset=True):
324+
fail_on_empty_changeset=True, disable_rollback=False):
301325
try:
302326
result = deployer.create_and_wait_for_changeset(
303327
stack_name=stack_name,
@@ -316,7 +340,8 @@ def deploy(self, deployer, stack_name, template_str,
316340
return 0
317341

318342
if execute_changeset:
319-
deployer.execute_changeset(result.changeset_id, stack_name)
343+
deployer.execute_changeset(result.changeset_id, stack_name,
344+
disable_rollback)
320345
deployer.wait_for_execute(stack_name, result.changeset_type)
321346
sys.stdout.write(self.MSG_EXECUTE_SUCCESS.format(
322347
stack_name=stack_name))

awscli/customizations/cloudformation/deployer.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,17 +177,20 @@ def wait_for_changeset(self, changeset_id, stack_name):
177177
"Status: {1}. Reason: {2}"
178178
.format(ex, status, reason))
179179

180-
def execute_changeset(self, changeset_id, stack_name):
180+
def execute_changeset(self, changeset_id, stack_name,
181+
disable_rollback=False):
181182
"""
182183
Calls CloudFormation to execute changeset
183184
184185
:param changeset_id: ID of the changeset
185186
:param stack_name: Name or ID of the stack
187+
:param disable_rollback: Disable rollback of all resource changes
186188
:return: Response from execute-change-set call
187189
"""
188190
return self._client.execute_change_set(
189191
ChangeSetName=changeset_id,
190-
StackName=stack_name)
192+
StackName=stack_name,
193+
DisableRollback=disable_rollback)
191194

192195
def wait_for_execute(self, stack_name, changeset_type):
193196

tests/unit/customizations/cloudformation/test_deploy.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def setUp(self):
5252
"Key2=Value2"],
5353
no_execute_changeset=False,
5454
execute_changeset=True,
55+
disable_rollback=True,
5556
capabilities=None,
5657
role_arn=None,
5758
notification_arns=[],
@@ -119,6 +120,7 @@ def test_command_invoked(self, mock_yaml_parse):
119120
[],
120121
None,
121122
fake_tags,
123+
True,
122124
True
123125
)
124126

@@ -205,6 +207,7 @@ def test_s3_uploader_is_configured_properly(self, s3UploaderMock,
205207
[],
206208
s3UploaderObject,
207209
[{"Key": "tagkey1", "Value": "tagvalue1"}],
210+
True,
208211
True
209212
)
210213

@@ -257,7 +260,7 @@ def test_deploy_success(self):
257260
tags=tags)
258261

259262
# since execute_changeset is set to True, deploy() will execute changeset
260-
self.deployer.execute_changeset.assert_called_once_with(changeset_id, stack_name)
263+
self.deployer.execute_changeset.assert_called_once_with(changeset_id, stack_name, False)
261264
self.deployer.wait_for_execute.assert_called_once_with(stack_name, changeset_type)
262265

263266

tests/unit/customizations/cloudformation/test_deployer.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,13 +261,30 @@ def test_execute_changeset(self):
261261

262262
expected_params = {
263263
"ChangeSetName": changeset_id,
264-
"StackName": stack_name
264+
"StackName": stack_name,
265+
"DisableRollback": False
265266
}
266267

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

272+
def test_execute_changeset_disable_rollback(self):
273+
stack_name = "stack_name"
274+
changeset_id = "changeset_id"
275+
disable_rollback = True
276+
277+
expected_params = {
278+
"ChangeSetName": changeset_id,
279+
"StackName": stack_name,
280+
"DisableRollback": disable_rollback
281+
}
282+
283+
self.stub_client.add_response("execute_change_set", {}, expected_params)
284+
with self.stub_client:
285+
self.deployer.execute_changeset(changeset_id, stack_name,
286+
disable_rollback)
287+
271288
def test_execute_changeset_exception(self):
272289
stack_name = "stack_name"
273290
changeset_id = "changeset_id"

0 commit comments

Comments
 (0)