Repository: ansible/ansible

Issue:
elb_application_lb does not convert port values to int when loaded via with_items


##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
elb_application_lb
##### ANSIBLE VERSION
```
ansible 2.4.0
  config file = /Users/byi470/Workspaces/Ansible_Developer/ansible.cfg
  configured module search path = [u'/Users/byi470/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/ansible
  executable location = /Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/bin/ansible
  python version = 2.7.13 (default, Apr  4 2017, 08:47:57) [GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.38)]
```

##### CONFIGURATION
n/a - no changes

##### OS / ENVIRONMENT
n/a

##### SUMMARY
When executing elb_application_lb via a with_items and a dictionary, elb_application_lb does not convert port values to integers.  Other ansible modules (e.g. ecs_service) do this conversion.

##### STEPS TO REPRODUCE
```yaml

### vars ###
ecs_service_and_task_definitions:
  - app_prefix:                          "{{ infrastucture_prefix }}-collector"
    listener_port:                       443

### task ###

- name: create application load balancer
  elb_application_lb:
    name:                                        "{{ item.app_prefix }}-lb"
    subnets:                                    "{{ subnets }}"
    security_groups:                       "{{ security_groups }}"
    scheme:                                     "{{ item.scheme | default('internal') }}"
    listeners:
      - Protocol:                               HTTPS
        Port:                                       "{{ item.listener_port }}"
        SslPolicy:                              "{{ lb_ssl_security_policy }}"
        Certificates:
          - CertificateArn:                  "{{ lb_ssl_certificate_arn }}"
        DefaultActions:
          - Type:                                 forward
            TargetGroupName:           "{{ item.app_prefix }}-tg"
    state:                                          present
  with_items:
    - "{{ ecs_service_and_task_definitions }}"

```

##### EXPECTED RESULTS
"{{ item.listener_port }}" is converted to an integer

NOTES:
* other modules do this conversation (e.g. ecs_service)
* conversion to int (via a  |int) does not work (jinja2 limitation)

##### ACTUAL RESULTS
```
task path: /Users/byi470/Workspaces/Ansible_Developer/roles/aws_create_loadbalancer/tasks/main.yml:17
Using module_utils file /Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/ansible/module_utils/basic.py
Using module_utils file /Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/ansible/module_utils/ec2.py
Using module_utils file /Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/ansible/module_utils/six/__init__.py
Using module_utils file /Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/ansible/module_utils/_text.py
Using module_utils file /Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/ansible/module_utils/parsing/convert_bool.py
Using module_utils file /Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/ansible/module_utils/parsing/__init__.py
Using module_utils file /Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/ansible/module_utils/pycompat24.py
Using module_utils file /Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/ansible/module_utils/cloud.py
Using module_utils file /Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/ansible/module_utils/six/_six.py
Using module file /Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/ansible/modules/cloud/amazon/elb_application_lb.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: byi470
<127.0.0.1> EXEC /bin/sh -c 'echo ~ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /Users/byi470/.ansible/tmp/ansible-tmp-1502749039.44-189230135111578 `" && echo ansible-tmp-1502749039.44-189230135111578="` echo /Users/byi470/.ansible/tmp/ansible-tmp-1502749039.44-189230135111578 `" ) && sleep 0'
<127.0.0.1> PUT /var/folders/k5/tnq7hf_s3fjc59sxdmh2hb7c8q_pwy/T/tmpCIDeUf TO /Users/byi470/.ansible/tmp/ansible-tmp-1502749039.44-189230135111578/elb_application_lb.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /Users/byi470/.ansible/tmp/ansible-tmp-1502749039.44-189230135111578/ /Users/byi470/.ansible/tmp/ansible-tmp-1502749039.44-189230135111578/elb_application_lb.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/bin/python2.7 /Users/byi470/.ansible/tmp/ansible-tmp-1502749039.44-189230135111578/elb_application_lb.py; rm -rf "/Users/byi470/.ansible/tmp/ansible-tmp-1502749039.44-189230135111578/" > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/var/folders/k5/tnq7hf_s3fjc59sxdmh2hb7c8q_pwy/T/ansible_fFYd0r/ansible_module_elb_application_lb.py", line 1010, in <module>
    main()
  File "/var/folders/k5/tnq7hf_s3fjc59sxdmh2hb7c8q_pwy/T/ansible_fFYd0r/ansible_module_elb_application_lb.py", line 1005, in main
    create_or_update_elb(connection, connection_ec2, module)
  File "/var/folders/k5/tnq7hf_s3fjc59sxdmh2hb7c8q_pwy/T/ansible_fFYd0r/ansible_module_elb_application_lb.py", line 900, in create_or_update_elb
    listener_changed = create_or_update_elb_listeners(connection, module, elb)
  File "/var/folders/k5/tnq7hf_s3fjc59sxdmh2hb7c8q_pwy/T/ansible_fFYd0r/ansible_module_elb_application_lb.py", line 721, in create_or_update_elb_listeners
    connection.create_listener(**listener_to_add)
  File "/Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/botocore/client.py", line 310, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/botocore/client.py", line 573, in _make_api_call
    api_params, operation_model, context=request_context)
  File "/Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/botocore/client.py", line 628, in _convert_to_request_dict
    api_params, operation_model)
  File "/Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/botocore/validate.py", line 291, in serialize_to_request
    raise ParamValidationError(report=report.generate_report())
botocore.exceptions.ParamValidationError: Parameter validation failed:
Invalid type for parameter Port, value: 8080, type: <type 'str'>, valid types: <type 'int'>, <type 'long'>

failed: [localhost] (item={u'lb_listener_port': 443, u'app_prefix': u'potomac-test-dev-collector'}) => {
    "changed": false,
    "failed": true,
    "item": {
        "app_prefix": "potomac-test-dev-collector",
        "lb_listener_port": 443,
    },
    "module_stderr": "Traceback (most recent call last):\n  File \"/var/folders/k5/tnq7hf_s3fjc59sxdmh2hb7c8q_pwy/T/ansible_fFYd0r/ansible_module_elb_application_lb.py\", line 1010, in <module>\n    main()\n  File \"/var/folders/k5/tnq7hf_s3fjc59sxdmh2hb7c8q_pwy/T/ansible_fFYd0r/ansible_module_elb_application_lb.py\", line 1005, in main\n    create_or_update_elb(connection, connection_ec2, module)\n  File \"/var/folders/k5/tnq7hf_s3fjc59sxdmh2hb7c8q_pwy/T/ansible_fFYd0r/ansible_module_elb_application_lb.py\", line 900, in create_or_update_elb\n    listener_changed = create_or_update_elb_listeners(connection, module, elb)\n  File \"/var/folders/k5/tnq7hf_s3fjc59sxdmh2hb7c8q_pwy/T/ansible_fFYd0r/ansible_module_elb_application_lb.py\", line 721, in create_or_update_elb_listeners\n    connection.create_listener(**listener_to_add)\n  File \"/Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/botocore/client.py\", line 310, in _api_call\n    return self._make_api_call(operation_name, kwargs)\n  File \"/Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/botocore/client.py\", line 573, in _make_api_call\n    api_params, operation_model, context=request_context)\n  File \"/Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/botocore/client.py\", line 628, in _convert_to_request_dict\n    api_params, operation_model)\n  File \"/Users/byi470/Workspaces/Ansible_Developer/.ansible_virtualenv/lib/python2.7/site-packages/botocore/validate.py\", line 291, in serialize_to_request\n    raise ParamValidationError(report=report.generate_report())\nbotocore.exceptions.ParamValidationError: Parameter validation failed:\nInvalid type for parameter Port, value: 443, type: <type 'str'>, valid types: <type 'int'>, <type 'long'>\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 0
}

```



Discussion:
cc @wimnat
[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/elb_application_lb.py b/lib/ansible/modules/cloud/amazon/elb_application_lb.py
--- a/lib/ansible/modules/cloud/amazon/elb_application_lb.py
+++ b/lib/ansible/modules/cloud/amazon/elb_application_lb.py
@@ -628,6 +628,7 @@ def compare_listeners(connection, module, current_listeners, new_listeners, purg
     for current_listener in current_listeners:
         current_listener_passed_to_module = False
         for new_listener in new_listeners[:]:
+            new_listener['Port'] = int(new_listener['Port'])
             if current_listener['Port'] == new_listener['Port']:
                 current_listener_passed_to_module = True
                 # Remove what we match so that what is left can be marked as 'to be added'


Test patch: