Repository: ansible-collections/amazon.aws

Issue:
 CreateVpcEndpoint operation: Route table IDs are only supported for Gateway type VPC Endpoint.
### Summary

I use `community.aws.ec2_vpc_endpoint` this module to create the `com.amazonaws.us-west-2.ec2` vpc endpoint and follow the [ansible document - community.aws.ec2_vpc_endpoint](https://docs.ansible.com/ansible/latest/collections/community/aws/ec2_vpc_endpoint_module.html#ec2-vpc-endpoint-module), but it's not working, like below from ansible documentation example.

```yaml
- name: Create new vpc endpoint with the default policy
  community.aws.ec2_vpc_endpoint:
    state: present
    region: ap-southeast-2
    vpc_id: vpc-12345678
    service: com.amazonaws.ap-southeast-2.s3
    route_table_ids:
      - rtb-12345678
      - rtb-87654321
  register: new_vpc_endpoint
```





### Issue Type

Bug Report

### Component Name

community.aws.ec2_vpc_endpoint 

### Ansible Version

```console (paste below)
$ ansible --version

ansible [core 2.11.6]
  config file = /work/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.8/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.8.10 (default, Sep 28 2021, 16:10:42) [GCC 9.3.0]
  jinja version = 3.0.3
  libyaml = True
```


### Collection Versions

```console (paste below)
$ ansible-galaxy collection list

# /usr/local/lib/python3.8/dist-packages/ansible_collections
Collection                    Version
----------------------------- -------
amazon.aws                    1.5.1
ansible.netcommon             2.4.0
ansible.posix                 1.3.0
ansible.utils                 2.4.2
ansible.windows               1.7.3
arista.eos                    2.2.0
awx.awx                       19.4.0
azure.azcollection            1.10.0
check_point.mgmt              2.1.1
chocolatey.chocolatey         1.1.0
cisco.aci                     2.1.0
cisco.asa                     2.1.0
cisco.intersight              1.0.17
cisco.ios                     2.5.0
cisco.iosxr                   2.5.0
cisco.meraki                  2.5.0
cisco.mso                     1.2.0
cisco.nso                     1.0.3
cisco.nxos                    2.7.0
cisco.ucs                     1.6.0
cloudscale_ch.cloud           2.2.0
community.aws                 1.5.0
community.azure               1.1.0
community.crypto              1.9.6
community.digitalocean        1.11.0
community.docker              1.10.0
community.fortios             1.0.0
community.general             3.8.1
community.google              1.0.0
community.grafana             1.2.3
community.hashi_vault         1.4.1
community.hrobot              1.2.0
community.kubernetes          1.2.1
community.kubevirt            1.0.0
community.libvirt             1.0.2
community.mongodb             1.3.1
community.mysql               2.3.1
community.network             3.0.0
community.okd                 1.1.2
community.postgresql          1.5.0
community.proxysql            1.3.0
community.rabbitmq            1.1.0
community.routeros            1.2.0
community.skydive             1.0.0
community.sops                1.1.0
community.vmware              1.15.0
community.windows             1.7.0
community.zabbix              1.5.0
containers.podman             1.8.1
cyberark.conjur               1.1.0
cyberark.pas                  1.0.7
dellemc.enterprise_sonic      1.1.0
dellemc.openmanage            3.6.0
dellemc.os10                  1.1.1
dellemc.os6                   1.0.7
dellemc.os9                   1.0.4
f5networks.f5_modules         1.12.0
fortinet.fortimanager         2.1.3
fortinet.fortios              2.1.2
frr.frr                       1.0.3
gluster.gluster               1.0.2
google.cloud                  1.0.2
hetzner.hcloud                1.6.0
hpe.nimble                    1.1.3
ibm.qradar                    1.0.3
infinidat.infinibox           1.2.4
inspur.sm                     1.3.0
junipernetworks.junos         2.6.0
kubernetes.core               1.2.1
mellanox.onyx                 1.0.0
netapp.aws                    21.6.0
netapp.azure                  21.9.0
netapp.cloudmanager           21.11.0
netapp.elementsw              21.6.1
netapp.ontap                  21.12.0
netapp.um_info                21.7.0
netapp_eseries.santricity     1.2.13
netbox.netbox                 3.3.0
ngine_io.cloudstack           2.2.2
ngine_io.exoscale             1.0.0
ngine_io.vultr                1.1.0
openstack.cloud               1.5.1
openvswitch.openvswitch       2.0.2
ovirt.ovirt                   1.6.4
purestorage.flasharray        1.11.0
purestorage.flashblade        1.7.0
sensu.sensu_go                1.12.0
servicenow.servicenow         1.0.6
splunk.es                     1.0.2
t_systems_mms.icinga_director 1.23.0
theforeman.foreman            2.2.0
vyos.vyos                     2.6.0
wti.remote                    1.0.1
```


### AWS SDK versions

```console (paste below)
$ pip show boto boto3 botocore

Name: boto
Version: 2.49.0
Summary: Amazon Web Services Library
Home-page: https://github.com/boto/boto/
Author: Mitch Garnaat
Author-email: mitch@garnaat.com
License: MIT
Location: /usr/local/lib/python3.8/dist-packages
Requires:
Required-by:
---
Name: boto3
Version: 1.20.12
Summary: The AWS SDK for Python
Home-page: https://github.com/boto/boto3
Author: Amazon Web Services
Author-email:
License: Apache License 2.0
Location: /usr/local/lib/python3.8/dist-packages
Requires: botocore, jmespath, s3transfer
Required-by:
---
Name: botocore
Version: 1.23.12
Summary: Low-level, data-driven core of boto 3.
Home-page: https://github.com/boto/botocore
Author: Amazon Web Services
Author-email:
License: Apache License 2.0
Location: /usr/local/lib/python3.8/dist-packages
Requires: jmespath, python-dateutil, urllib3
Required-by: boto3, s3transfer
```


### Configuration

```console (paste below)
$ ansible-config dump --only-changed

DEFAULT_HOST_LIST(/work/ansible.cfg) = ['/work/inventory/aws_ec2.yml']
DEFAULT_ROLES_PATH(/work/ansible.cfg) = ['/work/roles']
```


### OS / Environment

```console (paste below)
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.3 LTS
Release:	20.04
Codename:	focal
```

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)

- name: "Create VPC Endpoint"
  ec2_vpc_endpoint:
    region: "{{ aws_region }}"
    vpc_id: "{{ vpc_net.vpc.id }}"
    vpc_endpoint_type: "{{ item.Endpoint_type }}"
    service: "{{ item.Service }}"
    route_table_ids:
      - "{{ private_subnet_main_route.results[0].route_table.id }}"
      - "{{ private_subnet_main_route.results[1].route_table.id }}"
      - "{{ private_subnet_main_route.results[2].route_table.id }}"
    tags:
      Name: "{{ item.tagValue }}"
    state: "{{ state }}"
  loop:
    - { Endpoint_type: 'Interface', Service: "com.amazonaws.{{ aws_region }}.ec2", tagValue: 'EC2' }
```


### Expected Results


```yaml
- name: "Create VPC Endpoint"
  ec2_vpc_endpoint:
    region: "{{ aws_region }}"
    vpc_id: "{{ vpc_net.vpc.id }}"
    vpc_endpoint_type: "{{ item.Endpoint_type }}"
    service: "{{ item.Service }}"
    route_table_ids:
      - "{{ private_subnet_main_route.results[0].route_table.id }}"
      - "{{ private_subnet_main_route.results[1].route_table.id }}"
      - "{{ private_subnet_main_route.results[2].route_table.id }}"
    tags:
      Name: "{{ item.tagValue }}"
    state: "{{ state }}"
  loop:
    - { Endpoint_type: 'Interface', Service: "com.amazonaws.{{ aws_region }}.ec2", tagValue: 'EC2' }
```

btw, Is possible can support the choice `security group id`, because in AWS console that can choose the security group by user.

### Actual Results

```console (paste below)
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c 'echo ~root && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1637894276.0515084-32386-97836523424566 `" && echo ansible-tmp-1637894276.0515084-32386-97836523424566="` echo /root/.ansible/tmp/ansible-tmp-1637894276.0515084-32386-97836523424566 `" ) && sleep 0'
redirecting (type: modules) ansible.builtin.ec2_vpc_endpoint to community.aws.ec2_vpc_endpoint
Using module file /usr/local/lib/python3.8/dist-packages/ansible_collections/community/aws/plugins/modules/ec2_vpc_endpoint.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-31937124hjd64/tmpbxs2c7sv TO /root/.ansible/tmp/ansible-tmp-1637894276.0515084-32386-97836523424566/AnsiballZ_ec2_vpc_endpoint.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1637894276.0515084-32386-97836523424566/ /root/.ansible/tmp/ansible-tmp-1637894276.0515084-32386-97836523424566/AnsiballZ_ec2_vpc_endpoint.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1637894276.0515084-32386-97836523424566/AnsiballZ_ec2_vpc_endpoint.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1637894276.0515084-32386-97836523424566/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_ec2_vpc_endpoint_payload_3cc0p3_x/ansible_ec2_vpc_endpoint_payload.zip/ansible_collections/community/aws/plugins/modules/ec2_vpc_endpoint.py", line 366, in create_vpc_endpoint
  File "/tmp/ansible_ec2_vpc_endpoint_payload_3cc0p3_x/ansible_ec2_vpc_endpoint_payload.zip/ansible_collections/amazon/aws/plugins/module_utils/core.py", line 288, in deciding_wrapper
    return retrying_wrapper(*args, **kwargs)
  File "/tmp/ansible_ec2_vpc_endpoint_payload_3cc0p3_x/ansible_ec2_vpc_endpoint_payload.zip/ansible_collections/amazon/aws/plugins/module_utils/cloud.py", line 154, in retry_func
    raise e
  File "/tmp/ansible_ec2_vpc_endpoint_payload_3cc0p3_x/ansible_ec2_vpc_endpoint_payload.zip/ansible_collections/amazon/aws/plugins/module_utils/cloud.py", line 144, in retry_func
    return f(*args, **kwargs)
  File "/usr/local/lib/python3.8/dist-packages/botocore/client.py", line 391, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/usr/local/lib/python3.8/dist-packages/botocore/client.py", line 719, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (InvalidParameter) when calling the CreateVpcEndpoint operation: Route table IDs are only supported for Gateway type VPC Endpoint.
failed: [localhost] (item={'Endpoint_type': 'Interface', 'Service': 'com.amazonaws.us-west-2.ec2', 'tagValue': 'EC2'}) => {
    "ansible_loop_var": "item",
    "boto3_version": "1.20.12",
    "botocore_version": "1.23.12",
    "changed": false,
    "error": {
        "code": "InvalidParameter",
        "message": "Route table IDs are only supported for Gateway type VPC Endpoint."
    },
    "invocation": {
        "module_args": {
            "aws_access_key": null,
            "aws_ca_bundle": null,
            "aws_config": null,
            "aws_secret_key": null,
            "client_token": null,
            "debug_botocore_endpoint_logs": false,
            "ec2_url": null,
            "policy": null,
            "policy_file": null,
            "profile": null,
            "purge_tags": false,
            "region": "us-west-2",
            "route_table_ids": [
                "rtb-06f6616515eef5888",
                "rtb-0872dc0c821a00327",
                "rtb-0f74b1443db73337a"
            ],
            "security_token": null,
            "service": "com.amazonaws.us-west-2.ec2",
            "state": "present",
            "tags": {
                "Name": "EC2"
            },
            "validate_certs": true,
            "vpc_endpoint_id": null,
            "vpc_endpoint_type": "Interface",
            "vpc_id": "vpc-0ec64678a30309ee9",
            "wait": false,
            "wait_timeout": 320
        }
    },
    "item": {
        "Endpoint_type": "Interface",
        "Service": "com.amazonaws.us-west-2.ec2",
        "tagValue": "EC2"
    },
    "msg": "Failed to create VPC.: An error occurred (InvalidParameter) when calling the CreateVpcEndpoint operation: Route table IDs are only supported for Gateway type VPC Endpoint.",
    "response_metadata": {
        "http_headers": {
            "cache-control": "no-cache, no-store",
            "connection": "close",
            "content-type": "text/xml;charset=UTF-8",
            "date": "Fri, 26 Nov 2021 02:37:57 GMT",
            "server": "AmazonEC2",
            "strict-transport-security": "max-age=31536000; includeSubDomains",
            "transfer-encoding": "chunked",
            "vary": "accept-encoding",
            "x-amzn-requestid": "4e067ad3-0c90-4106-a6e2-7fa8ac9632ba"
        },
        "http_status_code": 400,
        "request_id": "4e067ad3-0c90-4106-a6e2-7fa8ac9632ba",
        "retry_attempts": 0
    }
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Hi @zarr12steven The API docs and that error do look like route table IDs are only valid for gateway type endpoints.  This would be a good documentation improvement, would you be interested in opening a PR to update the docs?

Resolving patch:
diff --git a/plugins/modules/ec2_vpc_endpoint.py b/plugins/modules/ec2_vpc_endpoint.py
--- a/plugins/modules/ec2_vpc_endpoint.py
+++ b/plugins/modules/ec2_vpc_endpoint.py
@@ -115,6 +115,7 @@
       - List of one or more route table ids to attach to the endpoint. A route
         is added to the route table with the destination of the endpoint if
         provided.
+      - Route table ids are only valid for gateway type endpoints.
     required: false
     type: list
     elements: str
@@ -309,6 +310,9 @@ def create_vpc_endpoint(client, module):
     params['VpcEndpointType'] = module.params.get('vpc_endpoint_type')
     params['ServiceName'] = module.params.get('service')
 
+    if module.params.get('vpc_endpoint_type') != 'Gateway' and module.params.get('route_table_ids'):
+        module.fail_json(msg="Route table IDs are only supported for Gateway type VPC Endpoint.")
+
     if module.check_mode:
         changed = True
         result = 'Would have created VPC Endpoint if not in check mode'


Test patch: