mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Support 'termination protection' for cloudformation stacks (#31675)
* Support 'termination protection' for cloudformation stacks - Pass in the stack_name and desired termination protection state to update_termination_protection * Fix for failing cloudformation unit test * Check if cfn has update_termination_protection attr * Use hasattr to test if cfn supports update_termination_protection * termination_protection shouldn't prevent update_stack call for existing stacks
This commit is contained in:
parent
a8bc6f69d9
commit
b9e15d0df1
1 changed files with 48 additions and 2 deletions
|
@ -118,6 +118,10 @@ options:
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
version_added: "2.3"
|
version_added: "2.3"
|
||||||
|
termination_protection:
|
||||||
|
description:
|
||||||
|
- enable or disable termination protection on the stack. Only works with botocore >= 1.7.18.
|
||||||
|
version_added: "2.5"
|
||||||
|
|
||||||
author: "James S. Martin (@jsmartin)"
|
author: "James S. Martin (@jsmartin)"
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
|
@ -173,6 +177,16 @@ EXAMPLES = '''
|
||||||
ClusterSize: 3
|
ClusterSize: 3
|
||||||
tags:
|
tags:
|
||||||
Stack: ansible-cloudformation
|
Stack: ansible-cloudformation
|
||||||
|
|
||||||
|
# Enable termination protection on a stack.
|
||||||
|
# If the stack already exists, this will update its termination protection
|
||||||
|
- name: enable termination protection during stack creation
|
||||||
|
cloudformation:
|
||||||
|
stack_name: my_stack
|
||||||
|
state: present
|
||||||
|
template_url: https://s3.amazonaws.com/my-bucket/cloudformation.template
|
||||||
|
termination_protection: yes
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = '''
|
RETURN = '''
|
||||||
|
@ -256,8 +270,14 @@ def create_stack(module, stack_params, cfn):
|
||||||
if 'TemplateBody' not in stack_params and 'TemplateURL' not in stack_params:
|
if 'TemplateBody' not in stack_params and 'TemplateURL' not in stack_params:
|
||||||
module.fail_json(msg="Either 'template' or 'template_url' is required when the stack does not exist.")
|
module.fail_json(msg="Either 'template' or 'template_url' is required when the stack does not exist.")
|
||||||
|
|
||||||
# 'disablerollback' only applies on creation, not update.
|
# 'disablerollback' and 'EnableTerminationProtection' only
|
||||||
|
# apply on creation, not update.
|
||||||
stack_params['DisableRollback'] = module.params['disable_rollback']
|
stack_params['DisableRollback'] = module.params['disable_rollback']
|
||||||
|
if module.params.get('termination_protection') is not None:
|
||||||
|
if boto_supports_termination_protection(cfn):
|
||||||
|
stack_params['EnableTerminationProtection'] = bool(module.params.get('termination_protection'))
|
||||||
|
else:
|
||||||
|
module.fail_json(msg="termination_protection parameter requires botocore >= 1.7.18")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cfn.create_stack(**stack_params)
|
cfn.create_stack(**stack_params)
|
||||||
|
@ -328,6 +348,26 @@ def update_stack(module, stack_params, cfn):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def update_termination_protection(module, cfn, stack_name, desired_termination_protection_state):
|
||||||
|
'''updates termination protection of a stack'''
|
||||||
|
if not boto_supports_termination_protection(cfn):
|
||||||
|
module.fail_json(msg="termination_protection parameter requires botocore >= 1.7.18")
|
||||||
|
stack = get_stack_facts(cfn, stack_name)
|
||||||
|
if stack:
|
||||||
|
if stack['EnableTerminationProtection'] is not desired_termination_protection_state:
|
||||||
|
try:
|
||||||
|
cfn.update_termination_protection(
|
||||||
|
EnableTerminationProtection=desired_termination_protection_state,
|
||||||
|
StackName=stack_name)
|
||||||
|
except botocore.exceptions.ClientError as e:
|
||||||
|
module.fail_json(msg=boto_exception(e), exception=traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
|
def boto_supports_termination_protection(cfn):
|
||||||
|
'''termination protection was added in botocore 1.7.18'''
|
||||||
|
return hasattr(cfn, "update_termination_protection")
|
||||||
|
|
||||||
|
|
||||||
def stack_operation(cfn, stack_name, operation):
|
def stack_operation(cfn, stack_name, operation):
|
||||||
'''gets the status of a stack while it is created/updated/deleted'''
|
'''gets the status of a stack while it is created/updated/deleted'''
|
||||||
existed = []
|
existed = []
|
||||||
|
@ -450,7 +490,8 @@ def main():
|
||||||
create_changeset=dict(default=False, type='bool'),
|
create_changeset=dict(default=False, type='bool'),
|
||||||
changeset_name=dict(default=None, required=False),
|
changeset_name=dict(default=None, required=False),
|
||||||
role_arn=dict(default=None, required=False),
|
role_arn=dict(default=None, required=False),
|
||||||
tags=dict(default=None, type='dict')
|
tags=dict(default=None, type='dict'),
|
||||||
|
termination_protection=dict(default=None, type='bool')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -511,6 +552,8 @@ def main():
|
||||||
cfn.describe_stacks = backoff_wrapper(cfn.describe_stacks)
|
cfn.describe_stacks = backoff_wrapper(cfn.describe_stacks)
|
||||||
cfn.list_stack_resources = backoff_wrapper(cfn.list_stack_resources)
|
cfn.list_stack_resources = backoff_wrapper(cfn.list_stack_resources)
|
||||||
cfn.delete_stack = backoff_wrapper(cfn.delete_stack)
|
cfn.delete_stack = backoff_wrapper(cfn.delete_stack)
|
||||||
|
if boto_supports_termination_protection(cfn):
|
||||||
|
cfn.update_termination_protection = backoff_wrapper(cfn.update_termination_protection)
|
||||||
|
|
||||||
stack_info = get_stack_facts(cfn, stack_params['StackName'])
|
stack_info = get_stack_facts(cfn, stack_params['StackName'])
|
||||||
|
|
||||||
|
@ -530,6 +573,9 @@ def main():
|
||||||
elif module.params.get('create_changeset'):
|
elif module.params.get('create_changeset'):
|
||||||
result = create_changeset(module, stack_params, cfn)
|
result = create_changeset(module, stack_params, cfn)
|
||||||
else:
|
else:
|
||||||
|
if module.params.get('termination_protection') is not None:
|
||||||
|
update_termination_protection(module, cfn, stack_params['StackName'],
|
||||||
|
bool(module.params.get('termination_protection')))
|
||||||
result = update_stack(module, stack_params, cfn)
|
result = update_stack(module, stack_params, cfn)
|
||||||
|
|
||||||
# format the stack output
|
# format the stack output
|
||||||
|
|
Loading…
Reference in a new issue