Repository: ansible/ansible

Issue:
ec2_group introduced with 2.4.0.0 throws TypeError
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
<!--- Name of the module/plugin/task/feature -->
ec2_group
##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.4.0.0
  config file = None
  configured module search path = [u'/home/arnon.k/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/arnon.k/production_dev/venvnew/lib/python2.7/site-packages/ansible
  executable location = /home/arnon.k/production_dev/venvnew/bin/ansible
  python version = 2.7.5 (default, Nov  6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]

```

##### CONFIGURATION
<!---
If using Ansible 2.4 or above, paste the results of "ansible-config dump --only-changed"

Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).

-->
Nothing
##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
Centos 7.4
##### SUMMARY
<!--- Explain the problem briefly -->

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->
When using ec2_group module

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- name: Configure ports
  ec2_group:
    name: Test
    state: present
    description: Issue
    region: us-east-1
    rules:
      - proto: tcp
        ports:
          - 8888
        cidr_ip: "1.1.1.1/32"

```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
To succeed
##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
The module throws an exception of: 
<!--- Paste verbatim command output between quotes below -->
```
The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_pIaxjv/ansible_module_ec2_group.py", line 899, in <module>
    main()
  File "/tmp/ansible_pIaxjv/ansible_module_ec2_group.py", line 801, in main
    add_rules_to_lookup(group['IpPermissionsEgress'], group['GroupId'], 'out', groupRules)
  File "/tmp/ansible_pIaxjv/ansible_module_ec2_group.py", line 314, in add_rules_to_lookup
    for ipv6Grants in rule.get('Ipv6Ranges'):
TypeError: 'NoneType' object is not iterable

fatal: [localhost]: FAILED! => {
    "changed": false,
    "failed": true,
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_pIaxjv/ansible_module_ec2_group.py\", line 899, in <module>\n    main()\n  File \"/tmp/ansible_pIaxjv/ansible_module_ec2_group.py\", line 801, in main\n    add_rules_to_lookup(group['IpPermissionsEgress'], group['GroupId'], 'out', groupRules)\n  File \"/tmp/ansible_pIaxjv/ansible_module_ec2_group.py\", line 314, in add_rules_to_lookup\n    for ipv6Grants in rule.get('Ipv6Ranges'):\nTypeError: 'NoneType' object is not iterable\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 0
}
```
ec2_group introduced with 2.4.0.0 throws TypeError
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
<!--- Name of the module/plugin/task/feature -->
ec2_group
##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.4.0.0
  config file = None
  configured module search path = [u'/home/arnon.k/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/arnon.k/production_dev/venvnew/lib/python2.7/site-packages/ansible
  executable location = /home/arnon.k/production_dev/venvnew/bin/ansible
  python version = 2.7.5 (default, Nov  6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]

```

##### CONFIGURATION
<!---
If using Ansible 2.4 or above, paste the results of "ansible-config dump --only-changed"

Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).

-->
Nothing
##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
Centos 7.4
##### SUMMARY
<!--- Explain the problem briefly -->

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->
When using ec2_group module

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- name: Configure ports
  ec2_group:
    name: Test
    state: present
    description: Issue
    region: us-east-1
    rules:
      - proto: tcp
        ports:
          - 8888
        cidr_ip: "1.1.1.1/32"

```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
To succeed
##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
The module throws an exception of: 
<!--- Paste verbatim command output between quotes below -->
```
The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_pIaxjv/ansible_module_ec2_group.py", line 899, in <module>
    main()
  File "/tmp/ansible_pIaxjv/ansible_module_ec2_group.py", line 801, in main
    add_rules_to_lookup(group['IpPermissionsEgress'], group['GroupId'], 'out', groupRules)
  File "/tmp/ansible_pIaxjv/ansible_module_ec2_group.py", line 314, in add_rules_to_lookup
    for ipv6Grants in rule.get('Ipv6Ranges'):
TypeError: 'NoneType' object is not iterable

fatal: [localhost]: FAILED! => {
    "changed": false,
    "failed": true,
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_pIaxjv/ansible_module_ec2_group.py\", line 899, in <module>\n    main()\n  File \"/tmp/ansible_pIaxjv/ansible_module_ec2_group.py\", line 801, in main\n    add_rules_to_lookup(group['IpPermissionsEgress'], group['GroupId'], 'out', groupRules)\n  File \"/tmp/ansible_pIaxjv/ansible_module_ec2_group.py\", line 314, in add_rules_to_lookup\n    for ipv6Grants in rule.get('Ipv6Ranges'):\nTypeError: 'NoneType' object is not iterable\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 0
}
```


Discussion:
cc @adq
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
cc @adq
[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_group.py b/lib/ansible/modules/cloud/amazon/ec2_group.py
--- a/lib/ansible/modules/cloud/amazon/ec2_group.py
+++ b/lib/ansible/modules/cloud/amazon/ec2_group.py
@@ -307,11 +307,11 @@ def make_rule_key(prefix, rule, group_id, cidr_ip):
 
 def add_rules_to_lookup(ipPermissions, group_id, prefix, dict):
     for rule in ipPermissions:
-        for groupGrant in rule.get('UserIdGroupPairs'):
+        for groupGrant in rule.get('UserIdGroupPairs', []):
             dict[make_rule_key(prefix, rule, group_id, groupGrant.get('GroupId'))] = (rule, groupGrant)
-        for ipv4Grants in rule.get('IpRanges'):
+        for ipv4Grants in rule.get('IpRanges', []):
             dict[make_rule_key(prefix, rule, group_id, ipv4Grants.get('CidrIp'))] = (rule, ipv4Grants)
-        for ipv6Grants in rule.get('Ipv6Ranges'):
+        for ipv6Grants in rule.get('Ipv6Ranges', []):
             dict[make_rule_key(prefix, rule, group_id, ipv6Grants.get('CidrIpv6'))] = (rule, ipv6Grants)
 
 
@@ -759,7 +759,7 @@ def main():
                                 ips = ip_permission
                                 if vpc_id:
                                     [useridpair.update({'VpcId': vpc_id}) for useridpair in
-                                     ip_permission.get('UserIdGroupPairs')]
+                                     ip_permission.get('UserIdGroupPairs', [])]
                                 try:
                                     client.authorize_security_group_ingress(GroupId=group['GroupId'], IpPermissions=[ips])
                                 except botocore.exceptions.ClientError as e:
@@ -824,7 +824,7 @@ def main():
                                 ips = ip_permission
                                 if vpc_id:
                                     [useridpair.update({'VpcId': vpc_id}) for useridpair in
-                                     ip_permission.get('UserIdGroupPairs')]
+                                     ip_permission.get('UserIdGroupPairs', [])]
                                 try:
                                     client.authorize_security_group_egress(GroupId=group['GroupId'], IpPermissions=[ips])
                                 except botocore.exceptions.ClientError as e:


Test patch: