Configuring a delegate to assume an IAM Role in a EKS Cluster: Step-by-Step Guide

image

Introduction

Amazon Elastic Kubernetes Service (EKS) is a managed Kubernetes service that makes it easy to deploy, manage, and scale containerized applications on AWS. In this article, we will discuss how to create a service account and link it to a delegate using eksctl.

In AWS, you can associate a Kubernetes service account with an IAM role using the AWS Identity and Access Management (IAM) service. By associating a service account with an IAM role, you can grant permissions to the service account to access AWS resources, just as you would with an IAM user or role. This allows you to control access to your AWS resources at a more granular level and provides an additional layer of security for your Kubernetes cluster.

In summary, associating a Kubernetes service account with an IAM role in AWS is a powerful feature that allows you to run terraform scripts and modify your infrastructure, push images to your registry without allowing the entire cluster to do that, and much more.

Prerequisites

Tutorial

Step 1 - Create a policy

  1. If you want to associate an existing IAM policy to your IAM role, skip to the next step.
    a. Create a file that includes the permissions for the AWS services that you want your delegate to access. For a list of all actions for all AWS services, see the Service Authorization Reference.
    cat >my-policy.json <<EOF
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "ec2:DescribeRegions",
                "Resource": "*"
            }
        ]
    }
    EOF
    
    b. Create the IAM policy.
    aws iam create-policy --policy-name my-policy --policy-document file://my-policy.json
    

Step 2 - Create an IAM role and associate it with a Kubernetes service account.

In this particular case, we will be using eksctl exclusively to create the association. However, it’s important to note that this association can also be created manually. If you’re interested in doing so, you can refer to the “Step 2” tab under the “AWS CLI” section of the following article: Configuring a Kubernetes service account to assume an IAM role - Amazon EKS

To create a Kubernetes service account and associate it with an IAM role using eksctl , you can use the following command:

eksctl create iamserviceaccount --name my-service-account --namespace default --cluster my-cluster --role-name "my-role" \
    --attach-policy-arn arn:aws:iam::111122223333:policy/my-policy --approve
  • If the role or service account already exist, the previous command might fail.

To customize this command for your needs, replace the following parameters:

  • my-service-account: Replace this with the desired name for your Kubernetes service account.
  • default: Replace this with the delegate’s namespace.
  • my-cluster: Replace this with the name of your EKS cluster.
  • my-role: Replace this with the name of the IAM role that you want to associate with the service account. If it doesn’t already exist, eksctl creates it for you.
  • 111122223333: Replace this with your AWS account ID.
  • my-policy: Replace this with the name of an existing policy that you want to attach to the role.

Step 3 (optional) - Confirm that the role and service account are configured correctly.

To ensure that everything is set up correctly, please follow step 3 outlined in this article: Configuring a Kubernetes service account to assume an IAM role - Amazon EKS.

Step 4 - Associate the created service account to a delegate

To associate the service account that you created in Step 2, follow the steps below based on the method you used to install your delegate:

Method 1: Helm Chart

Use the following command to update your delegate’s service account:

helm upgrade -i helm-delegate --namespace <your-delegate-namespace> \
  harness-delegate/harness-delegate-ng \
  --set serviceAccount.create=false \
  --set serviceAccount.name=<service-account-name>

Method 2: Kubernetes Manifest

Include the serviceAccountName attribute under the object .spec.template.spec in your Kubernetes manifest, as shown below:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    harness.io/name: kubernetes-delegate
  name: kubernetes-delegate
  namespace: harness-delegate-ng
spec:
  replicas: 1
  selector:
    matchLabels:
      harness.io/name: kubernetes-delegate
  template:
    ...
    spec:
      serviceAccountName: <service-account-name>

Method 3: Terraform Helm Provider

Include the values object inside the module block containing the name and disabling the service account creation, as shown below:

module "delegate" {
  source = "harness/harness-delegate/kubernetes"
  version = "0.1.5"

  ...
  values = {
    serviceAccount = {
      create = false
      name = "<service-account-name>"
    }
  }
}

Conclusion

In conclusion, we have learned how to create a service account and link it to a delegate in an EKS cluster at AWS. This powerful feature allows you to control access to your AWS resources at a more granular level and provides an additional layer of security for your Kubernetes cluster. Once you have associated a Kubernetes service account with an IAM role, you can grant permissions to the service account to access AWS resources, such as running terraform scripts, modifying your infrastructure, and pushing images to your registry.
To test if everything is working, you can run a terraform plan or aws-cli command inside a CD Stage, forcing the delegate selector to the one in which you updated the service account.
If you have any suggestions on how to improve this article or specific examples of permissions-related issues that may be of use to others, please leave a comment with the information as this document is intended to evolve over time. If this article cannot resolve your issue, don’t hesitate to contact Harness support through the Zendesk portal or at support@harness.io.

2 Likes