Repository: ansible-collections/amazon.aws

Issue:
IPv6 support in ec2_vpc_route_table
<!--- Verify first that your feature was not already discussed on GitHub -->
<!--- Complete *all* sections as described, this form is processed automatically -->

##### SUMMARY
Allow usage of IPv6 CIDR in `ec2_vpc_route_table`.

##### ISSUE TYPE
- Feature Idea

##### COMPONENT NAME
<!--- Write the short name of the module, plugin, task or feature below, use your best guess if unsure -->
ec2_vpc_route_table.py

##### ADDITIONAL INFORMATION
<!--- Describe how the feature would be used, why it is needed and what it would solve -->
An old PR tried to fix it already: https://github.com/ansible/ansible/pull/50220.
This would solve the error that occurs when we use an IPv6 CIDR.

```
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: botocore.exceptions.ClientError: An error occurred (InvalidParameterValue) when calling the CreateRoute operation: Value (::/0) for parameter destinationCidrBlock is invalid. This is not a valid CIDR block.
fatal: [localhost]: FAILED! => {"boto3_version": "1.17.3", "botocore_version": "1.20.3", "changed": false, "error": {"code": "InvalidParameterValue", "message": "Value (::/0) for parameter destinationCidrBlock is invalid. This is not a valid CIDR block."}, "msg": "Couldn't create route: An error occurred (InvalidParameterValue) when calling the CreateRoute operation: Value (::/0) for parameter destinationCidrBlock is invalid. This is not a valid CIDR block.", "response_metadata": {"http_headers": {"cache-control": "no-cache, no-store", "connection": "close", "date": "Wed, 10 Feb 2021 08:07:32 GMT", "server": "AmazonEC2", "strict-transport-security": "max-age=31536000; includeSubDomains", "transfer-encoding": "chunked", "x-amzn-requestid": "42c90a54-5eb3-42fd-a993-6c73cfccbe0f"}, "http_status_code": 400, "request_id": "42c90a54-5eb3-42fd-a993-6c73cfccbe0f", "retry_attempts": 0}}
```

<!--- Paste example playbooks or commands between quotes below -->
```yaml
  ec2_vpc_route_table:
      routes:
        - dest: 0.0.0.0/0
          gateway_id: gw-id
        - dest: ::/0
          gateway_id: gw-id
      subnets:
        - subnet-1
        - subnet-2
        - subnet-3
      vpc_id: vpc-id
```

<!--- HINT: You can also paste gist.github.com links for larger files -->



Discussion:
Files identified in the description:
* [`plugins/modules/ec2_vpc_route_table.py`](https://github.com/['ansible-collections/amazon.aws', 'ansible-collections/community.aws', 'ansible-collections/community.vmware']/blob/main/plugins/modules/ec2_vpc_route_table.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @jillr @s-hertel @tremble @willthames @wimnat
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
@jillr it seems that you are working on this module, could you please address this issue too ? 

Resolving patch:
diff --git a/plugins/modules/ec2_vpc_route_table.py b/plugins/modules/ec2_vpc_route_table.py
--- a/plugins/modules/ec2_vpc_route_table.py
+++ b/plugins/modules/ec2_vpc_route_table.py
@@ -226,6 +226,7 @@
 
 import re
 from time import sleep
+from ipaddress import ip_network
 
 try:
     import botocore
@@ -408,7 +409,7 @@ def ensure_routes(connection=None, module=None, route_table=None, route_specs=No
     for route_spec in route_specs:
         match = index_of_matching_route(route_spec, routes_to_match)
         if match is None:
-            if route_spec.get('DestinationCidrBlock'):
+            if route_spec.get('DestinationCidrBlock') or route_spec.get('DestinationIpv6CidrBlock'):
                 route_specs_to_create.append(route_spec)
             else:
                 module.warn("Skipping creating {0} because it has no destination cidr block. "
@@ -588,9 +589,13 @@ def get_route_table_info(connection, module, route_table):
 
 def create_route_spec(connection, module, vpc_id):
     routes = module.params.get('routes')
-
     for route_spec in routes:
-        rename_key(route_spec, 'dest', 'destination_cidr_block')
+
+        cidr_block_type = str(type(ip_network(route_spec['dest'])))
+        if "IPv4" in cidr_block_type:
+            rename_key(route_spec, 'dest', 'destination_cidr_block')
+        if "IPv6" in cidr_block_type:
+            rename_key(route_spec, 'dest', 'destination_ipv6_cidr_block')
 
         if route_spec.get('gateway_id') and route_spec['gateway_id'].lower() == 'igw':
             igw = find_igw(connection, module, vpc_id)


Test patch:
diff --git a/tests/integration/targets/ec2_vpc_route_table/tasks/main.yml b/tests/integration/targets/ec2_vpc_route_table/tasks/main.yml
--- a/tests/integration/targets/ec2_vpc_route_table/tasks/main.yml
+++ b/tests/integration/targets/ec2_vpc_route_table/tasks/main.yml
@@ -131,6 +131,8 @@
       routes:
       - dest: 0.0.0.0/0
         gateway_id: igw
+      - dest: ::/0
+        gateway_id: igw
     check_mode: true
     register: check_mode_results
   - name: assert a route would be added
@@ -147,16 +149,18 @@
       routes:
       - dest: 0.0.0.0/0
         gateway_id: igw
+      - dest: ::/0
+        gateway_id: igw
     register: add_routes
   - name: assert route table contains new route
     assert:
       that:
       - add_routes.changed
-      - add_routes.route_table.routes|length == 2
+      - add_routes.route_table.routes|length == 3
       - add_routes.route_table.id.startswith('rtb-')
       - "'Public' in add_routes.route_table.tags and add_routes.route_table.tags['Public']\
         \ == 'true'"
-      - add_routes.route_table.routes|length == 2
+      - add_routes.route_table.routes|length == 3
       - add_routes.route_table.associations|length == 0
       - add_routes.route_table.vpc_id == "{{ vpc.vpc.id }}"
       - add_routes.route_table.propagating_vgws|length == 0
@@ -191,7 +195,7 @@
     assert:
       that:
       - add_routes is not changed
-      - add_routes.route_table.routes|length == 2
+      - add_routes.route_table.routes|length == 3
 
   - name: CHECK MODE - add subnets to public route table
     ec2_vpc_route_table:
@@ -265,7 +269,7 @@
     assert:
       that:
       - not no_purge_routes.changed
-      - no_purge_routes.route_table.routes|length == 2
+      - no_purge_routes.route_table.routes|length == 3
       - no_purge_routes.route_table.associations|length == 2
 
   - name: rerun with purge_subnets set to false
@@ -283,7 +287,7 @@
     assert:
       that:
       - not no_purge_subnets.changed
-      - no_purge_subnets.route_table.routes|length == 2
+      - no_purge_subnets.route_table.routes|length == 3
       - no_purge_subnets.route_table.associations|length == 2
 
   - name: rerun with purge_tags not set (implicitly false)
@@ -428,7 +432,7 @@
     assert:
       that:
       - purge_routes.changed
-      - purge_routes.route_table.routes|length == 1
+      - purge_routes.route_table.routes|length == 2
       - purge_routes.route_table.id == create_public_table.route_table.id
 
   - name: CHECK MODE - update tags