How to define a Kubernetes Service with Terraform and ClusterIP

12/23/2019

I can define a service just fine with NodePort or LoadBalancer, but when I try and use ClusterIP Terraform gives me this message

Failed to update service: Service "hello-service" is invalid: spec.ports[0].nodePort: Forbidden: may not be used when `type` is 'ClusterIP'

It's an odd message because I'm not supplying a nodePort. Presumably it is defaulting to something ClusterIP doesn't want. This is my service definition:

resource "kubernetes_service" "hello-service" {
  metadata {
    name = "hello-service"
    labels = {
      app = "hello"
    }
  }
  spec {
    type = "ClusterIP" 
    selector = {
      app = "hello"
    }
    port {
      port        = 80
      target_port = 8080
      protocol = "TCP"
    }

  }
}

I've been over the docs and haven't seen anything that has to be different for ClusterIP. What did I miss?

terraform --version
Terraform v0.12.4
+ provider.google v3.3.0
+ provider.kubernetes v1.10.0

Running on GCP

Thanks.

-- RogerParkinson
kubernetes
terraform

1 Answer

12/31/2019
  1. Please try using $ kubectl apply -f your-service-conf-file.yaml --force

  2. You can also execute $ kubectl replace command

    Note: it requires specifying the clusterIP field to be the same IP as the allocated ClusterIP of this service

  3. You can use helm to fix the issue too:

        - port: {{ .Values.service.externalPort }} {{- if (eq .Values.service.type "ClusterIP") }}
          nodePort: null {{- end }}
          targetPort: {{ .Values.service.internalPort }}
          protocol: TCP
          name: {{ .Values.service.name }}

    This only works after the first install. So there's no "declarative" workaround, you need to change your service manually.

  4. Finally workaround might be deleting the service first: $ kubectl delete svc my-nginx

    Then you can create service with poper type.

More information you can find here: service-types-issue.

-- MaggieO
Source: StackOverflow