2
votes

I have a terraform code which will deploy the frontend application and have ingress.yaml helm chart.

ingress.yaml

{{- if .Values.ingress.enabled -}}
{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
  name: {{ .Values.global.namespace }}-ingress
  namespace: {{ .Values.global.namespace }}
  labels:
    {{- include "test-frontend.labels" . | nindent 4 }}
  annotations:
    kubernetes.io/ingress.class: "gce-internal"
    kubernetes.io/ingress.allow-http: "false"
spec:
  {{- if .Values.ingress.tls }}
  tls:
    {{- range .Values.ingress.tls }}
    - hosts:
        {{- range .hosts }}
        - {{ . | quote }}
        {{- end }}
      secretName: {{ .secretName }}
    {{- end }}
  {{- end }}
  rules:
    {{- range .Values.ingress.hosts }}
    - host: {{ .host | quote }}
      http:
        paths:
          {{- range .paths }}
          - path: {{ .path }}
            backend:
              serviceName: {{ .servicename }}
              servicePort: {{ .serviceport }}
          {{- end }}
    {{- end }}
  {{- end }}

values.yaml

ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: "gce-internal"
    kubernetes.io/ingress.regional-static-ip-name : "ingress-internal-static-ip"
    kubernetes.io/ingress.allow-http: "false"
  hosts:
    - host: test-dev.test.com
      paths:
      - path: "/*"
        servicename: test-frontend-service
        serviceport: 80
      - path: "/api/*"
        servicename: test-backend-service
        serviceport: 80
  tls:
  - hosts:
    - test-dev.test.com
    secretName: ingress-tls-credential-file
    type: kubernetes.io/tls
    crt: <<test.pem value>>
    key: <<test.key value>>

The terraform apply command ran successfully. In GCP also the certificate is accepted and ingress in up and running inside Kubernetes Service in GCP. But If I pass the .crt and .key as a file in values.yaml in terraform code

ingress:
      enabled: true
      annotations:
        kubernetes.io/ingress.class: "gce-internal"
        kubernetes.io/ingress.regional-static-ip-name : "ingress-internal-static-ip"
        kubernetes.io/ingress.allow-http: "false"
      hosts:
        - host: test-dev.test.com
          paths:
          - path: "/*"
            servicename: test-frontend-service
            serviceport: 80
          - path: "/api/*"
            servicename: test-backend-service
            serviceport: 80
      tls:
      - hosts:
        - test-dev.test.com
        secretName: ingress-tls-credential-file
        type: kubernetes.io/tls
        crt: file(../../.secret/test.crt)
        key: file(../../.secret/test.key)

The values.yaml will send the certificate to helm->template->secret.yaml which will create the secrets(ingress-tls-credential-file)

secret.yaml

{{- if .Values.ingress.tls }}
{{- $namespace := .Values.global.namespace }}
{{- range .Values.ingress.tls }}
apiVersion: v1
kind: Secret
metadata:
  name: {{ .secretName }}
  namespace: {{ $namespace }}
  labels:
    {{- include "test-frontend.labels" $ | nindent 4 }}
type: {{ .type }}
data:
  tls.crt: {{ toJson .crt | b64enc | quote }}
  tls.key: {{ toJson .key | b64enc | quote }}
{{- end }}
{{- end }}

We are getting below error in GCP -> Kubernetes Engine -> Service & Ingress. How to pass the files to the values.yaml file.

Error syncing to GCP: error running load balancer syncing routine: loadbalancer 6370cwdc-isp-isp-ingress-ixjheqwi does not exist: Cert creation failures - k8s2-cr-6370cwdc-q0ndkz9m629eictm-ca5d0f56ba7fe415 Error:googleapi: Error 400: The SSL certificate could not be parsed., sslCertificateCouldNotParseCert

2

2 Answers

2
votes

So google can accept your cert and key files, you need to make sure they have the proper format as per next steps

  1. You need to first format them creating a Self Managed SSL Certificate resource with your existing files using you GCP Cloud Shell
gcloud compute ssl-certificates create CERTIFICATE_NAME \
    --certificate=CERTIFICATE_FILE \
    --private-key=PRIVATE_KEY_FILE \
    --region=REGION \
    --project=PROJECT_ID

Then you need to complete a few more steps to make sure you have all the parameters required in your .yaml file and that you have the proper services enable to accept the information coming from it (you may already have completed them):

  1. Enable Kubernetes Engine API by running the following command:
gcloud services enable container.googleapis.com \
  --project=PROJECT_ID
  1. Create a GKE cluster:
gcloud container clusters create CLUSTER_NAME \
    --release-channel=rapid \
    --enable-ip-alias \
    --network=NETWORK_NAME \
    --subnetwork=BACKEND_SUBNET_NAME \
    --scopes=https://www.googleapis.com/auth/cloud-platform \
    --region=REGION --machine-type=MACHINE_TYPE \
    --project=PROJECT_ID
  • The cluster is created in the BACKEND_SUBNET_NAME.
  • The cluster uses GKE version is 1.18.9-gke.801 or later.
  • The cluster is created with the Cloud Platform scope.
  • The cluster is created with the desired service account you would like to use to run the - application.
  • The cluster is using n1-standard-4 machine type or better.
  1. Enable IAP by doing the following steps:
echo -n 'CLIENT_ID' | base64
echo -n 'CLIENT_SECRET' | base64
  1. Create an internal static IP address, and reserve a static IP address for your load balancer
gcloud compute addresses create STATIC_ADDRESS_NAME \
    --region=REGION --subnet=BACKEND_SUBNET_NAME \
    --project=PROJECT_ID
  1. Get the static IP address by running the following command:
gcloud compute addresses describe STATIC_ADDRESS_NAME \
    --region=REGION \
    --project=PROJECT_ID

7.Create the values YAML file by copying the gke_internal_ip_config_example.yaml and renaming it to PROJECT_ID_gke_config.yaml:

clientIDEncoded: Base64 encoded CLIENT_ID from earlier step.
clientSecretEncoded: Base64 encoded CLIENT_SECRET from earlier step.
certificate.name: CERTIFICATE_NAME that you have created earlier.
initialEmail: The INITIAL_USER_EMAIL email of the initial user who will set up Custom Governance.
staticIpName: STATIC_ADDRESS_NAME that you created earlier.

Try again your deployment after completing above steps.

0
votes

You seem to mix a secret and a direct definition. You need first to create the ingress-tls-credential-file secret then link it in your ingress definition like the example https://kubernetes.io/fr/docs/concepts/services-networking/ingress/#tls

apiVersion: v1
data:
  tls.crt: file(../../.secret/test.crt)
  tls.key: file(../../.secret/test.key)
kind: Secret
metadata:
  name: ingress-tls-credential-file
  namespace: default
type: kubernetes.io/tls

Then clean your ingress

ingress:
      enabled: true
      annotations:
        kubernetes.io/ingress.class: "gce-internal"
        kubernetes.io/ingress.regional-static-ip-name : "ingress-internal-static-ip"
        kubernetes.io/ingress.allow-http: "false"
      hosts:
        - host: test-dev.test.com
          paths:
          - path: "/*"
            servicename: test-frontend-service
            serviceport: 80
          - path: "/api/*"
            servicename: test-backend-service
            serviceport: 80
      tls:
      - hosts:
        - test-dev.test.com
        secretName: ingress-tls-credential-file
        type: kubernetes.io/tls