<p>I want to assign <code>RBAC</code> rule to a user providing access to all the resources except <code>'create'</code> and <code>'delete'</code> verb in <code>'namespace'</code> resource using Terraform.</p>
<p>Currently we have rule as stated below:</p>
<pre><code>rule {
    api_groups = [&quot;*&quot;]
    resources  = [&quot;*&quot;]
    verbs      = [&quot;*&quot;]
  }
</code></pre>

<p>As we can find in the <a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole" rel="nofollow noreferrer">Role and ClusterRole documentation</a>, permissions (rules) are purely additive - there are no &quot;deny&quot; rules:</p>
<blockquote>
<p>Role and ClusterRole
An RBAC Role or ClusterRole contains rules that represent a set of permissions. Permissions are purely additive (there are no &quot;deny&quot; rules).</p>
</blockquote>
<p>The list of possible verbs can be found <a href="https://kubernetes.io/docs/reference/access-authn-authz/authorization/#determine-the-request-verb" rel="nofollow noreferrer">here</a>:
<a href="https://i.stack.imgur.com/1KImX.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1KImX.png" alt="enter image description here" /></a></p>
<p><br>You need to provide all verbs that should be applied to the resources contained in the rule.<br />
Instead of:</p>
<pre><code>verbs      = [&quot;*&quot;]
</code></pre>
<p>Provide required verbs e.g.:</p>
<pre><code>verbs      = [&quot;get&quot;, &quot;list&quot;, &quot;patch&quot;, &quot;update&quot;, &quot;watch&quot;]
</code></pre>
<p><br>As an example, I've created an <code>example-role</code> <code>Role</code> and an <code>example_role_binding</code> <code>RoleBinding</code>.<br />
The <code>example_role_binding</code> <code>RoleBinding</code> grants the permissions defined in the <code>example-role</code> <code>Role</code> to user <code>john</code>.<br />
<strong>NOTE:</strong> For details on using the following resources, see the <a href="https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/role" rel="nofollow noreferrer">kubernetes_role</a> and <a href="https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/role_binding" rel="nofollow noreferrer">kubernetes_role_binding</a> resource documentation.</p>
<pre><code>resource &quot;kubernetes_role&quot; &quot;example_role&quot; {
  metadata {
    name      = &quot;example-role&quot;
    namespace = &quot;default&quot;
  }

  rule {
    api_groups = [&quot;*&quot;]
    resources  = [&quot;*&quot;]
    verbs      = [&quot;get&quot;, &quot;list&quot;, &quot;patch&quot;, &quot;update&quot;, &quot;watch&quot;]
  }
}

resource &quot;kubernetes_role_binding&quot; &quot;example_role_binding&quot; {
  metadata {
    name      = &quot;example_role_binding&quot;
    namespace = &quot;default&quot;
  }
  role_ref {
    api_group = &quot;rbac.authorization.k8s.io&quot;
    kind      = &quot;Role&quot;
    name      = &quot;example-role&quot;
  }

  subject {
    kind      = &quot;User&quot;
    name      = &quot;john&quot;
    api_group = &quot;rbac.authorization.k8s.io&quot;
  }
}
</code></pre>
<p>Additionally, I've created the <code>test_user.sh</code> Bash script to quickly check if it works as expected:<br />
<strong>NOTE:</strong> You may need to modify the variables <code>namespace</code>, <code>resources</code>, and <code>user</code> to fit your needs.</p>
<pre><code>$ cat test_user.sh
#!/bin/bash

namespace=default
resources=&quot;pods deployments&quot;
user=john

echo &quot;=== NAMESPACE: ${namespace} ===&quot;
for verb in create delete get list patch update watch; do
    echo &quot;-- ${verb} --&quot;
    for resource in ${resources}; do
        echo -n &quot;${resource}: &quot;
        kubectl auth can-i ${verb} ${resource} -n ${namespace} --as=${user}
    done
done

$ ./test_user.sh
=== NAMESPACE: default ===
-- create --
pods: no
deployments: no
-- delete --
pods: no
deployments: no
-- get --
pods: yes
deployments: yes
-- list --
pods: yes
deployments: yes
...
</code></pre>
