<p>We are using an ingress (<code>kubernetes_ingress.db_admin_ingress</code>) to expose the service (<code>kubernetes_service.db_admin</code>) of a deployment (<code>kubernetes_deployment.db_admin</code>) in Google Kubernetes Engine (GKE) with Terraform.</p>
<p>When Terraform creates the ingress, a Level 7 Load Balancer is automatically created with a default health check:</p>
<ul>
<li>port: 80</li>
<li>path: <code>/</code></li>
<li>protocol: HTTP(S)</li>
</ul>
<p>Our deployment (<code>kubernetes_deployment.db_admin</code>) does not respond to the path <code>/</code> with a <code>200</code>, so the health check fails.</p>
<p>How can we change the path in the health check configuration?</p>
<pre class="lang-hcl prettyprint-override"><code>resource &quot;google_compute_managed_ssl_certificate&quot; &quot;db_admin_ssl_certificate&quot; {
  provider = google-beta

  name = &quot;db-admin-ssl-certificate&quot;

  managed {
    domains = [&quot;db.${var.domain}.&quot;]
  }
}

resource &quot;kubernetes_deployment&quot; &quot;db_admin&quot; {
  metadata {
    name = &quot;db-admin&quot;
    labels = {
      App = &quot;db-admin&quot;
    }
  }

  spec {
    replicas = 1
    selector {
      match_labels = {
        App = &quot;db-admin&quot;
      }
    }
    template {
      metadata {
        labels = {
          App = &quot;db-admin&quot;
        }
      }
      spec {
        container {
          image = &quot;dpage/pgadmin4:2022-01-10-1&quot;
          name  = &quot;db-admin&quot;
          env {
            name = &quot;PGADMIN_DEFAULT_EMAIL&quot;
            value = &quot;test@test.com&quot;
          }
          env {
            name = &quot;PGADMIN_DEFAULT_PASSWORD&quot;
            value = &quot;test&quot;
          }      

          port {
            container_port = 80
          }

          resources {}
        }
      }
    }
  }
}

resource &quot;kubernetes_service&quot; &quot;db_admin&quot; {
  metadata {
    name = &quot;db-admin&quot;
  }
  spec {
    selector = {
      App = kubernetes_deployment.db_admin.spec.0.template.0.metadata[0].labels.App
    }
    port {
      protocol    = &quot;TCP&quot;
      port        = 80
      target_port = 80
    }

    type = &quot;NodePort&quot;
  }
}

resource &quot;kubernetes_ingress&quot; &quot;db_admin_ingress&quot; {
  wait_for_load_balancer = true
  
  metadata {
    name = &quot;db-admin-ingress&quot;
    annotations = {
      &quot;ingress.gcp.kubernetes.io/pre-shared-cert&quot;   = google_compute_managed_ssl_certificate.db_admin_ssl_certificate.name
    }
  }

  spec {

    rule {
      http {
        path {
          backend {
            service_name = &quot;db-admin&quot;
            service_port = 80
          }

          path = &quot;/*&quot;
        }


      }
    }

  }
}
</code></pre>

<p>According to Google Kubernetes Engine (GKE) official documentation <a href="https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#health_checks" rel="nofollow noreferrer">here</a>, you are able to customize <code>ingress</code>/Level 7 Load Balancer health checks through either:</p>
<ul>
<li><p>the <code>readinessProbe</code> for the <code>container</code> within the <code>pod</code> your <code>ingress</code> is serving traffic to</p>
<p><strong>Warning</strong>: this method comes with warnings <a href="https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#interpreted_hc" rel="nofollow noreferrer">here</a></p>
</li>
<li><p>a <code>backendconfig</code> resource</p>
</li>
</ul>
<p>I would <strong>highly</strong> recommend creating a <code>backendconfig</code> resource.</p>
<p>Unfortunately, the <code>kubernetes</code> Terraform provider does <strong>not</strong> seem to support the <code>backendconfig</code> resource based on <a href="https://github.com/hashicorp/terraform-provider-kubernetes/issues/764" rel="nofollow noreferrer">this</a> GitHub issue.  This means that you can either:</p>
<ul>
<li>use the <code>kubernetes-alpha</code> provider (found <a href="https://registry.terraform.io/providers/hashicorp/kubernetes-alpha/0.6.0" rel="nofollow noreferrer">here</a>) to transcribe a YAML <code>backendconfig</code> manifest to HCL with the <code>manifest</code> argument for the only <code>kubernetes-alpha</code> resource: <code>kubernetes-manifest</code> (more on that <a href="https://registry.terraform.io/providers/hashicorp/kubernetes-alpha/latest/docs/resources/kubernetes_manifest" rel="nofollow noreferrer">here</a>)</li>
<li>use an unofficial provider (such as <code>banzaicloud/k8s</code> found <a href="https://github.com/banzaicloud/terraform-provider-k8s" rel="nofollow noreferrer">here</a>)</li>
<li>check the <code>backendconfig</code> manifest (as either JSON or YAML) into SCM</li>
</ul>
<p>A sample <code>backendconfig</code> YAML manifest:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: db-admin
  namespace: default
spec:
  healthCheck:
    checkIntervalSec: 30
    timeoutSec: 5
    healthyThreshold: 1
    unhealthyThreshold: 2
    type: HTTP
    requestPath: /v1/some/path
    port: 80
</code></pre>
<p><strong>Note</strong>: a <code>service</code> is needed to associate a <code>backendconfig</code> with an <code>ingress</code>/Level 7 Load Balancer:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Service
metadata:
  name: db-admin-ingress-backend-config
  labels:
    app: db-admin
  annotations:
    cloud.google.com/backend-config: '{&quot;ports&quot;: {&quot;80&quot;:&quot;db-admin&quot;}}'
    cloud.google.com/neg: '{&quot;ingress&quot;: true}'
spec:
  type: NodePort
  selector:
    app: db-admin
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
</code></pre>
<p>You can learn more about the <code>backendconfig</code> resource and the <code>service</code> it requires <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#exercise" rel="nofollow noreferrer">here</a>.</p>
