Configuring the VPC CNI plugin to use IAM roles for service accounts - Amazon EKS

Configuring the VPC CNI plugin to use IAM roles for service accounts

The Amazon VPC CNI plugin for Kubernetes is the networking plugin for pod networking in Amazon EKS clusters. The CNI plugin is responsible for allocating VPC IP addresses to Kubernetes nodes and configuring the necessary networking for pods on each node. The plugin:

  • Requires IAM permissions, provided by the AWS managed policy AmazonEKS_CNI_Policy, to make calls to AWS APIs on your behalf.

  • Creates and is configured to use a service account named aws-node when it's deployed. The service account is bound to a Kubernetes clusterrole named aws-node, which is assigned the required Kubernetes permissions.

Note

Regardless of whether you configure the VPC CNI plugin to use IAM roles for service accounts, the pods also have access to the permissions assigned to the Amazon EKS node IAM role, unless you block access to IMDS. For more information, see Restricting access to the IMDS and Amazon EC2 instance profile credentials.

[eksctl]

  1. Create an IAM role and attach the AmazonEKS_CNI_Policy managed IAM policy with the following command. Replace <cluster_name> with your own value. This command creates an IAM OIDC provider for your cluster if it doesn't already exist. It then deploys an AWS CloudFormation stack that creates an IAM role, attaches the AmazonEKS_CNI_Policy AWS managed policy to it, and annotates the existing aws-node service account with the ARN of the IAM role.

    eksctl create iamserviceaccount \ --name aws-node \ --namespace kube-system \ --cluster <cluster_name> \ --attach-policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \ --approve \ --override-existing-serviceaccounts
  2. Describe one of the pods and verify that the AWS_WEB_IDENTITY_TOKEN_FILE and AWS_ROLE_ARN environment variables exist.

    kubectl exec -n kube-system aws-node-<9rgzw> env | grep AWS

    Output:

    AWS_VPC_K8S_CNI_LOGLEVEL=DEBUG AWS_ROLE_ARN=arn:aws:iam::<111122223333>:role/eksctl-prod-addon-iamserviceaccount-kube-sys-Role1-<V66K5I6JLDGK> AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token

[AWS Management Console]

Prerequisite

You must have an existing IAM OIDC provider for your cluster. To determine whether you already do or to create one, see Create an IAM OIDC provider for your cluster.

To create your CNI plugin IAM role with the AWS Management Console

  1. In the navigation panel, choose Roles, Create Role.

  2. In the Select type of trusted entity section, choose Web identity.

  3. In the Choose a web identity provider section:

    1. For Identity provider, choose the URL for your cluster.

    2. For Audience, choose sts.amazonaws.com.

  4. Choose Next: Permissions.

  5. In the Attach Policy section, select the AmazonEKS_CNI_Policy policy to use for your service account.

  6. Choose Next: Tags.

  7. On the Add tags (optional) screen, you can add tags for the account. Choose Next: Review.

  8. For Role Name, enter a name for your role, such as AmazonEKSCNIRole, and then choose Create Role.

  9. After the role is created, choose the role in the console to open it for editing.

  10. Choose the Trust relationships tab, and then choose Edit trust relationship.

  11. Find the line that looks similar to the following:

    "oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com"

    Change the line to look like the following line. Replace <EXAMPLED539D4633E53DE1B716D3041E> (including <>)with your cluster's OIDC provider ID and replace <region-code> with the Region code that your cluster is in.

    "oidc.eks.<region-code>.amazonaws.com/id/<EXAMPLED539D4633E53DE1B716D3041E>:sub": "system:serviceaccount:kube-system:aws-node"
  12. Choose Update Trust Policy to finish.

To annotate the aws-node Kubernetes service account with the IAM role

  1. If you're using the Amazon EKS add-on with a 1.18 or later Amazon EKS cluster with platform version eks.3 or later, see Configure an Amazon EKS add-on, instead of completing this procedure. If you're not using the Amazon VPC CNI Amazon EKS add-on, then use the following command to annotate the aws-node service account with the ARN of the IAM role that you created previously. Be sure to substitute your own values for the <example values> to use with your pods.

    kubectl annotate serviceaccount \ -n kube-system aws-node \ eks.amazonaws.com/role-arn=arn:aws:iam::<AWS_ACCOUNT_ID>:role/<AmazonEKSCNIRole>
  2. Delete and re-create any existing pods that are associated with the service account to apply the credential environment variables. The mutating web hook does not apply them to pods that are already running. The following command deletes the existing the aws-node DaemonSet pods and deploys them with the service account annotation.

    kubectl delete pods -n kube-system -l k8s-app=aws-node
  3. Confirm that the pods all restarted.

    kubectl get pods -n kube-system -l k8s-app=aws-node
  4. Describe one of the pods and verify that the AWS_WEB_IDENTITY_TOKEN_FILE and AWS_ROLE_ARN environment variables exist.

    kubectl exec -n kube-system aws-node-<9rgzw> env | grep AWS

    Output:

    AWS_VPC_K8S_CNI_LOGLEVEL=DEBUG AWS_ROLE_ARN=arn:aws:iam::<AWS_ACCOUNT_ID>:role/<IAM_ROLE_NAME> AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token

Remove the CNI policy from the node IAM role

If your Amazon EKS node IAM role currently has the AmazonEKS_CNI_Policy IAM policy attached to it, and you've created a separate IAM role, attached the policy to it instead, and assigned it to the aws-node Kubernetes service account, then we recommend that you remove the policy from your node role.

  1. Open the IAM console at https://console.aws.amazon.com/iam/.

  2. In the left navigation, choose Roles, and then search for your node instance role.

  3. Choose the Permissions tab for your node instance role and then choose the X to the right of the AmazonEKS_CNI_Policy.

  4. Choose Detach to finish.