<p>I am trying to attach an IAM role to a pod's service account from within the POD in EKS.</p>
<pre><code>kubectl annotate serviceaccount -n $namespace $serviceaccount eks.amazonaws.com/role-arn=$ARN
</code></pre>
<p>The current role attached to the <code>$serviceaccount</code>is outlined below:</p>
<pre><code>apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: common-role
rules:
  - apiGroups: [&quot;&quot;]
    resources:
      - event
      - secrets
      - configmaps
      - serviceaccounts
     verbs:
      - get
      - create
</code></pre>
<p>However, when I execute the <code>kubectl</code> command I get the following:</p>
<pre><code>error from server (forbidden): serviceaccounts $serviceaccount is forbidden: user &quot;system:servi....&quot; cannot get resource &quot;serviceaccounts&quot; in API group &quot;&quot; ...
</code></pre>
<p>Is my role correct? Why can't I modify the service account?</p>

<p>Kubernetes by default will run the pods with <code>service account: default</code> which don`t have the right permissions. Since I cannot determine which one you are using for your pod I can only assume that you are using either default or some other created by you. In both cases the error suggest that the service account your are using to run your pod does not have proper rights.</p>
<p>If you run this pod with service account type default you will have add the appropriate rights to it. Alternative way is to run your pod with another service account created for this purpose. Here`s an example:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1  
kind: ServiceAccount  
metadata:  
   name: run-kubectl-from-pod 
</code></pre>
<p>Then you will have to create appropriate role (you can find full list of verbs <a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#role-v1-rbac-authorization-k8s-io" rel="nofollow noreferrer">here</a>):</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: rbac.authorization.k8s.io/v1  
kind: Role  
metadata:  
  name: modify-service-accounts
rules:  
  - apiGroups: [&quot;&quot;]  
    resources:  
      - serviceaccounts 
    verbs:  
      - get  
      - create 
      - patch 
      - list
</code></pre>
<p>I'm using here more verbs as a test. <code>Get</code> and <code>Patch</code> would be enough for this use case. I`m mentioning this since its best practice to provide as minimum rights as possible.</p>
<p>Then create your role accordingly:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: rbac.authorization.k8s.io/v1  
kind: RoleBinding  
metadata:  
name: modify-service-account-bind 
subjects:  
- kind: ServiceAccount  
  name: run-kubectl-from-pod 
roleRef:  
  kind: Role  
  name: modify-service-accounts 
  apiGroup: rbac.authorization.k8s.io
</code></pre>
<p>And now you just have reference that service account when your run your pod:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1  
kind: Pod  
metadata:  
  name: run-kubectl-in-pod 
spec:  
  serviceAccountName: run-kubectl-from-pod  
  containers:  
    - name: kubectl-in-pod  
      image: bitnami/kubectl 
      command: 
      - sleep 
      - &quot;3600&quot; 
</code></pre>
<p>Once that is done, you just exec into the pod:</p>
<pre><code>➜  kubectl-pod kubectl exec -ti run-kubectl-in-pod sh  
</code></pre>
<p>And then annotate the service account:</p>
<pre><code>$ kubectl get sa 
NAME                   SECRETS   AGE
default                1         19m
eks-sa                 1         36s
run-kubectl-from-pod   1         17m

$ kubectl annotate serviceaccount eks-sa eks.amazonaws.com/role-arn=$ARN
serviceaccount/eks-sa annotated

$ kubectl describe sa eks-sa 
Name:                eks-sa
Namespace:           default
Labels:              &lt;none&gt;
Annotations:         eks.amazonaws.com/role-arn: 
Image pull secrets:  &lt;none&gt;
Mountable secrets:   eks-sa-token-sldnn
Tokens:              &lt;none&gt;
Events:              &lt;none&gt;
</code></pre>
<p>If you encounter any issues with request being refused please start with reviewing <a href="https://kubernetes.io/docs/reference/access-authn-authz/authorization/#review-your-request-attributes" rel="nofollow noreferrer">your request attributes</a> and <a href="https://kubernetes.io/docs/reference/access-authn-authz/authorization/#determine-the-request-verb" rel="nofollow noreferrer">determine the appropriate request verb</a>.</p>
<p>You can also check your access with <code>kubectl auth can-i</code> command:</p>
<pre><code>kubectl-pod kubectl auth can-i patch serviceaccount 
</code></pre>
<p>API server will respond with simple <code>yes</code> or <code>no</code>.</p>
<hr />
<p><strong>Please Note</strong> that If you want to patch a service account to use an IAM role you will have delete and re-create any existing pods that are assocaited with the service account to apply credentials environment variables. You can read more about it <a href="https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html" rel="nofollow noreferrer">here</a>.</p>
<hr />
