1

I would like to transform a ClusterRoleBinding in a RoleBinding using kustomize-v4.0.5, and also set the namespace field for the RoleBinding and in an additional Deployment resource with the same value.

I succeed in doing that using files below:

cat <<EOF > kustomization.yaml 
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
patchesJson6902:
- patch: |-
    - op: replace
      path: /kind
      value: RoleBinding
    - op: add
      path: /metadata/namespace
      value: 
        <NAMESPACE>
  target:
    group: rbac.authorization.k8s.io
    kind: ClusterRoleBinding
    name: manager-rolebinding
    version: v1
resources:
- role_binding.yaml 
- service_account.yaml
namespace: <NAMESPACE>
EOF

cat <<EOF > role_binding.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: manager-rolebinding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: manager-role
subjects:
- kind: ServiceAccount
  name: controller-manager
  namespace: system 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: controller-manager
  namespace: system
spec:
  selector:
    matchLabels:
      control-plane: controller-manager
  replicas: 1
  template:
    metadata:
      labels:
        control-plane: controller-manager
    spec:
      containers:
      - command:
        - /manager
        args:
        - --enable-leader-election
        image: controller:latest
        name: manager
EOF

cat <<EOF > service_account.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: controller-manager
  namespace: system
EOF

However, in above example, I have to hardcode <NAMESPACE> in several places of my kustomization.yaml. Is there a way to change namespace value for these field without using sed, in 'pure' kustomize and without having to change manually values in kustomization.json?

Fabrice Jammes
  • 2,275
  • 1
  • 26
  • 39
  • In general, the `namespace` field does the trick. But it looks like you want to use Kustomize more lite an imperative tool, instead of a declarative workflow - as it is designed for. – Jonas Apr 02 '21 at 18:38
  • Thanks @Jonas in my example, unfortunately the `namespace` field alone does not do the trick. My use case is that I need to create a `kustomize` overlay which convert an upstream cluster-scoped operator to a namespace-scoped one, without editing the upstream yaml files (i.e. ClusterRoleBinding an al.). Could you please elaborate on the way of doing this in a more declarative way? – Fabrice Jammes Apr 02 '21 at 18:49
  • 1
    The declarative config management model requires you to save the full RoleBinding to your project. It is not intended to "change" from one kind to another with a transformation. – Jonas Apr 02 '21 at 18:52
  • LGTM, but then I'd also like not to create the upstream `ClusterRoleBinding`, which is actually in an external resource and not in my `kustomize build` directory. and I also want to keep the identical `roleRef` and `subjects` in the `RoleBinding` than in the `ClusterRoleBinding`, even if they change after an upstream update by third-party. So "changing" the resource was the only solution I could find, any other one is of course welcome! – Fabrice Jammes Apr 02 '21 at 18:57
  • Hi @Wytrzymały Wiktor, no progress with this. I ended up using `sed` on the generated `yaml` file. – Fabrice Jammes Apr 07 '21 at 11:12

1 Answers1

1

This is a community wiki answer. Feel free to expand it.

I have analyzed your issue and came to the following conclusions.

TL;DR: Unfortunately, the answer is: "not possible like you want it". The current workaround you are using with sed is the way to go. At the end of the day, even if a bit atypical, it is a practical solution.

First of all, the whole point of Kustomize is to apply different configurations from files or rather directories containing files to customize for multiple environments or the likes of environments. As such, if you know which values you would like to apply, than you would only have to include them in the corresponding overlay directory and apply whichever you would like to. For example, as part of the "development" and "production" overlays included here. That means hardcoding the namespace for each overlay.

But there is that question: "where do you get the namespace value from"? And, as a consequence, how dynamic it is - if not dynamic at all, simply one of a set of values, it is just a matter of using the approach I just described.

Let's assume it is fully dynamic:

There is a command for dynamic substitution of values: kustomize edit set but unfortunately it only takes these parameters: image, label, nameprefix, namespace, namesuffix, replicas so we cannot use it here (See the help for that command for more information). This is also an indication that dynamic substitution for arbitrary values has not been implemented yet.

I have also investigated other approaches and I can think of no "pure" Kustomize solution.

Wytrzymały Wiktor
  • 11,492
  • 5
  • 29
  • 37