Search code examples
kubernetespipelineazure-akscicdflux

How to patch only one key(hosts) of array element(spec.tls[0]) in flux kustomization?


Here is my ingress.yaml file that I'm trying to patch.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: notesapp-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: addon-http-application-routing
    cert-manager.io/cluster-issuer: letsencrypt
    nginx.ingress.kubernetes.io/proxy-body-size: 100m
    cert-manager.io/issue-temporary-certificate: "true"
    acme.cert-manager.io/http01-edit-in-place: "true"
spec:
  tls:
  - hosts:
    - notesapp.plan.com
    secretName: tls-secret
  rules:
  - host: notesapp.plan.com
    http: 
        paths: 
        - backend:
            service:
              name: notesapp-service
              port: 
                  number: 4000
          path: /
          pathType: Prefix 

I want to patch spec.tls[0].hosts url to custom url and patched like following. Here is ingress-patch.yaml file.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: notesapp-ingress
  namespace: default
spec:
  tls:
  - hosts:
    - staging.notesapp.plan.com
  rules:
    - host: staging.notesapp.plan.com

But after flux reconciled this patch, I see this error.

Here, Look.

kubectl describe ingress notesapp-ingress

Events:
  Type     Reason     Age                From                       Message
  ----     ------     ----               ----                       -------
  Warning  BadConfig  54m (x2 over 55m)  cert-manager-ingress-shim  Skipped a TLS block: spec.tls[0].secretName: Required value
  Normal   Sync       54m (x2 over 55m)  nginx-ingress-controller   Scheduled for sync

It looks like spec.tls[0] element was completely replaced with my patch instead of patching only spec.tls[0].hosts. How can I patch only spec.tls[0].hosts?

The problem: Imagine there are many other key-values in spec.tls[0] object(just like when I want to patch spec.rules[0].host). Then it would cause code duplication. For example, when I patch spec.rules[0].host value, I have to add this code, where it's not necessary for me.

   http: 
    paths: 
    - backend:
        service:
          name: notesapp-service
          port: 
              number: 4000
      path: /
      pathType: Prefix 

Solution

  • You are currently replacing the list and not only a single item.

    you can use the patch replace operation to target list item replacement, be careful when mixing with other operations like delete or add as index can change in such szenarios!

    ---
    # yaml-language-server: $schema=https://json.schemastore.org/kustomization
    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    resources:
      - ingress.yaml
    patches:
      - patch: |
          - op: replace
            path: /spec/tls/0/hosts/0
            value: staging.notesapp.plan.com
          - op: replace
            path: /spec/rules/0/host
            value: staging.notesapp.plan.com
        target:
          kind: Ingress
          version: v1
          name: notesapp-ingress
    

    As flux kustomization is using kustomize under the hood you can add this to a flux kustomization aswel.