Using Kustomize to replace the host in IngressRoute YAML of Traefik

203 Views Asked by At

I am using Traefik ingress controller for my kubernetes cluster.

I have defined a IngressRoute of Traefik :

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: my-app-route
spec:
  entryPoints:
  - web
  routes:
  - match: Host(``) # I want to fill in the value of host in kustomization.yml 
    kind: Rule
    services:
    - name: my-app
      port: 8000

I am using Kustomize to manage my k8s manifests.

I would like to replace or fill-in the value of

Host(``)

to something like:

Host(`www.alpha.app.com`)

I tried in my kustomization.yml:

# generate config map for the host value
configMapGenerator:
- name: my-config
  literals:
  - host=www.alpha.app.com

# replace the value
replacements:
- source:
    kind: ConfigMap
    name: my-config
    fieldPath: data.host
  targets:
  - select:
      kind: IngressRoute
      name: my-app-route
    fieldPaths:
    - spec.routes.match

I know it won't work since the value contains string Host(``), but that is how far I can make. I want to keep the configMap data as it is, how to replace the Host(``) to Host(`www.alpha.app.com`) using Kustomize?

1

There are 1 best solutions below

2
VonC On BEST ANSWER

I know it won't work since the value contains string Host(``),

A possible workaround would be to set a placeholder value in your IngressRoute YAML where the host should be. For example, you might use __HOST_PLACEHOLDER__:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: my-app-route
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`__HOST_PLACEHOLDER__`)
    kind: Rule
    services:
    - name: my-app
      port: 8000

Then use the replacements field in your kustomization.yml to replace the entire spec.routes.match field (which contains the placeholder) with the value from the ConfigMap.

configMapGenerator:
- name: my-config
  literals:
  - host=www.alpha.app.com

replacements:
- source:
    kind: ConfigMap
    name: my-config
    fieldPath: data.host
  targets:
  - select:
      kind: IngressRoute
      name: my-app-route
    fieldPaths:
    - spec.routes.match

Note that kubernetes-sigs/kustomize issue 4012 discusses a similar use case, but it is stale (closed by k8s-ci-robot).

The discussion highlights that the ReplacementTransformer in Kustomize, at the time of that issue, had limitations when dealing with scenarios where only a part of a field's value (like a placeholder within a string) needs to be replaced. That is precisely the challenge you are facing with replacing __HOST_PLACEHOLDER__.

The issue references this Stack Overflow answer, which could involve defining the Host value as a shell variable: That will be used to create the patch file with the correct host value.

HOST_VALUE="www.alpha.app.com"

Then create an IngressRoute patch file, which will contain the IngressRoute configuration with the host value dynamically inserted.

cat > ./ingressroute-patch.yml <<EOF
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: my-app-route
spec:
  entryPoints:
    - web
  routes:
    - match: Host(\`$HOST_VALUE\`)
      kind: Rule
      services:
        - name: my-app
          port: 8000
EOF

And include the patch in kustomization.yaml, to be included as a strategic merge patch to apply the changes.

resources:
  - original-ingressroute.yaml  # Include your original IngressRoute resource

patchesStrategicMerge:
  - ingressroute-patch.yml  # That is the patch file we created

Kustomize will apply the ingressroute-patch.yml as a strategic merge patch to the original IngressRoute resource, effectively replacing the host part of the match field with the desired value.
However, patchesStrategicMerge is deprecated in Kustomize v5.0.0+, and use the patches field.

So that would be:

resources:
  - original-ingressroute.yaml  # Include your original IngressRoute resource

patches:
  - path: ingressroute-patch.yml
    target:
      group: traefik.io
      version: v1alpha1
      kind: IngressRoute
      name: my-app-route

And:

kustomize build . | kubectl apply -f -

That workaround would bypass the limitation of Kustomize regarding partial string replacements within a field. By pre-generating a patch file with the correct host value and including it in the kustomization.yaml, you could dynamically set the host in the IngressRoute.