diff --git a/lib/ansible/modules/cloud/amazon/ec2_vpc_route_table.py b/lib/ansible/modules/cloud/amazon/ec2_vpc_route_table.py index effc61026e..57d7893520 100644 --- a/lib/ansible/modules/cloud/amazon/ec2_vpc_route_table.py +++ b/lib/ansible/modules/cloud/amazon/ec2_vpc_route_table.py @@ -39,6 +39,20 @@ options: - "Enable route propagation from virtual gateways specified by ID." default: None required: false + purge_routes: + version_added: "2.3" + description: + - "Purge existing routes that are not found in routes." + required: false + default: 'true' + aliases: [] + purge_subnets: + version_added: "2.3" + description: + - "Purge existing subnets that are not found in subnets." + required: false + default: 'true' + aliases: [] route_table_id: description: - "The ID of the route table to update or delete." @@ -327,7 +341,7 @@ def index_of_matching_route(route_spec, routes_to_match): def ensure_routes(vpc_conn, route_table, route_specs, propagating_vgw_ids, - check_mode): + check_mode, purge_routes): routes_to_match = list(route_table.routes) route_specs_to_create = [] for route_spec in route_specs: @@ -344,13 +358,14 @@ def ensure_routes(vpc_conn, route_table, route_specs, propagating_vgw_ids, # The current logic will leave non-propagated routes using propagating # VGWs in place. routes_to_delete = [] - for r in routes_to_match: - if r.gateway_id: - if r.gateway_id != 'local' and not r.gateway_id.startswith('vpce-'): - if not propagating_vgw_ids or r.gateway_id not in propagating_vgw_ids: - routes_to_delete.append(r) - else: - routes_to_delete.append(r) + if purge_routes: + for r in routes_to_match: + if r.gateway_id: + if r.gateway_id != 'local' and not r.gateway_id.startswith('vpce-'): + if not propagating_vgw_ids or r.gateway_id not in propagating_vgw_ids: + routes_to_delete.append(r) + else: + routes_to_delete.append(r) changed = bool(routes_to_delete or route_specs_to_create) if changed: @@ -397,7 +412,7 @@ def ensure_subnet_association(vpc_conn, vpc_id, route_table_id, subnet_id, def ensure_subnet_associations(vpc_conn, vpc_id, route_table, subnets, - check_mode): + check_mode, purge_subnets): current_association_ids = [a.id for a in route_table.associations] new_association_ids = [] changed = False @@ -409,12 +424,13 @@ def ensure_subnet_associations(vpc_conn, vpc_id, route_table, subnets, return {'changed': True} new_association_ids.append(result['association_id']) - to_delete = [a_id for a_id in current_association_ids + if purge_subnets: + to_delete = [a_id for a_id in current_association_ids if a_id not in new_association_ids] - for a_id in to_delete: - changed = True - vpc_conn.disassociate_route_table(a_id, dry_run=check_mode) + for a_id in to_delete: + changed = True + vpc_conn.disassociate_route_table(a_id, dry_run=check_mode) return {'changed': changed} @@ -512,6 +528,8 @@ def ensure_route_table_present(connection, module): lookup = module.params.get('lookup') propagating_vgw_ids = module.params.get('propagating_vgw_ids') + purge_routes = module.params.get('purge_routes') + purge_subnets = module.params.get('purge_subnets') route_table_id = module.params.get('route_table_id') subnets = module.params.get('subnets') tags = module.params.get('tags') @@ -553,7 +571,9 @@ def ensure_route_table_present(connection, module): if routes is not None: try: - result = ensure_routes(connection, route_table, routes, propagating_vgw_ids, module.check_mode) + result = ensure_routes(connection, route_table, routes, + propagating_vgw_ids, module.check_mode, + purge_routes) changed = changed or result['changed'] except EC2ResponseError as e: module.fail_json(msg=e.message) @@ -580,7 +600,10 @@ def ensure_route_table_present(connection, module): ) try: - result = ensure_subnet_associations(connection, vpc_id, route_table, associated_subnets, module.check_mode) + result = ensure_subnet_associations(connection, vpc_id, route_table, + associated_subnets, + module.check_mode, + purge_subnets) changed = changed or result['changed'] except EC2ResponseError as e: raise AnsibleRouteTableException( @@ -597,6 +620,8 @@ def main(): dict( lookup = dict(default='tag', required=False, choices=['tag', 'id']), propagating_vgw_ids = dict(default=None, required=False, type='list'), + purge_routes=dict(default=True, type='bool'), + purge_subnets=dict(default=True, type='bool'), route_table_id = dict(default=None, required=False), routes = dict(default=[], required=False, type='list'), state = dict(default='present', choices=['present', 'absent']),