Repository: ansible-collections/amazon.aws

Issue:
elb_classic_lb - failed to create https listener
### Summary

When i try to create a classic ELB it fails to add a HTTPS listener even if i provide `ssl_certificate_id`

Locally i fixed the issue by updating https://github.com/ansible-collections/amazon.aws/blob/main/plugins/modules/elb_classic_lb.py#L903
* From: `return snake_dict_to_camel_dict(listener, True)`
* To: `return formatted_listener` (already converted & has `SSLCertificateId`)

### Issue Type

Bug Report

### Component Name

elb_classic_lb

### Ansible Version

```console (paste below)
$ ansible --version

ansible [core 2.12.0]
  config file = /Users/<USER>/Source/dataintelligence-ansible/ansible.cfg
  configured module search path = ['/Users/<USER>/Source/dataintelligence-ansible/library']
  ansible python module location = /Users/<USER>/Source/dataintelligence-ansible/.runtime/.pyvenv/lib/python3.9/site-packages/ansible
  ansible collection location = /Users/<USER>/.ansible/collections:/usr/share/ansible/collections
  executable location = /Users/<USER>/Source/dataintelligence-ansible/.runtime/.pyvenv/bin/ansible
  python version = 3.9.8 (main, Nov 18 2021, 16:08:04) [Clang 12.0.5 (clang-1205.0.22.9)]
  jinja version = 3.0.3
  libyaml = True
```


### Collection Versions

```console (paste below)
$ ansible-galaxy collection list

# /Users/<USER>/Source/dataintelligence-ansible/.runtime/.pyvenv/lib/python3.9/site-packages/ansible_collections
Collection                    Version
----------------------------- -------
amazon.aws                    2.1.0
ansible.netcommon             2.4.0
ansible.posix                 1.3.0
ansible.utils                 2.4.2
ansible.windows               1.8.0
arista.eos                    3.1.0
awx.awx                       19.4.0
azure.azcollection            1.10.0
check_point.mgmt              2.1.1
chocolatey.chocolatey         1.1.0
cisco.aci                     2.1.0
cisco.asa                     2.1.0
cisco.intersight              1.0.17
cisco.ios                     2.5.0
cisco.iosxr                   2.5.0
cisco.ise                     1.2.1
cisco.meraki                  2.5.0
cisco.mso                     1.2.0
cisco.nso                     1.0.3
cisco.nxos                    2.7.1
cisco.ucs                     1.6.0
cloud.common                  2.1.0
cloudscale_ch.cloud           2.2.0
community.aws                 2.1.0
community.azure               1.1.0
community.ciscosmb            1.0.4
community.crypto              2.0.1
community.digitalocean        1.12.0
community.dns                 2.0.3
community.docker              2.0.1
community.fortios             1.0.0
community.general             4.0.2
community.google              1.0.0
community.grafana             1.2.3
community.hashi_vault         2.0.0
community.hrobot              1.2.1
community.kubernetes          2.0.1
community.kubevirt            1.0.0
community.libvirt             1.0.2
community.mongodb             1.3.2
community.mysql               2.3.1
community.network             3.0.0
community.okd                 2.1.0
community.postgresql          1.5.0
community.proxysql            1.3.0
community.rabbitmq            1.1.0
community.routeros            2.0.0
community.skydive             1.0.0
community.sops                1.2.0
community.vmware              1.16.0
community.windows             1.8.0
community.zabbix              1.5.0
containers.podman             1.8.2
cyberark.conjur               1.1.0
cyberark.pas                  1.0.13
dellemc.enterprise_sonic      1.1.0
dellemc.openmanage            4.2.0
dellemc.os10                  1.1.1
dellemc.os6                   1.0.7
dellemc.os9                   1.0.4
f5networks.f5_modules         1.12.0
fortinet.fortimanager         2.1.4
fortinet.fortios              2.1.3
frr.frr                       1.0.3
gluster.gluster               1.0.2
google.cloud                  1.0.2
hetzner.hcloud                1.6.0
hpe.nimble                    1.1.3
ibm.qradar                    1.0.3
infinidat.infinibox           1.3.0
infoblox.nios_modules         1.1.2
inspur.sm                     1.3.0
junipernetworks.junos         2.6.0
kubernetes.core               2.2.1
mellanox.onyx                 1.0.0
netapp.aws                    21.7.0
netapp.azure                  21.10.0
netapp.cloudmanager           21.12.0
netapp.elementsw              21.7.0
netapp.ontap                  21.13.1
netapp.storagegrid            21.7.0
netapp.um_info                21.8.0
netapp_eseries.santricity     1.2.13
netbox.netbox                 3.3.0
ngine_io.cloudstack           2.2.2
ngine_io.exoscale             1.0.0
ngine_io.vultr                1.1.0
openstack.cloud               1.5.3
openvswitch.openvswitch       2.0.2
ovirt.ovirt                   1.6.5
purestorage.flasharray        1.11.0
purestorage.flashblade        1.8.1
sensu.sensu_go                1.12.0
servicenow.servicenow         1.0.6
splunk.es                     1.0.2
t_systems_mms.icinga_director 1.24.0
theforeman.foreman            2.2.0
vyos.vyos                     2.6.0
wti.remote                    1.0.3
```


### AWS SDK versions

```console (paste below)
$ pip show boto boto3 botocore

Name: boto
Version: 2.49.0
Summary: Amazon Web Services Library
Home-page: https://github.com/boto/boto/
Author: Mitch Garnaat
Author-email: mitch@garnaat.com
License: MIT
Location: /Users/<USER>/Source/dataintelligence-ansible/.runtime/.pyvenv/lib/python3.9/site-packages
Requires:
Required-by:
---
Name: boto3
Version: 1.20.11
Summary: The AWS SDK for Python
Home-page: https://github.com/boto/boto3
Author: Amazon Web Services
Author-email:
License: Apache License 2.0
Location: /Users/<USER>/Source/dataintelligence-ansible/.runtime/.pyvenv/lib/python3.9/site-packages
Requires: botocore, jmespath, s3transfer
Required-by:
---
Name: botocore
Version: 1.23.11
Summary: Low-level, data-driven core of boto 3.
Home-page: https://github.com/boto/botocore
Author: Amazon Web Services
Author-email:
License: Apache License 2.0
Location: /Users/<USER>/Source/dataintelligence-ansible/.runtime/.pyvenv/lib/python3.9/site-packages
Requires: jmespath, python-dateutil, urllib3
Required-by: boto3, s3transfer
```


### Configuration

```console (paste below)
$ ansible-config dump --only-changed

DEFAULT_CALLBACK_PLUGIN_PATH(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = ['/Users/<USER>/Source/dataintelligence-ansible/plugins/callbacks']
DEFAULT_FILTER_PLUGIN_PATH(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = ['/Users/<USER>/Source/dataintelligence-ansible/plugins/filters']
DEFAULT_FORKS(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = 55
DEFAULT_HOST_LIST(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = ['/Users/<USER>/Source/dataintelligence-ansible/inventory/dev']
DEFAULT_INVENTORY_PLUGIN_PATH(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = ['/Users/<USER>/Source/dataintelligence-ansible/plugins/inventory']
DEFAULT_JINJA2_EXTENSIONS(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = jinja2.ext.do
DEFAULT_LOOKUP_PLUGIN_PATH(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = ['/Users/<USER>/Source/dataintelligence-ansible/plugins/lookups']
DEFAULT_MANAGED_STR(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = WARNING!!!! This file is managed by Ansible. Any changes will be overwritten.
DEFAULT_MODULE_PATH(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = ['/Users/<USER>/Source/dataintelligence-ansible/library']
DEFAULT_ROLES_PATH(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = ['/Users/<USER>/Source/dataintelligence-ansible/roles']
DEFAULT_STDOUT_CALLBACK(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = yaml
DEFAULT_TEST_PLUGIN_PATH(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = ['/Users/<USER>/Source/dataintelligence-ansible/plugins/tests']
DEFAULT_TIMEOUT(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = 30
HOST_KEY_CHECKING(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = False
INVENTORY_ANY_UNPARSED_IS_FAILED(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = True
INVENTORY_ENABLED(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = ['host_list', 'script', 'meta']
TRANSFORM_INVALID_GROUP_CHARS(/Users/<USER>/Source/dataintelligence-ansible/ansible.cfg) = ignore


```


### OS / Environment

macOS 11.6

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
---
- name: test playbook
  hosts: localhost
  gather_facts: false
  vars:
    elb_definition:
      connection_draining_timeout: 5
      health_check:
        healthy_threshold: 5
        interval: 5
        ping_path: /verify/service/name/service-name
        ping_port: 8599
        ping_protocol: http
        response_timeout: 3
        unhealthy_threshold: 2
      listeners:
        - instance_port: 8080
          instance_protocol: http
          load_balancer_port: 443
          protocol: https
          ssl_certificate_id: arn:aws:acm:us-east-1:1234...
      name: dev-service-name
      region: us-east-1
      security_group_names:
        - sec-dev-admin
        - sec-dev
      state: present
      subnets:
        - subnet-...
        - subnet-...
      tags:
        CreatedBy: <USER>
        Lifecycle: dev
        Service: service-name

  tasks:
    - name: Create load balancer
      amazon.aws.elb_classic_lb: "{{ elb_definition }}"
      register: created_load_balancer
```


### Expected Results

Classic ELB named dev-service-name with a HTTPS listener

### Actual Results

```console (paste below)
TASK [Create load balancer] ****************************************************
[WARNING]: Using a variable for a task's 'args' is unsafe in some situations
(see
https://docs.ansible.com/ansible/devel/reference_appendices/faq.html#argsplat-
unsafe)
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: botocore.exceptions.ClientError: An error occurred (ValidationError) when calling the CreateLoadBalancer operation: Secure Listeners need to specify a SSLCertificateId
fatal: [localhost -> 127.0.0.1]: FAILED! => changed=false 
  boto3_version: 1.20.48
  botocore_version: 1.23.48
  error:
    code: ValidationError
    message: Secure Listeners need to specify a SSLCertificateId
    type: Sender
  msg: 'Failed to create load balancer: An error occurred (ValidationError) when calling the CreateLoadBalancer operation: Secure Listeners need to specify a SSLCertificateId'
  response_metadata:
    http_headers:
      connection: close
      content-length: '314'
      content-type: text/xml
      date: Fri, 18 Feb 2022 00:43:23 GMT
      x-amzn-requestid: 28d50f62-85a3-4cf7-8977-fd5e96ee1b2d
    http_status_code: 400
    request_id: 28d50f62-85a3-4cf7-8977-fd5e96ee1b2d
    retry_attempts: 0
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Files identified in the description:
* [`plugins/modules/elb_classic_lb.py`](https://github.com/['ansible-collections/amazon.aws', 'ansible-collections/community.aws', 'ansible-collections/community.vmware']/blob/main/plugins/modules/elb_classic_lb.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 @jillr @jsdalton @s-hertel @tremble
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
@anjo-swe Thank you for raising this. Would you be willing to open a pull request with your patch and add an integration test for it (if it's not already covered)? In addition, you also should add a changelog fragment.

Resolving patch:
diff --git a/plugins/modules/elb_classic_lb.py b/plugins/modules/elb_classic_lb.py
--- a/plugins/modules/elb_classic_lb.py
+++ b/plugins/modules/elb_classic_lb.py
@@ -890,7 +890,7 @@ def _format_listener(self, listener, inject_protocol=False):
         if ssl_id:
             formatted_listener['SSLCertificateId'] = ssl_id
 
-        return snake_dict_to_camel_dict(listener, True)
+        return formatted_listener
 
     def _format_healthcheck_target(self):
         """Compose target string from healthcheck parameters"""


Test patch: