Repository: ansible/ansible

Issue:
Subnet association fails when name starts with "subnet-"
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
ec2_vpc_nacl

##### ANSIBLE VERSION
```
$ ansible --version
ansible 2.4.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/Users/tornow/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python2.7/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.14 (default, Sep 25 2017, 09:53:22) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.37)]
```

##### SUMMARY

https://github.com/ansible/ansible/blob/f8fa79818c4b5c9dbae055562b82fad305287963/lib/ansible/modules/cloud/amazon/ec2_vpc_nacl.py#L523

Right now a subnet named `"subnet-abc..."` results in a missing NACL association, because the current code automatically searches for 
```
if params[0].startswith("subnet-"):
```
which then assumes it is a subnet-id. If the check for a matching subnet name runs first, this could be prevented and subnets whose names start with `subnet-ABC...` would still work.


Discussion:
@srvvrs Greetings! Thanks for taking the time to open this issue. In order for the community to handle your issue effectively, we need a bit more information. 

Here are the items we could not find in your description:
- issue type
- ansible version
- component name

Please set the description of this issue with this template:
https://raw.githubusercontent.com/ansible/ansible/devel/.github/ISSUE_TEMPLATE.md

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: issue_missing_data --->
##### ISSUE TYPE
- Feature Idea ooooor
 - Documentation Report

##### COMPONENT NAME
ec2_vpc_nacl

##### ANSIBLE VERSION
```
$ ansible --version
ansible 2.4.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/Users/tornow/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python2.7/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.14 (default, Sep 25 2017, 09:53:22) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.37)]
```

##### CONFIGURATION
No changes

##### OS / ENVIRONMENT
<!---
Mac OS Sierra
-->

##### SUMMARY
In the current implementation when creating a new or updating an existing NACL with a subnet association fails, when the subnet's name is used as parameter and the name starts with `subnet-`. The reason is that the distinguishing code just looks for a `startswith("subnet-")`.
By reversing the order of checking for ID or name (checking for name first), it would be even possible to use the subnet's ID as name (for whatever reason that would make any sense).

Otherwise I would state in the documentation that a subnet's name can not start with `subnet-`.

##### STEPS TO REPRODUCE
Just try create a NACL and associate it with a subnet whose name starts with `subnet-`

##### EXPECTED RESULTS
The NACL will be created and the desired subnet is associated

##### ACTUAL RESULTS
The NACL is  created without the desired subnet association
cc @mmochan
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
cc @willthames
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/lib/ansible/modules/cloud/amazon/ec2_vpc_nacl.py b/lib/ansible/modules/cloud/amazon/ec2_vpc_nacl.py
--- a/lib/ansible/modules/cloud/amazon/ec2_vpc_nacl.py
+++ b/lib/ansible/modules/cloud/amazon/ec2_vpc_nacl.py
@@ -141,6 +141,7 @@
 except ImportError:
     HAS_BOTO3 = False
 
+import traceback
 from ansible.module_utils.basic import AnsibleModule
 from ansible.module_utils.ec2 import boto3_conn, ec2_argument_spec, get_aws_connection_info
 
@@ -522,19 +523,22 @@ def subnets_to_associate(nacl, client, module):
     params = list(module.params.get('subnets'))
     if not params:
         return []
-    if params[0].startswith("subnet-"):
+    all_found = []
+    if any(x.startswith("subnet-") for x in params):
         try:
             subnets = client.describe_subnets(Filters=[
                 {'Name': 'subnet-id', 'Values': params}])
+            all_found.extend(subnets.get('Subnets', []))
         except botocore.exceptions.ClientError as e:
-            module.fail_json(msg=str(e))
-    else:
+            module.fail_json(msg=str(e), exception=traceback.format_exc())
+    if len(params) != len(all_found):
         try:
             subnets = client.describe_subnets(Filters=[
                 {'Name': 'tag:Name', 'Values': params}])
+            all_found.extend(subnets.get('Subnets', []))
         except botocore.exceptions.ClientError as e:
-            module.fail_json(msg=str(e))
-    return [s['SubnetId'] for s in subnets['Subnets'] if s['SubnetId']]
+            module.fail_json(msg=str(e), exception=traceback.format_exc())
+    return list(set(s['SubnetId'] for s in all_found if s.get('SubnetId')))
 
 
 def main():


Test patch: