From 99078659caf42bdd3c9c8cd17b8dce2748bc5130 Mon Sep 17 00:00:00 2001 From: Frank van Tol Date: Thu, 11 Mar 2021 11:28:33 +0100 Subject: [PATCH] feat: support for StackPolicyDuringUpdateBody (#155) * feat: support for StackPolicyDuringUpdateBody * Create 155-support-for-StackPolicyDuringUpdateBody.yaml * Added stack_policy_body to migrate away from file reading * Enable tests Co-authored-by: Mark Chappell --- ...pport-for-StackPolicyDuringUpdateBody.yaml | 2 + plugins/modules/cloudformation.py | 22 +++++++++- .../cloudformation/files/update_policy.json | 10 +++++ .../targets/cloudformation/tasks/main.yml | 40 +++++++++++++++++++ 4 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/155-support-for-StackPolicyDuringUpdateBody.yaml create mode 100644 tests/integration/targets/cloudformation/files/update_policy.json diff --git a/changelogs/fragments/155-support-for-StackPolicyDuringUpdateBody.yaml b/changelogs/fragments/155-support-for-StackPolicyDuringUpdateBody.yaml new file mode 100644 index 00000000000..97f29a184cd --- /dev/null +++ b/changelogs/fragments/155-support-for-StackPolicyDuringUpdateBody.yaml @@ -0,0 +1,2 @@ +minor_changes: + - cloudformation - added support for StackPolicyDuringUpdateBody (https://github.com/ansible-collections/amazon.aws/pull/155). diff --git a/plugins/modules/cloudformation.py b/plugins/modules/cloudformation.py index 030bfc45524..76fb55f19b7 100644 --- a/plugins/modules/cloudformation.py +++ b/plugins/modules/cloudformation.py @@ -72,9 +72,20 @@ type: str stack_policy: description: - - The path of the CloudFormation stack policy. A policy cannot be removed once placed, but it can be modified. + - The path of the file containing the CloudFormation stack policy. A policy cannot be removed once placed, but it can be modified. for instance, allow all updates U(https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/protect-stack-resources.html#d0e9051) type: str + stack_policy_body: + description: + - The CloudFormation stack policy in JSON. A policy cannot be removed once placed, but it can be modified. + for instance, allow all updates U(https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/protect-stack-resources.html#d0e9051) + type: json + version_added: 1.5.0 + stack_policy_on_update_body: + description: + - the body of the cloudformation stack policy only applied during this update. + type: json + version_added: 1.5.0 tags: description: - Dictionary of tags to associate with stack and its resources during stack creation. @@ -471,6 +482,9 @@ def update_stack(module, stack_params, cfn, events_limit): if 'TemplateBody' not in stack_params and 'TemplateURL' not in stack_params: stack_params['UsePreviousTemplate'] = True + if module.params['stack_policy_on_update_body'] is not None: + stack_params['StackPolicyDuringUpdateBody'] = module.params['stack_policy_on_update_body'] + # if the state is present and the stack already exists, we try to update it. # AWS will tell us if the stack template and parameters are the same and # don't need to be updated. @@ -628,6 +642,8 @@ def main(): template=dict(default=None, required=False, type='path'), notification_arns=dict(default=None, required=False), stack_policy=dict(default=None, required=False), + stack_policy_body=dict(default=None, required=False, type='json'), + stack_policy_on_update_body=dict(default=None, required=False, type='json'), disable_rollback=dict(default=False, type='bool'), on_create_failure=dict(default=None, required=False, choices=['DO_NOTHING', 'ROLLBACK', 'DELETE']), create_timeout=dict(default=None, type='int'), @@ -685,7 +701,9 @@ def main(): stack_params['NotificationARNs'] = [] # can't check the policy when verifying. - if module.params['stack_policy'] is not None and not module.check_mode and not module.params['create_changeset']: + if module.params['stack_policy_body'] is not None and not module.check_mode and not module.params['create_changeset']: + stack_params['StackPolicyBody'] = module.params['stack_policy_body'] + elif module.params['stack_policy'] is not None and not module.check_mode and not module.params['create_changeset']: with open(module.params['stack_policy'], 'r') as stack_policy_fh: stack_params['StackPolicyBody'] = stack_policy_fh.read() diff --git a/tests/integration/targets/cloudformation/files/update_policy.json b/tests/integration/targets/cloudformation/files/update_policy.json new file mode 100644 index 00000000000..6a35138257b --- /dev/null +++ b/tests/integration/targets/cloudformation/files/update_policy.json @@ -0,0 +1,10 @@ +{ + "Statement" : [ + { + "Effect" : "Allow", + "Action" : "Update:*", + "Principal": "*", + "Resource" : "*" + } + ] +} diff --git a/tests/integration/targets/cloudformation/tasks/main.yml b/tests/integration/targets/cloudformation/tasks/main.yml index 9b89722b20f..cc21d64ed74 100644 --- a/tests/integration/targets/cloudformation/tasks/main.yml +++ b/tests/integration/targets/cloudformation/tasks/main.yml @@ -363,6 +363,46 @@ that: - "not stack_info.cloudformation[stack_name].stack_description.enable_termination_protection" + # ==== Cloudformation tests (update_policy) ====================== + + - name: setting an stack policy with json body + cloudformation: + stack_name: "{{ stack_name }}" + stack_policy_body: "{{ lookup('file','update_policy.json') }}" + template_body: "{{ lookup('file','cf_template.json') }}" + template_parameters: + InstanceType: "t3.nano" + ImageId: "{{ ec2_ami_image }}" + SubnetId: "{{ testing_subnet.subnet.id }}" + tags: + Stack: "{{ stack_name }}" + test: "{{ resource_prefix }}" + register: cf_stack + + - name: get stack details + cloudformation_info: + stack_name: "{{ stack_name }}" + register: stack_info + + - name: setting an stack policy on update + cloudformation: + stack_name: "{{ stack_name }}" + stack_policy_on_update_body: "{{ lookup('file','update_policy.json') }}" + template_body: "{{ lookup('file','cf_template.json') }}" + template_parameters: + InstanceType: "t3.nano" + ImageId: "{{ ec2_ami_image }}" + SubnetId: "{{ testing_subnet.subnet.id }}" + tags: + Stack: "{{ stack_name }}" + test: "{{ resource_prefix }}" + register: cf_stack + + - name: get stack details + cloudformation_info: + stack_name: "{{ stack_name }}" + register: stack_info + # ==== Cloudformation tests (delete stack tests) ========================== - name: delete cloudformation stack (check mode)