Repository: ansible-collections/amazon.aws

Issue:
Add support for OutpostArn in ec2_vpc_subnet
##### SUMMARY
Add support for OutpostArn in ec2_vpc_subnet

##### ISSUE TYPE
- Feature Idea

##### COMPONENT NAME
ec2_vpc_subnet

##### ADDITIONAL INFORMATION
Add a module option for OutpostArn in the ec2_vpc_subnet module. When creating a subnet in an Outposts the OutpostARN is needed.



Discussion:
Files identified in the description:
* [`plugins/modules/ec2_vpc_subnet.py`](https://github.com/['ansible-collections/amazon.aws', 'ansible-collections/community.aws', 'ansible-collections/community.vmware']/blob/main/plugins/modules/ec2_vpc_subnet.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 @brandond @jillr @s-hertel @tremble @wimnat
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/plugins/modules/ec2_vpc_subnet.py b/plugins/modules/ec2_vpc_subnet.py
--- a/plugins/modules/ec2_vpc_subnet.py
+++ b/plugins/modules/ec2_vpc_subnet.py
@@ -31,6 +31,12 @@
       - "The IPv6 CIDR block for the subnet. The VPC must have a /56 block assigned and this value must be a valid IPv6 /64 that falls in the VPC range."
       - "Required if I(assign_instances_ipv6=true)"
     type: str
+  outpost_arn:
+    description:
+      - The Amazon Resource Name (ARN) of the Outpost.
+      - If set, allows to create subnet in an Outpost.
+      - To specify outpost_arn, availability zone of Outpost subnet must be specified.
+    type: str
   tags:
     description:
       - "A dict of tags to apply to the subnet. Any tags currently applied to the subnet and not present here will be removed."
@@ -217,6 +223,7 @@
 from ..module_utils.ec2 import ansible_dict_to_boto3_filter_list
 from ..module_utils.ec2 import boto3_tag_list_to_ansible_dict
 from ..module_utils.ec2 import ensure_ec2_tags
+from ..module_utils.ec2 import is_outposts_arn
 from ..module_utils.waiters import get_waiter
 
 
@@ -266,7 +273,7 @@ def handle_waiter(conn, module, waiter_name, params, start_time):
         module.fail_json_aws(e, "An exception happened while trying to wait for updates")
 
 
-def create_subnet(conn, module, vpc_id, cidr, ipv6_cidr=None, az=None, start_time=None):
+def create_subnet(conn, module, vpc_id, cidr, ipv6_cidr=None, outpost_arn=None, az=None, start_time=None):
     wait = module.params['wait']
     wait_timeout = module.params['wait_timeout']
 
@@ -279,6 +286,12 @@ def create_subnet(conn, module, vpc_id, cidr, ipv6_cidr=None, az=None, start_tim
     if az:
         params['AvailabilityZone'] = az
 
+    if outpost_arn:
+        if is_outposts_arn(outpost_arn):
+            params['OutpostArn'] = outpost_arn
+        else:
+            module.fail_json('OutpostArn does not match the pattern specified in API specifications.')
+
     try:
         subnet = get_subnet_info(conn.create_subnet(aws_retry=True, **params))
     except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
@@ -431,7 +444,8 @@ def ensure_subnet_present(conn, module):
     if subnet is None:
         if not module.check_mode:
             subnet = create_subnet(conn, module, module.params['vpc_id'], module.params['cidr'],
-                                   ipv6_cidr=module.params['ipv6_cidr'], az=module.params['az'], start_time=start_time)
+                                   ipv6_cidr=module.params['ipv6_cidr'], outpost_arn=module.params['outpost_arn'],
+                                   az=module.params['az'], start_time=start_time)
         changed = True
         # Subnet will be None when check_mode is true
         if subnet is None:
@@ -521,6 +535,7 @@ def main():
         az=dict(default=None, required=False),
         cidr=dict(required=True),
         ipv6_cidr=dict(default='', required=False),
+        outpost_arn=dict(default='', type='str', required=False),
         state=dict(default='present', choices=['present', 'absent']),
         tags=dict(default={}, required=False, type='dict', aliases=['resource_tags']),
         vpc_id=dict(required=True),
@@ -535,6 +550,9 @@ def main():
 
     module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True, required_if=required_if)
 
+    if module.params.get('outpost_arn') and not module.params.get('az'):
+        module.fail_json(msg="To specify OutpostArn, you must specify the Availability Zone of the Outpost subnet.")
+
     if module.params.get('assign_instances_ipv6') and not module.params.get('ipv6_cidr'):
         module.fail_json(msg="assign_instances_ipv6 is True but ipv6_cidr is None or an empty string")
 


Test patch: