Repository: ansible-collections/community.aws

Issue:
elb_target_group stickiness_type default no longer works on TCP target groups
<!--- Verify first that your issue is not already reported on GitHub -->
<!--- Also test if the latest release and devel branch are affected too -->
<!--- Complete *all* sections as described, this form is processed automatically -->

##### SUMMARY
This issue was first reported in https://github.com/ansible/ansible/issues/67993 (it was closed by the author because they found a workaround).

The default value of `lb_cookie` for `stickiness_type` is no longer ignored by AWS for TCP target groups, which is causing this module to fail when not explicitly specifying a stickiness type (even when stickiness is off/not set).

It looks like Amazon is changing their API and rolling it out slowly as the linked issue starts on Mar 4, and seems to be hitting people little by little. It showed up today at different times for us on different target groups across some of our accounts.

---

The default should either be left out in the call to AWS so that it chooses its own default (if that's possible), or this module should choose a default based on the protocol of the target group.

The current workaround I'm using is a conditional in jinja, something like:
```yaml
- elb_target_group:
    protocol: "{{ proto }}"
    stickiness_type: "{{ 'source_ip' if proto == 'tcp' else omit }}"
```


##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
<!--- Write the short name of the module, plugin, task or feature below, use your best guess if unsure -->
elb_target_group

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes -->
```paste below
2.9.6
```

##### CONFIGURATION
<!--- Paste verbatim output from "ansible-config dump --only-changed" between quotes -->

##### OS / ENVIRONMENT
<!--- Provide all relevant information below, e.g. target OS versions, network device firmware, etc. -->


##### STEPS TO REPRODUCE
<!--- Describe exactly how to reproduce the problem, using a minimal test-case -->

<!--- Paste example playbooks or commands between quotes below -->
```yaml
#pseudo
- elb_target_group:
    name: test
    protocol: tcp
```

<!--- HINT: You can paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- Describe what you expected to happen when running the steps above -->
Success

##### ACTUAL RESULTS
<!--- Describe what actually happened. If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes -->
```paste below
TASK [immutable_server : target group for analytics-tst-plebos loadbalancer] ***
17:21:08 An exception occurred during task execution. To see the full traceback, use -vvv. The error was: InvalidConfigurationRequestException:
An error occurred (InvalidConfigurationRequest) when calling the ModifyTargetGroupAttributes operation: 
Stickiness type 'lb_cookie' is not supported for target groups with the TCP protocol
17:21:08 fatal: [localhost]: FAILED! => {"changed": false, "error": {"code": "InvalidConfigurationRequest", "message": "Stickiness type 'lb_cookie'
is not supported for target groups with the TCP protocol", "type": "Sender"}, "msg": "An error occurred (InvalidConfigurationRequest) 
when calling the ModifyTargetGroupAttributes operation: Stickiness type 'lb_cookie' is not supported for target groups with the TCP protocol", 
"response_metadata": {"http_headers": {"connection": "close", "content-length": "359", "content-type": "text/xml", "date": "Tue, 03 Mar 2020 11:51:08 GMT", 
"x-amzn-requestid": "23b0ca87-e0fb-4b84-b93b-ae5b1363df53"}, "http_status_code": 400, "request_id": "23b0ca87-e0fb-4b84-b93b-ae5b1363df53", "retry_attempts": 0}}

```



Discussion:

Resolving patch:
diff --git a/plugins/modules/elb_target_group.py b/plugins/modules/elb_target_group.py
--- a/plugins/modules/elb_target_group.py
+++ b/plugins/modules/elb_target_group.py
@@ -107,8 +107,8 @@
     type: int
   stickiness_type:
     description:
-      - The type of sticky sessions. The possible value is lb_cookie.
-    default: lb_cookie
+      - The type of sticky sessions.
+      - If not set AWS will default to C(lb_cookie) for Application Load Balancers or C(source_ip) for Network Load Balancers.
     type: str
   successful_response_codes:
     description:
@@ -547,7 +547,7 @@ def create_or_update_target_group(connection, module):
             # Only need to check response code and path for http(s) health checks
             if tg['HealthCheckProtocol'] in ['HTTP', 'HTTPS']:
                 # Health check path
-                if 'HealthCheckPath'in params and tg['HealthCheckPath'] != params['HealthCheckPath']:
+                if 'HealthCheckPath' in params and tg['HealthCheckPath'] != params['HealthCheckPath']:
                     health_check_params['HealthCheckPath'] = params['HealthCheckPath']
 
                 # Matcher (successful response codes)
@@ -744,8 +744,8 @@ def create_or_update_target_group(connection, module):
     if stickiness_lb_cookie_duration is not None:
         if str(stickiness_lb_cookie_duration) != current_tg_attributes['stickiness_lb_cookie_duration_seconds']:
             update_attributes.append({'Key': 'stickiness.lb_cookie.duration_seconds', 'Value': str(stickiness_lb_cookie_duration)})
-    if stickiness_type is not None and "stickiness_type" in current_tg_attributes:
-        if stickiness_type != current_tg_attributes['stickiness_type']:
+    if stickiness_type is not None:
+        if stickiness_type != current_tg_attributes.get('stickiness_type'):
             update_attributes.append({'Key': 'stickiness.type', 'Value': stickiness_type})
 
     if update_attributes:
@@ -825,7 +825,7 @@ def main():
         protocol=dict(choices=protocols_list),
         purge_tags=dict(default=True, type='bool'),
         stickiness_enabled=dict(type='bool'),
-        stickiness_type=dict(default='lb_cookie'),
+        stickiness_type=dict(),
         stickiness_lb_cookie_duration=dict(type='int'),
         state=dict(required=True, choices=['present', 'absent']),
         successful_response_codes=dict(),


Test patch: