Repository: ansible/ansible

Issue:
elb_target_group: health_check_port is ignored
##### SUMMARY
When creating a elb_target_group, setting health_check_port has no effect and 'traffic-port' is always selected

##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
elb_target_group

##### ANSIBLE VERSION
```
ansible 2.6.1
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/dse09/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Jul 13 2018, 13:06:57) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
```

##### CONFIGURATION

##### OS / ENVIRONMENT
CentOS 7

##### STEPS TO REPRODUCE
```yaml
- name: create targetgroup
  elb_target_group:
    name: "test-tg"
    protocol: tcp
    port: 12345
    vpc_id: vpc-xxxx
    health_check_protocol: tcp
    health_check_port: 80
    successful_response_codes: "200"
    state: present
  register: elb_target_group

- debug: msg={{elb_target_group}}
```

##### EXPECTED RESULTS
I expect the target group to be created with the health check port set to 80.

If the command is run using aws cli, it works fine:
```bash
$ aws elbv2 create-target-group --name test-tg --protocol TCP --port 12345 --health-check-port 80 --vpc-id vpc-3xxxx
{
    "TargetGroups": [
        {
            "TargetType": "instance",
            "HealthCheckIntervalSeconds": 30,
            "VpcId": "vpc-xxxx",
            "Protocol": "TCP",
            "HealthCheckTimeoutSeconds": 10,
            "HealthCheckProtocol": "TCP",
            "UnhealthyThresholdCount": 3,
            "HealthyThresholdCount": 3,
            "TargetGroupArn": "arn:aws:elasticloadbalancing:eu-west-1:0xxxx:targetgroup/test-tg/0xxxxxxxx",
            "HealthCheckPort": "80",
            "Port": 12345,
            "TargetGroupName": "test-tg"
        }
    ]
}
```

##### ACTUAL RESULTS
targetgroup is created with health_check_port set to 'traffic-port'.

```
TASK [create targetgroup] *********************************************************************************************************************************************************************************
task path: /home/dse09/src/vtp-bcmed-proxy/test2.yml:7
Using module file /usr/lib/python2.7/site-packages/ansible/modules/cloud/amazon/elb_target_group.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: dse09
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 && sleep 0'
changed: [localhost] => {
    "changed": true,
    "deregistration_delay_timeout_seconds": "300",
    "health_check_interval_seconds": 30,
    "health_check_port": "traffic-port",
    "health_check_protocol": "TCP",
    "health_check_timeout_seconds": 10,
    "healthy_threshold_count": 3,
    "invocation": {
        "module_args": {
            "aws_access_key": null,
            "aws_secret_key": null,
            "deregistration_delay_timeout": null,
            "ec2_url": null,
            "health_check_interval": null,
            "health_check_path": null,
            "health_check_port": "80",
            "health_check_protocol": "tcp",
            "health_check_timeout": null,
            "healthy_threshold_count": null,
            "modify_targets": true,
            "name": "test-tg",
            "port": 12345,
            "profile": null,
            "protocol": "tcp",
            "purge_tags": true,
            "region": null,
            "security_token": null,
            "state": "present",
            "stickiness_enabled": null,
            "stickiness_lb_cookie_duration": null,
            "stickiness_type": "lb_cookie",
            "successful_response_codes": "200",
            "tags": {},
            "target_type": "instance",
            "targets": null,
            "unhealthy_threshold_count": null,
            "validate_certs": true,
            "vpc_id": "vpc-xxxx",
            "wait": null,
            "wait_timeout": null
        }
    },
    "load_balancer_arns": [],
    "port": 12345,
    "protocol": "TCP",
    "proxy_protocol_v2_enabled": "false",
    "tags": {},
    "target_group_arn": "arn:aws:elasticloadbalancing:eu-west-1:xxxx:targetgroup/test-tg/xxxx",
    "target_group_name": "test-tg",
    "target_type": "instance",
    "unhealthy_threshold_count": 3,
    "vpc_id": "vpc-xxxx"
}

TASK [debug] **********************************************************************************************************************************************************************************************
task path: /home/dse09/src/vtp-bcmed-proxy/test2.yml:19
ok: [localhost] => {
    "msg": {
        "changed": true,
        "deregistration_delay_timeout_seconds": "300",
        "failed": false,
        "health_check_interval_seconds": 30,
        "health_check_port": "traffic-port",
        "health_check_protocol": "TCP",
        "health_check_timeout_seconds": 10,
        "healthy_threshold_count": 3,
        "load_balancer_arns": [],
        "port": 12345,
        "protocol": "TCP",
        "proxy_protocol_v2_enabled": "false",
        "tags": {},
        "target_group_arn": "arn:aws:elasticloadbalancing:eu-west-1:xxxx:targetgroup/test-tg/xxx",
        "target_group_name": "test-tg",
        "target_type": "instance",
        "unhealthy_threshold_count": 3,
        "vpc_id": "vpc-xxxx"
    }
}
```



Discussion:
Files identified in the description:
* [lib/ansible/modules/cloud/amazon/elb_target_group.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/amazon/elb_target_group.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 @wimnat
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Hi dseeley-sky,

Thank you for the issue, just so you are aware we have a dedicated Working Group for aws.
You can find other people interested in this in #ansible-aws on Freenode IRC
For more information about communities, meetings and agendas see https://github.com/ansible/community

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: community_workgroups --->
This is happening because it's TCP type.  I'll raise a PR with a fix shortly.
FYI - the other parameters (health_check_interval, health_check_timeout, etc) are also ignored.

Resolving patch:
diff --git a/lib/ansible/modules/cloud/amazon/elb_target_group.py b/lib/ansible/modules/cloud/amazon/elb_target_group.py
--- a/lib/ansible/modules/cloud/amazon/elb_target_group.py
+++ b/lib/ansible/modules/cloud/amazon/elb_target_group.py
@@ -397,9 +397,14 @@ def create_or_update_target_group(connection, module):
     stickiness_lb_cookie_duration = module.params.get("stickiness_lb_cookie_duration")
     stickiness_type = module.params.get("stickiness_type")
 
-    # If health check path not None, set health check attributes
-    if module.params.get("health_check_path") is not None:
-        params['HealthCheckPath'] = module.params.get("health_check_path")
+    health_option_keys = [
+        "health_check_path", "health_check_protocol", "health_check_interval", "health_check_timeout",
+        "healthy_threshold_count", "unhealthy_threshold_count", "successful_response_codes"
+    ]
+    health_options = any([module.params[health_option_key] is not None for health_option_key in health_option_keys])
+
+    # Set health check if anything set
+    if health_options:
 
         if module.params.get("health_check_protocol") is not None:
             params['HealthCheckProtocol'] = module.params.get("health_check_protocol").upper()
@@ -419,9 +424,15 @@ def create_or_update_target_group(connection, module):
         if module.params.get("unhealthy_threshold_count") is not None:
             params['UnhealthyThresholdCount'] = module.params.get("unhealthy_threshold_count")
 
-        if module.params.get("successful_response_codes") is not None:
-            params['Matcher'] = {}
-            params['Matcher']['HttpCode'] = module.params.get("successful_response_codes")
+        # Only need to check response code and path for http(s) health checks
+        if module.params.get("health_check_protocol") is not None and module.params.get("health_check_protocol").upper() != 'TCP':
+
+            if module.params.get("health_check_path") is not None:
+                params['HealthCheckPath'] = module.params.get("health_check_path")
+
+            if module.params.get("successful_response_codes") is not None:
+                params['Matcher'] = {}
+                params['Matcher']['HttpCode'] = module.params.get("successful_response_codes")
 
     # Get target type
     if module.params.get("target_type") is not None:
@@ -441,8 +452,9 @@ def create_or_update_target_group(connection, module):
         # Target group exists so check health check parameters match what has been passed
         health_check_params = dict()
 
-        # If we have no health check path then we have nothing to modify
-        if module.params.get("health_check_path") is not None:
+        # Modify health check if anything set
+        if health_options:
+
             # Health check protocol
             if 'HealthCheckProtocol' in params and tg['HealthCheckProtocol'] != params['HealthCheckProtocol']:
                 health_check_params['HealthCheckProtocol'] = params['HealthCheckProtocol']
@@ -451,10 +463,6 @@ def create_or_update_target_group(connection, module):
             if 'HealthCheckPort' in params and tg['HealthCheckPort'] != params['HealthCheckPort']:
                 health_check_params['HealthCheckPort'] = params['HealthCheckPort']
 
-            # Health check path
-            if 'HealthCheckPath'in params and tg['HealthCheckPath'] != params['HealthCheckPath']:
-                health_check_params['HealthCheckPath'] = params['HealthCheckPath']
-
             # Health check interval
             if 'HealthCheckIntervalSeconds' in params and tg['HealthCheckIntervalSeconds'] != params['HealthCheckIntervalSeconds']:
                 health_check_params['HealthCheckIntervalSeconds'] = params['HealthCheckIntervalSeconds']
@@ -471,14 +479,20 @@ def create_or_update_target_group(connection, module):
             if 'UnhealthyThresholdCount' in params and tg['UnhealthyThresholdCount'] != params['UnhealthyThresholdCount']:
                 health_check_params['UnhealthyThresholdCount'] = params['UnhealthyThresholdCount']
 
-            # Matcher (successful response codes)
-            # TODO: required and here?
-            if 'Matcher' in params:
-                current_matcher_list = tg['Matcher']['HttpCode'].split(',')
-                requested_matcher_list = params['Matcher']['HttpCode'].split(',')
-                if set(current_matcher_list) != set(requested_matcher_list):
-                    health_check_params['Matcher'] = {}
-                    health_check_params['Matcher']['HttpCode'] = ','.join(requested_matcher_list)
+            # Only need to check response code and path for http(s) health checks
+            if tg['HealthCheckProtocol'] != 'TCP':
+                # Health check path
+                if 'HealthCheckPath'in params and tg['HealthCheckPath'] != params['HealthCheckPath']:
+                    health_check_params['HealthCheckPath'] = params['HealthCheckPath']
+
+                # Matcher (successful response codes)
+                # TODO: required and here?
+                if 'Matcher' in params:
+                    current_matcher_list = tg['Matcher']['HttpCode'].split(',')
+                    requested_matcher_list = params['Matcher']['HttpCode'].split(',')
+                    if set(current_matcher_list) != set(requested_matcher_list):
+                        health_check_params['Matcher'] = {}
+                        health_check_params['Matcher']['HttpCode'] = ','.join(requested_matcher_list)
 
             try:
                 if health_check_params:


Test patch: