<p>I am creating a new Operator with Kubebuilder to deploy a Kubernetes controller to manage a new CRD Custom Resource Definition.</p>
<p>This new CRD (let's say is called <code>MyNewResource</code>), needs to list/create/delete CronJobs.</p>
<p>So in the Controller Go code where the <code>Reconcile(...)</code> method is defined I added a new RBAC comment to allow the reconciliation to work on CronJobs (see <a href="https://book.kubebuilder.io/reference/markers/rbac.html" rel="nofollow noreferrer">here</a>):</p>
<pre class="lang-golang prettyprint-override"><code>//+kubebuilder:rbac:groups=batch,resources=cronjobs,verbs=get;list;watch;create;update;patch;delete
</code></pre>
<p>However after building pushing and deploying the Docker/Kubernetes controller (repo <code>myrepo</code>, <code>make manifests</code>, then <code>make install</code>, then <code>make docker-build docker-push</code>, then <code>make deploy</code>), then in the logs I still see:</p>
<pre><code>E0111 09:35:18.785523       1 reflector.go:138] pkg/mod/k8s.io/client-go@v0.22.1/tools/cache/reflector.go:167: Failed to watch *v1beta1.CronJob: failed to list *v1beta1.CronJob: cronjobs.batch is forbidden: User &quot;system:serviceaccount:myrepo-system:myrepo-controller-manager&quot; cannot list resource &quot;cronjobs&quot; in API group &quot;batch&quot; at the cluster scope
</code></pre>
<p>I also see issues about the cache, but they might not be related (not sure):</p>
<pre><code>2022-01-11T09:35:57.857Z        ERROR   controller.mynewresource        Could not wait for Cache to sync        {&quot;reconciler group&quot;: &quot;mygroup.mydomain.com&quot;, &quot;reconciler kind&quot;: &quot;MyNewResource&quot;, &quot;error&quot;: &quot;failed to wait for mynewresource caches to sync: timed out waiting for cache to be synced&quot;}
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start
        /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.10.0/pkg/internal/controller/controller.go:234
sigs.k8s.io/controller-runtime/pkg/manager.(*controllerManager).startRunnable.func1
        /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.10.0/pkg/manager/internal.go:696
2022-01-11T09:35:57.858Z        ERROR   error received after stop sequence was engaged  {&quot;error&quot;: &quot;leader election lost&quot;}
2022-01-11T09:35:57.858Z        ERROR   setup   problem running manager {&quot;error&quot;: &quot;failed to wait for mynewresource caches to sync: timed out waiting for cache to be synced&quot;}
</code></pre>
<p>How can I allow my new Operator to deal with CronJobs resources?</p>
<p>At the moment basically I am not able to create new CronJobs programmatically (Go code) when I provide some YAML for a new instance of my CRD, by invoking:</p>
<pre><code>kubectl create -f mynewresource-project/config/samples/
</code></pre>

<p>You need to create new Role or ClusterRole (depending if you want your permissions to be namespaced or cluster-wide) and bind that to your <code>system:serviceaccount:myrepo-system:myrepo-controller-manager</code> user using RoleBinding/ClusterRoleBinding. I will provide examples for cluster-wide configuration.</p>
<p>ClusterRole:</p>
<pre><code>apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cronjobs-role
rules:
- apiGroups: [&quot;&quot;]
  resources: [&quot;cronjobs&quot;]
  verbs: [&quot;get&quot;, &quot;watch&quot;, &quot;list&quot;, &quot;create&quot;, &quot;update&quot;, &quot;patch&quot;, &quot;delete&quot;]
</code></pre>
<p>Then, bind that using ClusterRoleBinding:</p>
<pre><code>apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cronjobs-rolebinding
subjects:
- kind: User
  name: system:serviceaccount:myrepo-system:myrepo-controller-manager
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cronjob-role
  apiGroup: rbac.authorization.k8s.io
</code></pre>
<p>Judging from your logs you might want to use <code>batch</code> apiGroup but I'll leave more generic example. More about k8s RBAC <a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/" rel="nofollow noreferrer">here</a>.</p>
<p><strong>Kubebuilder</strong></p>
<p>With Kubebuilder the ClusterRole and the ClusterRoleBinding YAML code is autogenerated and stored in the <code>config/rbac/</code> directory.</p>
<p>To grant the binding on all groups (rather than just <code>batch</code>), you can place the Go comment with an asterisk like this:</p>
<pre class="lang-golang prettyprint-override"><code>//+kubebuilder:rbac:groups=*,resources=cronjobs,verbs=get;list;watch;create;update;patch;delete
</code></pre>
<p>This will change the autogenerated YAML for the <code>ClusterRole</code> to:</p>
<pre><code>rules:
 - apiGroups:
   - '*' # instead of simply: batch
</code></pre>
<p>When deploying the updated operator, then the controller should be able to list/create/delete CronJobs.</p>
<p>See here for a <a href="https://book.kubebuilder.io/reference/markers/rbac.html" rel="nofollow noreferrer">reference RBAC for Kubebuilder comments</a></p>
