Create EKS Node IAM Role

Kubernetes agent, kubelet, runs on every Amazon EKS node and makes calls to multiple AWS APIs. To grant each node sufficient permissions to perform these actions, you need to create an IAM role. This section will guide you through creating this role for the nodes of your EKS cluster using AWS CloudFormation and GitOps.

Choose one of the following options to create an IAM role your your node group:

Check Your Environment

When working with AWS CloudFormation stacks to manage resources, not only do you need sufficient permissions on AWS CloudFormation, but also on the underlying resources that are defined in the template.

In order to create an IAM role with proper IAM policies attached to it for the nodes of your EKS cluster using AWS CloudFormation you need permissions for the following actions:

  • Deploy AWS CloudFormation stacks.
  • Create IAM roles.
  • Attach managed IAM policies to IAM roles.

Note

If you do not have the above permissions, contact your AWS administrator to grant sufficient permissions to your IAM user or deploy the below AWS CloudFormation stack for you.

Option 1: Create EKS Node IAM Role Automatically (preferred)

Create an IAM role for your node group by following the on-screen instructions on the rok-deploy user interface.

If rok-deploy is not already running, start it with:

root@rok-tools:~# rok-deploy --run-from eks-iam-node
../../../_images/eks-iam-node.png

Proceed to the Summary section.

Option 2: Create EKS Node IAM Role Manually

If you want to create an IAM role for your node group manually, follow the instructions below.

Procedure

  1. Go to your GitOps repository, inside your rok-tools management environment:

    root@rok-tools:~# cd ~/ops/deployments
    
  2. Set the name for the EKS node IAM role:

    root@rok-tools:~/ops/deployments# export EKS_IAM_NODE_ROLE=eksNodeRole
    
  3. Set the name of the CloudFormation stack you will deploy:

    root@rok-tools:~/ops/deployments# export EKS_IAM_NODE_CF=eksNodeRole
    
  4. Generate an AWS CloudFormation stack:

    root@rok-tools:~/ops/deployments# j2 rok/eks/eks-node-iam-role.yaml.j2 \
    > -o rok/eks/eks-node-iam-role.yaml
    

    Alternatively, download the eks-node-iam-role.yaml AWS CloudFormation Template provided below and use it locally.

    eks-node-iam-role.yaml.j2
    1AWSTemplateFormatVersion: "2010-09-09"
    2
    3Description: Amazon EKS - Node Group Role
    4-38
    4
    5Metadata:
    6 Rok::StackName: {{EKS_IAM_NODE_CF}}
    7
    8Mappings:
    9 ServicePrincipals:
    10 aws-cn:
    11 ec2: ec2.amazonaws.com.cn
    12 aws-us-gov:
    13 ec2: ec2.amazonaws.com
    14 aws:
    15 ec2: ec2.amazonaws.com
    16
    17Resources:
    18 eksNodeRole:
    19 Type: "AWS::IAM::Role"
    20 Properties:
    21 AssumeRolePolicyDocument:
    22 Version: "2012-10-17"
    23 Statement:
    24 - Effect: Allow
    25 Principal:
    26 Service:
    27 - !FindInMap [ServicePrincipals, !Ref "AWS::Partition", ec2]
    28 Action:
    29 - "sts:AssumeRole"
    30 ManagedPolicyArns:
    31 - !Sub "arn:${AWS::Partition}:iam::aws:policy/AmazonEKSWorkerNodePolicy"
    32 - !Sub "arn:${AWS::Partition}:iam::aws:policy/AmazonEKS_CNI_Policy"
    33 - !Sub "arn:${AWS::Partition}:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
    34 - !Sub "arn:${AWS::Partition}:iam::aws:policy/CloudWatchAgentServerPolicy"
    35 Path: /
    36 RoleName: {{EKS_IAM_NODE_ROLE}}
    37
    38Outputs:
    39 RoleArn:
    40 Description: The node instance role
    41 Value: !GetAtt eksNodeRole.Arn
  5. Save your state:

    root@rok-tools:~/ops/deployments# j2 deploy/env.eks-iam-node.j2 \
    > -o deploy/env.eks-iam-node
    
  6. Commit your changes:

    root@rok-tools:~/ops/deployments# git commit -am "Create EKS Node IAM Role"
    
  7. Deploy the AWS CloudFormation stack to create the EKS node IAM role:

    root@rok-tools:~/ops/deployments# aws cloudformation deploy \
    > --stack-name ${EKS_IAM_NODE_CF?} \
    > --template-file rok/eks/eks-node-iam-role.yaml \
    > --capabilities CAPABILITY_NAMED_IAM
    
    Waiting for changeset to be created..
    Waiting for stack create/update to complete
    Successfully created/updated stack - eksNodeRole
    

    Troubleshooting

    AccessDenied

    If the above command fails with an error message similar to the following:

    Αn error occurred (AccessDenied) when calling the DescribeStacks operation:
    User: arn:aws:iam::123456789012:user/user is not authorized to perform:
    cloudformation:DescribeStacks on resource: arn:aws:cloudformation:us-east-1:123456789012:stack/eksNodeRole/*
    

    it means your IAM user does not have sufficient permissions to perform an action necessary to deploy an AWS CloudFormation stack.

    To proceed, Check Your Environment and contact your AWS administrator to grant sufficient permissions to your IAM user or deploy the AWS CloudFormation stack for you.

    Failed to create/update stack

    If the above command fails with an error message similar to the following:

    Failed to create/update the stack. Run the following command
    to fetch the list of events leading up to the failure
    aws cloudformation describe-stack-events --stack-name eksNodeRole
    

    describe the events of the CloudFormation stack to identify the root cause of the failure:

    root@rok-tools:~/ops/deployments# aws cloudformation describe-stack-events --stack-name ${EKS_IAM_NODE_ROLE?}
    
    • A stack event like the following:

      {
         "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/eksNodeRole/599bc930-7b3f-11eb-ac1c-029efe3a90a0",
         "EventId": "eksNodeRole-CREATE_FAILED-2021-03-02T10:09:27.457Z",
         "StackName": "eksNodeRole",
         "LogicalResourceId": "eksNodeRole",
         "PhysicalResourceId": "",
         "ResourceType": "AWS::IAM::Role",
         "Timestamp": "2021-03-02T10:09:27.457000+00:00",
         "ResourceStatus": "CREATE_FAILED",
         "ResourceStatusReason": "eksNodeRole already exists",
         "ResourceProperties": "{\"ManagedPolicyArns\":[\"arn:aws:iam::aws:policy/AmazonEKSClusterPolicy\"],\"RoleName\":\"eksNodeRole\",\"AssumeRolePolicyDocument\":{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"sts:AssumeRole\"],\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"eks.amazonaws.com\"]}}]}}"
      }
      

      means that one or more resources that the AWS CloudFormation stack defines already exist, leading to name conflicts.

      To proceed, use the existing role, assuming it has the right policies attached, or create a new one by changing the variable's value in step 2 and following the guide again.

    • A stack event like the following:

      {
         "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/eksNodeRole/415eef80-7b46-11eb-b047-06980f530fec",
         "EventId": "eksNodeRole-CREATE_FAILED-2021-03-02T10:58:54.216Z",
         "StackName": "eksNodeRole",
         "LogicalResourceId": "eksNodeRole",
         "PhysicalResourceId": "",
         "ResourceType": "AWS::IAM::Role",
         "Timestamp": "2021-03-02T10:58:54.216000+00:00",
         "ResourceStatus": "CREATE_FAILED",
         "ResourceStatusReason": "API: iam:CreateRole User: arn:aws:iam::123456789012:user/user is not authorized to perform: iam:CreateRole on resource: arn:aws:iam::123456789012:role/eksNodeRole",
         "ResourceProperties": "{\"ManagedPolicyArns\":[\"arn:aws:iam::aws:policy/AmazonEKSClusterPolicy\"],\"RoleName\":\"eksClusterRole\",\"AssumeRolePolicyDocument\":{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"sts:AssumeRole\"],\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"eks.amazonaws.com\"]}}]}}"
      }
      

      means that your IAM user does not have sufficient permissions to create the resources that the AWS CloudFormation stack defines.

      To proceed, Check Your Environment and contact your AWS administrator to grant your IAM user sufficient permissions or deploy the AWS CloudFormation stack for you.

    ValidationError

    If the above command fails with an error message similar to the following:

    An error occurred (ValidationError) when calling the CreateChangeSet
    operation:
    Stack:arn:aws:cloudformation:us-east-1:123456789012:stack/eksNodeRole/671606f0-eb2b-11eb-8afb-0217413c9ed2
    is in ROLLBACK_COMPLETE state and can not be updated.
    

    delete the stack and deploy it again.

Verify

  1. Go to your GitOps repository, inside your rok-tools management environment:

    root@rok-tools:~# cd ~/ops/deployments
    
  2. Restore the required context from previous sections:

    root@rok-tools:~/ops/deployments# source <(cat deploy/env.{envvars-aws,eks-iam-node})
    
    root@rok-tools:~/ops/deployments# export AWS_ACCOUNT_ID EKS_IAM_NODE_ROLE
    
  3. Verify that the EKS node IAM role exists:

    root@rok-tools:~/ops/deployments# aws iam get-role \
    > --role-name ${EKS_IAM_NODE_ROLE?} \
    > --query Role.RoleName \
    > --output text && echo OK
    eksNodeRole
    OK
    
  4. Verify that your EKS node IAM role allows making calls to the necessary AWS APIs:

    root@rok-tools:~/ops/deployments# aws iam simulate-principal-policy \
    > --cli-input-yaml "$(j2 rok/eks/can-i/iam-node-all.yaml.j2)" | \
    >   jq -r '.EvaluationResults[].EvalDecision' | \
    >   sort -u
    allowed
    
    root@rok-tools:~/ops/deployments# aws iam simulate-principal-policy \
    > --cli-input-yaml "$(j2 rok/eks/can-i/iam-node-net.yaml.j2)" | \
    >   jq -r '.EvaluationResults[].EvalDecision' | \
    >   sort -u
    allowed
    
    root@rok-tools:~/ops/deployments# aws iam simulate-principal-policy \
    > --cli-input-yaml "$(j2 rok/eks/can-i/iam-node-cloudwatch.yaml.j2)" | \
    >   jq -r '.EvaluationResults[].EvalDecision' | \
    >   sort -u
    allowed
    

Summary

You have successfully created an IAM role for the nodes of your new EKS cluster using AWS CloudFormation and GitOps.

What's Next

The next step is to create an EKS cluster.