From e1e5b6b47fba88124998eb26c15270464d3872b3 Mon Sep 17 00:00:00 2001 From: Alina Buzachis <49211501+alinabuzachis@users.noreply.github.com> Date: Wed, 7 Apr 2021 13:43:25 +0200 Subject: [PATCH] rds_instance: Add purge_security_groups (#500) * rds_instance: Add purge_security_groups feature for vpc_security_groups_ids. * Fixes: #385 This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/cd32e65ef1e01b5bc183f8298ecfb1d5c69394f8 --- .../500-rds_instance-purge-sg-option.yml | 2 + plugins/modules/rds_instance.py | 35 +++++++++++- .../tasks/test_vpc_security_groups.yml | 56 ++++++++++++++++++- 3 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/500-rds_instance-purge-sg-option.yml diff --git a/changelogs/fragments/500-rds_instance-purge-sg-option.yml b/changelogs/fragments/500-rds_instance-purge-sg-option.yml new file mode 100644 index 00000000000..77c103cf399 --- /dev/null +++ b/changelogs/fragments/500-rds_instance-purge-sg-option.yml @@ -0,0 +1,2 @@ +minor_changes: +- rds_instance - new ``purge_security_groups`` parameter (https://github.com/ansible-collections/community.aws/issues/385). diff --git a/plugins/modules/rds_instance.py b/plugins/modules/rds_instance.py index 8f3a7a39ae1..875a4fb9c34 100644 --- a/plugins/modules/rds_instance.py +++ b/plugins/modules/rds_instance.py @@ -416,6 +416,13 @@ - A list of EC2 VPC security groups to associate with the DB cluster. type: list elements: str + purge_security_groups: + description: + - Set to False to retain any enabled security groups that aren't specified in the task and are associated with the instance. + - Can be applied to I(vpc_security_group_ids) and I(db_security_groups) + type: bool + default: True + version_added: 1.5.0 ''' EXAMPLES = r''' @@ -451,6 +458,15 @@ id: "{{ instance_id }}" state: absent final_snapshot_identifier: "{{ snapshot_id }}" + +- name: Add a new security group without purge + community.aws.rds_instance: + id: "{{ instance_id }}" + state: present + vpc_security_group_ids: + - sg-0be17ba10c9286b0b + purge_security_groups: false + register: result ''' RETURN = r''' @@ -752,6 +768,7 @@ except ImportError: pass # caught by AnsibleAWSModule + from ansible.module_utils._text import to_text from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict from ansible.module_utils.six import string_types @@ -861,6 +878,7 @@ def get_options_with_changing_values(client, module, parameters): port = module.params['port'] apply_immediately = parameters.pop('ApplyImmediately', None) cloudwatch_logs_enabled = module.params['enable_cloudwatch_logs_exports'] + purge_security_groups = module.params['purge_security_groups'] if port: parameters['DBPortNumber'] = port @@ -872,7 +890,7 @@ def get_options_with_changing_values(client, module, parameters): parameters.pop('Iops', None) instance = get_instance(client, module, instance_id) - updated_parameters = get_changing_options_with_inconsistent_keys(parameters, instance, purge_cloudwatch_logs) + updated_parameters = get_changing_options_with_inconsistent_keys(parameters, instance, purge_cloudwatch_logs, purge_security_groups) updated_parameters.update(get_changing_options_with_consistent_keys(parameters, instance)) parameters = updated_parameters @@ -922,7 +940,7 @@ def get_current_attributes_with_inconsistent_keys(instance): return options -def get_changing_options_with_inconsistent_keys(modify_params, instance, purge_cloudwatch_logs): +def get_changing_options_with_inconsistent_keys(modify_params, instance, purge_cloudwatch_logs, purge_security_groups): changing_params = {} current_options = get_current_attributes_with_inconsistent_keys(instance) @@ -938,7 +956,12 @@ def get_changing_options_with_inconsistent_keys(modify_params, instance, purge_c # TODO: allow other purge_option module parameters rather than just checking for things to add if isinstance(current_option, list): if isinstance(desired_option, list): - if set(desired_option) <= set(current_option): + if ( + set(desired_option) < set(current_option) and + option in ('DBSecurityGroups', 'VpcSecurityGroupIds',) and purge_security_groups + ): + changing_params[option] = desired_option + elif set(desired_option) <= set(current_option): continue elif isinstance(desired_option, string_types): if desired_option in current_option: @@ -958,6 +981,11 @@ def get_changing_options_with_inconsistent_keys(modify_params, instance, purge_c format_option['DisableLogTypes'] = list(current_option.difference(desired_option)) if format_option['EnableLogTypes'] or format_option['DisableLogTypes']: changing_params[option] = format_option + elif option in ('DBSecurityGroups', 'VpcSecurityGroupIds',): + if purge_security_groups: + changing_params[option] = desired_option + else: + changing_params[option] = list(set(current_option) | set(desired_option)) else: changing_params[option] = desired_option @@ -1082,6 +1110,7 @@ def main(): purge_tags=dict(type='bool', default=True), read_replica=dict(type='bool'), wait=dict(type='bool', default=True), + purge_security_groups=dict(type='bool', default=True), ) parameter_options = dict( diff --git a/tests/integration/targets/rds_instance/tasks/test_vpc_security_groups.yml b/tests/integration/targets/rds_instance/tasks/test_vpc_security_groups.yml index f481b71fd72..940ce5b0fae 100644 --- a/tests/integration/targets/rds_instance/tasks/test_vpc_security_groups.yml +++ b/tests/integration/targets/rds_instance/tasks/test_vpc_security_groups.yml @@ -73,18 +73,70 @@ that: - result.changed - "result.db_instance_identifier == '{{ instance_id }}'" + - "result.vpc_security_groups | selectattr('status', 'in', ['active', 'adding']) | list | length == 2" - - name: Add a new security group + - name: Add a new security group without purge (check_mode) rds_instance: id: "{{ instance_id }}" state: present vpc_security_group_ids: - "{{ sgs_result.results.2.group_id }}" + apply_immediately: true + purge_security_groups: false + check_mode: true register: result - assert: that: - result.changed + - "result.db_instance_identifier == '{{ instance_id }}'" + + - name: Add a new security group without purge + rds_instance: + id: "{{ instance_id }}" + state: present + vpc_security_group_ids: + - "{{ sgs_result.results.2.group_id }}" + apply_immediately: true + purge_security_groups: false + register: result + + - assert: + that: + - result.changed + - "result.db_instance_identifier == '{{ instance_id }}'" + - "result.vpc_security_groups | selectattr('status', 'in', ['active', 'adding']) | list | length == 3" + + - name: Add a new security group without purge (test idempotence) + rds_instance: + id: "{{ instance_id }}" + state: present + vpc_security_group_ids: + - "{{ sgs_result.results.2.group_id }}" + apply_immediately: true + purge_security_groups: false + register: result + + - assert: + that: + - not result.changed + - "result.db_instance_identifier == '{{ instance_id }}'" + + - name: Add a security group with purge + rds_instance: + id: "{{ instance_id }}" + state: present + vpc_security_group_ids: + - "{{ sgs_result.results.2.group_id }}" + apply_immediately: true + register: result + + - assert: + that: + - result.changed + - "result.db_instance_identifier == '{{ instance_id }}'" + - "result.vpc_security_groups | selectattr('status', 'in', ['active', 'adding']) | list | length == 1" + - "result.vpc_security_groups | selectattr('status', 'equalto', 'removing') | list | length == 2" always: @@ -127,7 +179,7 @@ - {"cidr": "10.122.122.160/28", "zone": "{{ aws_region }}c"} - {"cidr": "10.122.122.176/28", "zone": "{{ aws_region }}d"} - - name: create a VPC + - name: Delete VPC ec2_vpc_net: name: "{{ resource_prefix }}-vpc" state: absent