diff --git a/cloud/amazon/ec2_vpc_nat_gateway.py b/cloud/amazon/ec2_vpc_nat_gateway.py
new file mode 100644
index 00000000000..9b1fb235a61
--- /dev/null
+++ b/cloud/amazon/ec2_vpc_nat_gateway.py
@@ -0,0 +1,930 @@
+#!/usr/bin/python
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
+
+DOCUMENTATION = '''
+---
+module: ec2_vpc_nat_gateway
+short_description: Manage AWS VPC NAT Gateways
+description:
+  - Ensure the state of AWS VPC NAT Gateways based on their id, allocation and subnet ids.
+version_added: "2.1"
+requirements: [boto3, botocore]
+options:
+  state:
+    description:
+      - Ensure NAT Gateway is present or absent
+    required: false
+    default: "present"
+    choices: ["present", "absent"]
+  nat_gateway_id:
+    description:
+      - The id AWS dynamically allocates to the NAT Gateway on creation.
+        This is required when the absent option is present.
+    required: false
+    default: None
+  subnet_id:
+    description:
+      - The id of the subnet to create the NAT Gateway in. This is required
+        with the present option.
+    required: false
+    default: None
+  allocation_id:
+    description:
+      - The id of the elastic IP allocation. If this is not passed and the
+        eip_address is not passed. An EIP is generated for this Nat Gateway
+    required: false
+    default: None
+  eip_address:
+    description:
+      - The elasti ip address of the EIP you want attached to this Nat Gateway.
+        If this is not passed and the allocation_id is not passed.
+        An EIP is generated for this Nat Gateway
+    required: false
+  if_exist_do_not_create:
+    description:
+      - if a Nat Gateway exists already in the subnet_id, then do not create a new one.
+    required: false
+    default: false
+  release_eip:
+    description:
+      - Deallocate the EIP from the VPC.
+      - Option is only valid with the absent state.
+    required: false
+    default: true
+  wait:
+    description:
+      - Wait for operation to complete before returning
+    required: false
+    default: true
+  wait_timeout:
+    description:
+      - How many seconds to wait for an operation to complete before timing out
+    required: false
+    default: 300
+  client_token:
+    description:
+      - Optional unique token to be used during create to ensure idempotency.
+        When specifying this option, ensure you specify the eip_address parameter
+        as well otherwise any subsequent runs will fail.
+    required: false
+
+author:
+  - "Allen Sanabria (@linuxdynasty)"
+  - "Jon Hadfield (@jonhadfield)"
+  - "Karen Cheng(@Etherdaemon)"
+extends_documentation_fragment:
+  - aws
+  - ec2
+'''
+
+EXAMPLES = '''
+# Note: These examples do not set authentication details, see the AWS Guide for details.
+
+- name: Create new nat gateway with client token
+  ec2_vpc_nat_gateway:
+  state: present
+  subnet_id: subnet-12345678
+  eip_address: 52.1.1.1
+  region: ap-southeast-2
+  client_token: abcd-12345678
+  register: new_nat_gateway
+
+- name: Create new nat gateway allocation-id
+  ec2_vpc_nat_gateway:
+    state: present
+    subnet_id: subnet-12345678
+    allocation_id: eipalloc-12345678
+    region: ap-southeast-2
+  register: new_nat_gateway
+
+- name: Create new nat gateway with when condition
+  ec2_vpc_nat_gateway:
+    state: present
+    subnet_id: subnet-12345678
+    eip_address: 52.1.1.1
+    region: ap-southeast-2
+  register: new_nat_gateway
+  when: existing_nat_gateways.result == []
+
+- name: Create new nat gateway and wait for available status
+  ec2_vpc_nat_gateway:
+    state: present
+    subnet_id: subnet-12345678
+    eip_address: 52.1.1.1
+    wait: yes
+    region: ap-southeast-2
+  register: new_nat_gateway
+
+- name: Create new nat gateway and allocate new eip
+  ec2_vpc_nat_gateway:
+    state: present
+    subnet_id: subnet-12345678
+    wait: yes
+    region: ap-southeast-2
+  register: new_nat_gateway
+
+- name: Create new nat gateway and allocate new eip if a nat gateway does not yet exist in the subnet.
+  ec2_vpc_nat_gateway:
+    state: present
+    subnet_id: subnet-12345678
+    wait: yes
+    region: ap-southeast-2
+    if_exist_do_not_create: true
+  register: new_nat_gateway
+
+- name: Delete nat gateway using discovered nat gateways from facts module
+  ec2_vpc_nat_gateway:
+    state: absent
+    region: ap-southeast-2
+    wait: yes
+    nat_gateway_id: "{{ item.NatGatewayId }}"
+    release_eip: yes
+  register: delete_nat_gateway_result
+  with_items: "{{ gateways_to_remove.result }}"
+
+- name: Delete nat gateway and wait for deleted status
+  ec2_vpc_nat_gateway:
+    state: absent
+    nat_gateway_id: nat-12345678
+    wait: yes
+    wait_timeout: 500
+    region: ap-southeast-2
+
+- name: Delete nat gateway and release EIP
+  ec2_vpc_nat_gateway:
+    state: absent
+    nat_gateway_id: nat-12345678
+    release_eip: yes
+    region: ap-southeast-2
+'''
+
+RETURN = '''
+create_time:
+  description: The ISO 8601 date time formatin UTC.
+  returned: In all cases.
+  type: string
+  sample: "2016-03-05T05:19:20.282000+00:00'"
+nat_gateway_id:
+  description: id of the VPC NAT Gateway
+  returned: In all cases.
+  type: string
+  sample: "nat-0d1e3a878585988f8"
+subnet_id:
+  description: id of the Subnet
+  returned: In all cases.
+  type: string
+  sample: "subnet-12345"
+state:
+  description: The current state of the Nat Gateway.
+  returned: In all cases.
+  type: string
+  sample: "available"
+vpc_id:
+  description: id of the VPC.
+  returned: In all cases.
+  type: string
+  sample: "vpc-12345"
+nat_gateway_addresses:
+  description: List of dictionairies containing the public_ip, network_interface_id, private_ip, and allocation_id.
+  returned: In all cases.
+  type: string
+  sample: [
+      {
+          'public_ip': '52.52.52.52',
+          'network_interface_id': 'eni-12345',
+          'private_ip': '10.0.0.100',
+          'allocation_id': 'eipalloc-12345'
+      }
+  ]
+'''
+
+try:
+    import botocore
+    import boto3
+    HAS_BOTO3 = True
+except ImportError:
+    HAS_BOTO3 = False
+
+import time
+import datetime
+
+def convert_to_lower(data):
+    """Convert all uppercase keys in dict with lowercase_
+    Args:
+        data (dict): Dictionary with keys that have upper cases in them
+            Example.. NatGatewayAddresses == nat_gateway_addresses
+            if a val is of type datetime.datetime, it will be converted to
+            the ISO 8601
+
+    Basic Usage:
+        >>> test = {'NatGatewaysAddresses': []}
+        >>> test = convert_to_lower(test)
+        {
+            'nat_gateways_addresses': []
+        }
+
+    Returns:
+        Dictionary
+    """
+    results = dict()
+    for key, val in data.items():
+        key = re.sub('([A-Z]{1})', r'_\1', key).lower()[1:]
+        if isinstance(val, datetime.datetime):
+            results[key] = val.isoformat()
+        else:
+            results[key] = val
+    return results
+
+def formatted_nat_gw_output(data):
+    """Format the results of NatGateways into lowercase with underscores.
+    Args:
+        data (list): List of dictionaries with keys that have upper cases in
+            them. Example.. NatGatewayAddresses == nat_gateway_addresses
+            if a val is of type datetime.datetime, it will be converted to
+            the ISO 8601
+
+    Basic Usage:
+        >>> test = [
+            {
+                'VpcId': 'vpc-12345',
+                'State': 'available',
+                'NatGatewayId': 'nat-0b2f9f2ac3f51a653',
+                'SubnetId': 'subnet-12345',
+                'NatGatewayAddresses': [
+                    {
+                        'PublicIp': '52.52.52.52',
+                        'NetworkInterfaceId': 'eni-12345',
+                        'AllocationId': 'eipalloc-12345',
+                        'PrivateIp': '10.0.0.100'
+                    }
+                ],
+                'CreateTime': datetime.datetime(2016, 3, 5, 5, 19, 20, 282000, tzinfo=tzutc())
+            }
+        ]
+        >>> test = formatted_nat_gw_output(test)
+            [
+                {
+                    'nat_gateway_id': 'nat-0b2f9f2ac3f51a653',
+                    'subnet_id': 'subnet-12345',
+                    'nat_gateway_addresses': [
+                        {
+                            'public_ip': '52.52.52.52',
+                            'network_interface_id': 'eni-12345',
+                            'private_ip': '10.0.0.100',
+                            'allocation_id': 'eipalloc-12345'
+                        }
+                    ],
+                    'state': 'available',
+                    'create_time': '2016-03-05T05:19:20.282000+00:00',
+                    'vpc_id': 'vpc-12345'
+                }
+            ]
+
+    Returns:
+        List
+    """
+    results = list()
+    for gw in data:
+        output = dict()
+        ng_addresses = gw.pop('NatGatewayAddresses')
+        output = convert_to_lower(gw)
+        output['nat_gateway_addresses'] = []
+        for address in ng_addresses:
+            gw_data = convert_to_lower(address)
+            output['nat_gateway_addresses'].append(gw_data)
+        results.append(output)
+
+    return results
+
+def get_nat_gateways(client, subnet_id=None, nat_gateway_id=None):
+    """Retrieve a list of NAT Gateways
+    Args:
+        client (botocore.client.EC2): Boto3 client
+
+    Kwargs:
+        subnet_id (str): The subnet_id the nat resides in.
+        nat_gateway_id (str): The Amazon nat id.
+
+    Basic Usage:
+        >>> client = boto3.client('ec2')
+        >>> subnet_id = 'subnet-w4t12897'
+        >>> get_nat_gateways(client, subnet_id)
+        [
+            true,
+            "",
+            {
+                "nat_gateway_id": "nat-03835afb6e31df79b",
+                "subnet_id": "subnet-w4t12897",
+                "nat_gateway_addresses": [
+                    {
+                        "public_ip": "52.87.29.36",
+                        "network_interface_id": "eni-5579742d",
+                        "private_ip": "10.0.0.102",
+                        "allocation_id": "eipalloc-36014da3"
+                    }
+                ],
+                "state": "deleted",
+                "create_time": "2016-03-05T00:33:21.209000+00:00",
+                "delete_time": "2016-03-05T00:36:37.329000+00:00",
+                "vpc_id": "vpc-w68571b5"
+            }
+
+    Returns:
+        Tuple (bool, str, list)
+    """
+    params = dict()
+    err_msg = ""
+    gateways_retrieved = False
+    if nat_gateway_id:
+        params['NatGatewayIds'] = [nat_gateway_id]
+    else:
+        params['Filter'] = [
+            {
+                'Name': 'subnet-id',
+                'Values': [subnet_id]
+            }
+        ]
+
+    try:
+        gateways = client.describe_nat_gateways(**params)['NatGateways']
+        existing_gateways = formatted_nat_gw_output(gateways)
+        gateways_retrieved = True
+    except botocore.exceptions.ClientError as e:
+        err_msg = str(e)
+
+    return gateways_retrieved, err_msg, existing_gateways
+
+def wait_for_status(client, wait_timeout, nat_gateway_id, status):
+    """Wait for the Nat Gateway to reach a status
+    Args:
+        client (botocore.client.EC2): Boto3 client
+        wait_timeout (int): Number of seconds to wait, until this timeout is reached.
+        nat_gateway_id (str): The Amazon nat id.
+        status (str): The status to wait for.
+            examples. status=available, status=deleted
+
+    Basic Usage:
+        >>> client = boto3.client('ec2')
+        >>> subnet_id = 'subnet-w4t12897'
+        >>> allocation_id = 'eipalloc-36014da3'
+        >>> wait_for_status(client, subnet_id, allocation_id)
+        [
+            true,
+            "",
+            {
+                "nat_gateway_id": "nat-03835afb6e31df79b",
+                "subnet_id": "subnet-w4t12897",
+                "nat_gateway_addresses": [
+                    {
+                        "public_ip": "52.87.29.36",
+                        "network_interface_id": "eni-5579742d",
+                        "private_ip": "10.0.0.102",
+                        "allocation_id": "eipalloc-36014da3"
+                    }
+                ],
+                "state": "deleted",
+                "create_time": "2016-03-05T00:33:21.209000+00:00",
+                "delete_time": "2016-03-05T00:36:37.329000+00:00",
+                "vpc_id": "vpc-w68571b5"
+            }
+        ]
+
+    Returns:
+        Tuple (bool, str, list)
+    """
+    polling_increment_secs = 5
+    wait_timeout = time.time() + wait_timeout
+    status_achieved = False
+    nat_gateway = list()
+    err_msg = ""
+
+    while wait_timeout > time.time():
+        try:
+            gws_retrieved, err_msg, nat_gateway = (
+                get_nat_gateways(client, nat_gateway_id=nat_gateway_id)
+            )
+            if gws_retrieved and nat_gateway:
+                if nat_gateway[0].get('state') == status:
+                    status_achieved = True
+                    break
+
+                elif nat_gateway[0].get('state') == 'failed':
+                    err_msg = nat_gateway[0].get('failure_message')
+                    break
+
+            else:
+                time.sleep(polling_increment_secs)
+        except botocore.exceptions.ClientError as e:
+            err_msg = str(e)
+
+    if not status_achieved:
+        err_msg = "Wait time out reached, while waiting for results"
+
+    return status_achieved, err_msg, nat_gateway
+
+def gateway_in_subnet_exists(client, subnet_id, allocation_id=None):
+    """Retrieve all NAT Gateways for a subnet.
+    Args:
+        subnet_id (str): The subnet_id the nat resides in.
+
+    Kwargs:
+        allocation_id (str): The eip Amazon identifier.
+            default = None
+
+    Basic Usage:
+        >>> client = boto3.client('ec2')
+        >>> subnet_id = 'subnet-w4t12897'
+        >>> allocation_id = 'eipalloc-36014da3'
+        >>> gateway_in_subnet_exists(client, subnet_id, allocation_id)
+        (
+            [
+                {
+                    "nat_gateway_id": "nat-03835afb6e31df79b",
+                    "subnet_id": "subnet-w4t12897",
+                    "nat_gateway_addresses": [
+                        {
+                            "public_ip": "52.87.29.36",
+                            "network_interface_id": "eni-5579742d",
+                            "private_ip": "10.0.0.102",
+                            "allocation_id": "eipalloc-36014da3"
+                        }
+                    ],
+                    "state": "deleted",
+                    "create_time": "2016-03-05T00:33:21.209000+00:00",
+                    "delete_time": "2016-03-05T00:36:37.329000+00:00",
+                    "vpc_id": "vpc-w68571b5"
+                }
+            ],
+            False
+        )
+
+    Returns:
+        Tuple (list, bool)
+    """
+    allocation_id_exists = False
+    gateways = []
+    gws_retrieved, _, gws = get_nat_gateways(client, subnet_id)
+    if not gws_retrieved:
+        return gateways, allocation_id_exists
+    for gw in gws:
+        for address in gw['nat_gateway_addresses']:
+            if gw.get('state') == 'available' or gw.get('state') == 'pending':
+                if allocation_id:
+                    if address.get('allocation_id') == allocation_id:
+                        allocation_id_exists = True
+                        gateways.append(gw)
+                else:
+                    gateways.append(gw)
+
+    return gateways, allocation_id_exists
+
+def get_eip_allocation_id_by_address(client, eip_address, check_mode=False):
+    """Release an EIP from your EIP Pool
+    Args:
+        client (botocore.client.EC2): Boto3 client
+        eip_address (str): The Elastic IP Address of the EIP.
+
+    Kwargs:
+        check_mode (bool): if set to true, do not run anything and
+            falsify the results.
+
+    Basic Usage:
+        >>> client = boto3.client('ec2')
+        >>> eip_address = '52.87.29.36'
+        >>> get_eip_allocation_id_by_address(client, eip_address)
+        'eipalloc-36014da3'
+
+    Returns:
+        Tuple (str, str)
+    """
+    params = {
+        'PublicIps': [eip_address]
+    }
+    allocation_id = None
+    err_msg = ""
+    if check_mode:
+        return "eipalloc-123456", err_msg
+    try:
+        allocation = client.describe_addresses(**params)['Addresses'][0]
+        if not allocation.get('Domain') != 'vpc':
+            err_msg = (
+                "EIP provided is a non-VPC EIP, please allocate a VPC scoped EIP"
+            )
+        else:
+            allocation_id = allocation.get('AllocationId')
+    except botocore.exceptions.ClientError as e:
+        err_msg = str(e)
+
+    return allocation_id, err_msg
+
+def allocate_eip_address(client, check_mode=False):
+    """Release an EIP from your EIP Pool
+    Args:
+        client (botocore.client.EC2): Boto3 client
+
+    Kwargs:
+        check_mode (bool): if set to true, do not run anything and
+            falsify the results.
+
+    Basic Usage:
+        >>> client = boto3.client('ec2')
+        >>> allocate_eip_address(client)
+        True
+
+    Returns:
+        Tuple (bool, str)
+    """
+    if check_mode:
+        return True, "eipalloc-123456"
+
+    ip_allocated = False
+    params = {
+        'Domain': 'vpc'
+    }
+    try:
+        new_eip = client.allocate_address(**params)
+        ip_allocated = True
+    except botocore.exceptions.ClientError:
+        pass
+
+    return ip_allocated, new_eip['AllocationId']
+
+def release_address(client, allocation_id, check_mode=False):
+    """Release an EIP from your EIP Pool
+    Args:
+        client (botocore.client.EC2): Boto3 client
+        allocation_id (str): The eip Amazon identifier.
+
+    Kwargs:
+        check_mode (bool): if set to true, do not run anything and
+            falsify the results.
+
+    Basic Usage:
+        >>> client = boto3.client('ec2')
+        >>> allocation_id = "eipalloc-123456"
+        >>> release_address(client, allocation_id)
+        True
+
+    Returns:
+        Boolean
+    """
+    if check_mode:
+        return True
+
+    ip_released = False
+    params = {
+        'AllocationId': allocation_id,
+    }
+    try:
+        client.release_address(**params)
+        ip_released = True
+    except botocore.exceptions.ClientError:
+        pass
+
+    return ip_released
+
+def create(client, subnet_id, allocation_id, client_token=None,
+           wait=False, wait_timeout=0, if_exist_do_not_create=False):
+    """Create an Amazon NAT Gateway.
+    Args:
+        client (botocore.client.EC2): Boto3 client
+        subnet_id (str): The subnet_id the nat resides in.
+        allocation_id (str): The eip Amazon identifier.
+
+    Kwargs:
+        if_exist_do_not_create (bool): if a nat gateway already exists in this
+            subnet, than do not create another one.
+            default = False
+        wait (bool): Wait for the nat to be in the deleted state before returning.
+            default = False
+        wait_timeout (int): Number of seconds to wait, until this timeout is reached.
+            default = 0
+        client_token (str):
+            default = None
+
+    Basic Usage:
+        >>> client = boto3.client('ec2')
+        >>> subnet_id = 'subnet-w4t12897'
+        >>> allocation_id = 'eipalloc-36014da3'
+        >>> create(client, subnet_id, allocation_id, if_exist_do_not_create=True, wait=True, wait_timeout=500)
+        [
+            true,
+            "",
+            {
+                "nat_gateway_id": "nat-03835afb6e31df79b",
+                "subnet_id": "subnet-w4t12897",
+                "nat_gateway_addresses": [
+                    {
+                        "public_ip": "52.87.29.36",
+                        "network_interface_id": "eni-5579742d",
+                        "private_ip": "10.0.0.102",
+                        "allocation_id": "eipalloc-36014da3"
+                    }
+                ],
+                "state": "deleted",
+                "create_time": "2016-03-05T00:33:21.209000+00:00",
+                "delete_time": "2016-03-05T00:36:37.329000+00:00",
+                "vpc_id": "vpc-w68571b5"
+            }
+        ]
+
+    Returns:
+        Tuple (bool, str, list)
+    """
+    params = {
+        'SubnetId': subnet_id,
+        'AllocationId': allocation_id
+    }
+    request_time = datetime.datetime.utcnow()
+    changed = False
+    token_provided = False
+    err_msg = ""
+
+    if client_token:
+        token_provided = True
+        params['ClientToken'] = client_token
+
+    try:
+        result = client.create_nat_gateway(**params)["NatGateway"]
+        changed = True
+        create_time = result['CreateTime'].replace(tzinfo=None)
+        if token_provided and (request_time > create_time):
+            changed = False
+        elif wait:
+            status_achieved, err_msg, result = (
+                wait_for_status(
+                    client, wait_timeout, result['NatGatewayId'], 'available'
+                )
+            )
+    except botocore.exceptions.ClientError as e:
+        if "IdempotentParameterMismatch" in e.message:
+            err_msg = (
+                'NAT Gateway does not support update and token has already been provided'
+            )
+        else:
+            err_msg = str(e)
+
+    return changed, err_msg, result
+
+def pre_create(client, subnet_id, allocation_id=None, eip_address=None,
+              if_exist_do_not_create=False, wait=False, wait_timeout=0,
+              client_token=None):
+    """Create an Amazon NAT Gateway.
+    Args:
+        client (botocore.client.EC2): Boto3 client
+        subnet_id (str): The subnet_id the nat resides in.
+
+    Kwargs:
+        allocation_id (str): The eip Amazon identifier.
+            default = None
+        eip_address (str): The Elastic IP Address of the EIP.
+            default = None
+        if_exist_do_not_create (bool): if a nat gateway already exists in this
+            subnet, than do not create another one.
+            default = False
+        wait (bool): Wait for the nat to be in the deleted state before returning.
+            default = False
+        wait_timeout (int): Number of seconds to wait, until this timeout is reached.
+            default = 0
+        client_token (str):
+            default = None
+
+    Basic Usage:
+        >>> client = boto3.client('ec2')
+        >>> subnet_id = 'subnet-w4t12897'
+        >>> allocation_id = 'eipalloc-36014da3'
+        >>> pre_create(client, subnet_id, allocation_id, if_exist_do_not_create=True, wait=True, wait_timeout=500)
+        [
+            true,
+            "",
+            {
+                "nat_gateway_id": "nat-03835afb6e31df79b",
+                "subnet_id": "subnet-w4t12897",
+                "nat_gateway_addresses": [
+                    {
+                        "public_ip": "52.87.29.36",
+                        "network_interface_id": "eni-5579742d",
+                        "private_ip": "10.0.0.102",
+                        "allocation_id": "eipalloc-36014da3"
+                    }
+                ],
+                "state": "deleted",
+                "create_time": "2016-03-05T00:33:21.209000+00:00",
+                "delete_time": "2016-03-05T00:36:37.329000+00:00",
+                "vpc_id": "vpc-w68571b5"
+            }
+        ]
+
+    Returns:
+        Tuple (bool, str, list)
+    """
+    changed = False
+    err_msg = ""
+    results = list()
+
+    if not allocation_id and not eip_address:
+        existing_gateways, allocation_id_exists = (
+            gateway_in_subnet_exists(client, subnet_id)
+        )
+        if len(existing_gateways) > 0 and if_exist_do_not_create:
+            results = existing_gateways
+            return changed, err_msg, results
+        else:
+            _, allocation_id = allocate_eip_address(client)
+
+    elif eip_address or allocation_id:
+        if eip_address and not allocation_id:
+            allocation_id = get_eip_allocation_id_by_address(client)
+
+        existing_gateways, allocation_id_exists = (
+            gateway_in_subnet_exists(client, subnet_id, allocation_id)
+        )
+        if len(existing_gateways) > 0 and (allocation_id_exists or if_exist_do_not_create):
+            results = existing_gateways
+            return changed, err_msg, results
+
+    changed, err_msg, results = create(
+        client, subnet_id, allocation_id, client_token,
+        wait, wait_timeout,if_exist_do_not_create
+    )
+
+    return changed, err_msg, results
+
+def remove(client, nat_gateway_id, wait=False, wait_timeout=0, release_eip=False):
+    """Delete an Amazon NAT Gateway.
+    Args:
+        client (botocore.client.EC2): Boto3 client
+        nat_gateway_id (str): The Amazon nat id.
+
+    Kwargs:
+        wait (bool): Wait for the nat to be in the deleted state before returning.
+        wait_timeout (int): Number of seconds to wait, until this timeout is reached.
+        release_eip (bool): Once the nat has been deleted, you can deallocate the eip from the vpc.
+
+    Basic Usage:
+        >>> client = boto3.client('ec2')
+        >>> nat_gw_id = 'nat-03835afb6e31df79b'
+        >>> remove(client, nat_gw_id, wait=True, wait_timeout=500, release_eip=True)
+        [
+            true,
+            "",
+            {
+                "nat_gateway_id": "nat-03835afb6e31df79b",
+                "subnet_id": "subnet-w4t12897",
+                "nat_gateway_addresses": [
+                    {
+                        "public_ip": "52.87.29.36",
+                        "network_interface_id": "eni-5579742d",
+                        "private_ip": "10.0.0.102",
+                        "allocation_id": "eipalloc-36014da3"
+                    }
+                ],
+                "state": "deleted",
+                "create_time": "2016-03-05T00:33:21.209000+00:00",
+                "delete_time": "2016-03-05T00:36:37.329000+00:00",
+                "vpc_id": "vpc-w68571b5"
+            }
+        ]
+
+    Returns:
+        Tuple (bool, str, list)
+    """
+    params = {
+        'NatGatewayId': nat_gateway_id
+    }
+    changed = False
+    err_msg = ""
+    results = list()
+    try:
+        exist, _, gw = get_nat_gateways(client, nat_gateway_id=nat_gateway_id)
+        if exist and len(gw) == 1:
+            results = gw[0]
+            result = client.delete_nat_gateway(**params)
+            result = convert_to_lower(result)
+            allocation_id = (
+                results['nat_gateway_addresses'][0]['allocation_id']
+            )
+            changed = True
+    except botocore.exceptions.ClientError as e:
+        err_msg = str(e)
+
+    if wait and not err_msg:
+        status_achieved, err_msg, results = (
+            wait_for_status(client, wait_timeout, nat_gateway_id, 'deleted')
+        )
+
+    if release_eip:
+        eip_released = release_address(client, allocation_id)
+        if not eip_released:
+            err_msg = "Failed to release eip %s".format(allocation_id)
+
+    return changed, err_msg, results
+
+def main():
+    argument_spec = ec2_argument_spec()
+    argument_spec.update(dict(
+        subnet_id=dict(),
+        eip_address=dict(),
+        allocation_id=dict(),
+        if_exist_do_not_create=dict(type='bool', default=False),
+        state=dict(default='present', choices=['present', 'absent']),
+        wait=dict(type='bool', default=True),
+        wait_timeout=dict(type='int', default=320, required=False),
+        release_eip=dict(type='bool', default=False),
+        nat_gateway_id=dict(),
+        client_token=dict(),
+        )
+    )
+    module = AnsibleModule(
+        argument_spec=argument_spec,
+        supports_check_mode=True,
+        mutually_exclusive=[
+            ['allocation_id', 'eip_address']
+        ]
+    )
+
+    # Validate Requirements
+    if not HAS_BOTO3:
+        module.fail_json(msg='botocore/boto3 is required.')
+
+    state = module.params.get('state').lower()
+    check_mode = module.check_mode
+    subnet_id = module.params.get('subnet_id')
+    allocation_id = module.params.get('allocation_id')
+    eip_address = module.params.get('eip_address')
+    nat_gateway_id = module.params.get('nat_gateway_id')
+    wait = module.params.get('wait')
+    wait_timeout = module.params.get('wait_timeout')
+    release_eip = module.params.get('release_eip')
+    client_token = module.params.get('client_token')
+    if_exist_do_not_create = module.params.get('if_exist_do_not_create')
+
+    try:
+        region, ec2_url, aws_connect_kwargs = (
+            get_aws_connection_info(module, boto3=True)
+        )
+        client = (
+            boto3_conn(
+                module, conn_type='client', resource='ec2',
+                region=region, endpoint=ec2_url, **aws_connect_kwargs
+            )
+        )
+    except botocore.exceptions.ClientError, e:
+        module.fail_json(msg="Boto3 Client Error - " + str(e.msg))
+
+    changed = False
+    err_msg = None
+
+    #Ensure resource is present
+    if state == 'present':
+        if not subnet_id:
+            module.fail_json(msg='subnet_id is required for creation')
+
+        elif check_mode:
+            changed =  True
+            results = 'Would have created NAT Gateway if not in check mode'
+        else:
+            changed, err_msg, results = (
+                pre_create(
+                    client, subnet_id, allocation_id, eip_address,
+                    if_exist_do_not_create, wait, wait_timeout,
+                    client_token
+                )
+            )
+    else:
+        if not nat_gateway_id:
+            module.fail_json(msg='nat_gateway_id is required for removal')
+
+        elif check_mode:
+            changed = True
+            results = 'Would have deleted NAT Gateway if not in check mode'
+        else:
+            changed, err_msg, results = (
+                remove(client, nat_gateway_id, wait, wait_timeout, release_eip)
+            )
+
+    if err_msg:
+        module.fail_json(msg=err_msg)
+    else:
+        module.exit_json(changed=changed, **results[0])
+
+# import module snippets
+from ansible.module_utils.basic import *
+from ansible.module_utils.ec2 import *
+
+if __name__ == '__main__':
+    main()
+