GoogleCloudPlatform / deploymentmanager-samples

Deployment Manager samples and templates.
Apache License 2.0
946 stars 716 forks source link

CF template: external load balancer template fails due to health check #469

Open claudiobizzotto opened 5 years ago

claudiobizzotto commented 5 years ago

When deploying the external load balancer templates with healthCheck set to the selfLink of a previously defined health check resource (eg.: $(ref.my-health-check.selfLink)), I get the following error:

Invalid value for field 'resource.healthChecks[0]':
'https://www.googleapis.com/compute/v1/projects/xxx/global/httpHealthChecks/my-health-check'.
This TCP/UDP/SSL backend service only supports HealthCheck"

I've also tried setting healthCheck to the hardcoded self link (projects/xxx/global/httpHealthChecks/my-health-check) but the error persists.

bohdanyurov-gl commented 5 years ago

Hi @claudiobizzotto!

It looks like you are using http healthcheck with TCP backend service. Could you please share your backend service config?

claudiobizzotto commented 5 years ago

Thanks for looking into this, @bohdanyurov-gl. Here's my template:

def GenerateConfig(context):
    return {
        'resources': [{
            'name': 'yyy-instance-group',
            'type': 'managed_instance_group.py',
            'properties': {
                'region': 'us-east1-b',
                'baseInstanceName': 'yyy',
                'targetSize': 3,
                'instanceTemplate': {
                    'name': 'yyy-instance-template',
                    'diskImage': 'projects/ubuntu-os-cloud/global/images/family/ubuntu-1804-lts',
                    'network': ${network-link},
                    'subnetwork': ${subnetwork-link},
                    'machineType': 'n1-standard-1'
                }
            }
        }, {
            'name': 'yyy-health-check',
            'type': 'healthcheck.py',
            'properties': {
                'checkIntervalSec': 5,
                'timeoutSec': 5,
                'unhealthyThreshold': 2,
                'healthyThreshold': 2,
                'port': 80,
                'healthcheckType': 'HTTP'
            }
        }, {
            'name': 'yyy-external-load-balancer',
            'type': 'external_load_balancer.py',
            'properties': {
                'portRange': 80,
                 'backendServices': [{
                     'name': 'backend-service',
                     'portName': 'http',
                     'healthCheck': '$(ref.yyy-health-check.selfLink)',
                     'backends': [{
                         'group': '$(ref.yyy-instance-group.instanceGroupSelfLink)'
                     }]
                 }]
            }
        }]
    }
claudiobizzotto commented 5 years ago

Update: I can make this work when all of health check, managed instance group and external load balancer are of type HTTP (i.e. they listen on port 80).

However, instead of that setup, I would like to have everything on port 80 except for the load balancer, which should listen on port 443 (for SSL/HTTPS).

And that's where the problem is. When I assign an SSL certificate to the load balancer and tell it to use portRange 443, it fails with this error message:

ERROR: (gcloud.deployment-manager.deployments.create) Error in Operation [operation...]: errors:
- code: RESOURCE_ERROR
  location: /deployments/nginx/resources/nginx-backend-service
  message: "{\"ResourceType\":\"compute.v1.backendService\",\"ResourceErrorCode\"\
    :\"400\",\"ResourceErrorMessage\":{\"code\":400,\"errors\":[{\"domain\":\"global\"\
    ,\"message\":\"Invalid value for field 'resource.healthChecks[0]': 'projects/my-project4-staging-service/global/httpHealthChecks/nginx-health-check'.\
    \ This HTTPS/HTTP2 backend service supports HealthCheck and HttpsHealthCheck\"\
    ,\"reason\":\"invalid\"}],\"message\":\"Invalid value for field 'resource.healthChecks[0]':\
    \ 'projects/my-project4-staging-service/global/httpHealthChecks/nginx-health-check'.\
    \ This HTTPS/HTTP2 backend service supports HealthCheck and HttpsHealthCheck\"\
    ,\"statusMessage\":\"Bad Request\",\"requestPath\":\"https://www.googleapis.com/compute/v1/projects/my-project4-staging-service/global/backendServices\"\
    ,\"httpMethod\":\"POST\"}}"

Here's the load balancer definition:

{
    'name': 'nginx-external-load-balancer',
    'type': 'external_load_balancer.py',
    'properties': {
        'IPAddress': 'https://www.googleapis.com/compute/v1/projects/my-project4-staging-service/global/addresses/nginx-ip',
        'portRange': 443,
        'backendServices': [{
            'name': 'nginx-backend-service',
            'portName': 'nginx-port',
            'healthCheck': getHealthCheckLink(context.env['project']),
            'backends': [{
                'group': '$(ref.nginx-managed-instance-group.instanceGroupSelfLink)'
            }]
        }],
        'ssl': {
            'certificate': {
                'url': getSSLCertificateLink(context.env['project'])
            }
        },
        'urlMap': {
            'defaultService': 'nginx-backend-service'
        }
    }
}

I'm using a few Python variables and Deployment Manager refs above but those are not causing any sort of problem, so much so that I can keep them and still successfully perform a deployment, as long as I'm not using SSL/port 443.