#  Multi-Tenancy on AWS EKS: Separating Teams with Namespaces and IAM

As your team and projects grow, managing a single EKS cluster can get complicated. You'll likely have different teams like a "**Backend Team**" and a "**Frontend Team**" all needing to deploy their applications. If everyone deploys to the same place, things can get messy. Resources can be over-consumed, security becomes a concern, and it's hard to tell who owns what.

The solution to this common problem is multi-tenancy. Multi-tenancy is the practice of having multiple tenants (in this case, teams or applications) share the same EKS cluster while being logically isolated from each other. This is a highly efficient and cost-effective way to manage your Kubernetes infrastructure.

This blog post will walk you through a simple yet powerful way to achieve multi-tenancy on AWS EKS using two fundamental concepts: Kubernetes Namespaces and AWS IAM for EKS. By the end, you will have a practical setup that provides clear separation and security for different teams.

### **The Problem: A Single, Shared Cluster**

Imagine a scenario where both the Backend Team and Frontend Team deploy their applications to the default namespace.

*   **Chaos**: Deployments might accidentally have the same names, leading to conflicts.
    
*   **Resource Hogs**: The Frontend Team's application could suddenly get a lot of traffic and use up all the cluster's CPU, making the Backend Team's services slow or unresponsive.
    
*   **Security Risks**: An engineer from the Backend Team might have permissions to accidentally delete a critical service belonging to the Frontend Team.
    
*   **No Ownership**: When something goes wrong, it's difficult to quickly figure out which team is responsible.
    

### **The Solution: Namespaces + IAM**

Our solution is to create a dedicated namespace for each team. A namespace is a virtual partition inside a Kubernetes cluster. It gives you a way to divide cluster resources and provide a scope for names. But just creating a namespace isn't enough; we need to enforce who can access what. This is where AWS IAM comes in.

AWS EKS has a powerful feature that lets you map AWS IAM roles directly to Kubernetes RBAC (Role-Based Access Control) permissions. This allows you to say, "The IAM role for the Backend Team's developers can only access the backend-team namespace, and nothing else."

Here's the plan:

*   **Create an EKS Cluster:** We'll start with a standard EKS cluster.
    
*   **Create Namespaces:** We'll create two namespaces, backend-team and frontend-team.
    
*   **Create IAM Roles:** We'll set up two IAM roles, BackendTeamDeveloper and FrontendTeamDeveloper.
    
*   **Map IAM to RBAC:** We'll use EKS's built-in access management to grant each IAM role specific permissions for their respective namespaces.
    
*   **Deploy and Demo:** We'll deploy a simple application for each team and demonstrate how they are isolated.
    

### **Practical Demo: Step-by-Step**

This demo assumes you have the AWS CLI and kubectl configured.

**Step 1: Create an EKS Cluster**

```yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: multi-tenancy-demo
  region: us-east-1
  version: "1.28"

managedNodeGroups:
- name: standard-nodes
  instanceType: t3.medium
  desiredCapacity: 2
```

Now, create the cluster:

```shell
eksctl create cluster -f cluster.yaml
```

**Step 2: Create Namespaces**

Once your cluster is active, let's create a dedicated namespace for each team.

```shell
kubectl create namespace backend-team
kubectl create namespace frontend-team
```

You can verify the namespaces are created with:

```shell
kubectl get namespaces
```

![](https://cdn.hashnode.com/uploads/covers/6338fc85e594fa4ba3b90a69/7111a968-d03c-487e-ad46-09745f6721ea.png align="center")

**Step 3: Create IAM Roles**

In the AWS Console, navigate to the IAM service and create two IAM roles:

*   BackendTeamDeveloper
    
*   FrontendTeamDeveloper
    

These roles are what your team members will assume to interact with the cluster. For this demo, you can leave the roles without any specific permissions initially. The EKS access management will handle the permissions for the cluster itself.

![](https://cdn.hashnode.com/uploads/covers/6338fc85e594fa4ba3b90a69/d7198816-3112-4906-affe-30fa50826f4b.png align="center")

#### **Step 4: Map IAM Roles to Namespaces and Kubernetes Role RoleBinding**

This is the most critical step for security. We'll use EKS's Access Management feature to map our IAM roles to specific permissions within the cluster.

You need to use the AWS CLI to create an Access Entry and Access Policy for each team. Replace 123456789 with your AWS account ID.

```shell
# For the Backend Team 

eksctl create accessentry --cluster multi-tenancy-demo \ --principal-arn arn:aws:iam::123456789:role/BackendTeamDeveloper \ --type STANDARD

# For the Frontend Team 

eksctl create accessentry --cluster multi-tenancy-demo \ --principal-arn arn:aws:iam::123456789:role/FrontendTeamDeveloper \ --type STANDARD
```

Now, we'll create the RBAC resources.

```yaml
# This Role defines permissions for the backend team within their namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: backend-team-developer-role
  namespace: backend-team
rules:
- apiGroups: ["", "apps", "extensions"] 
  resources: ["pods", "deployments", "services", "configmaps"] 
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list"]
---
# This RoleBinding links the IAM principal to the Role
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: backend-team-developer-rolebinding
  namespace: backend-team
subjects:
- kind: User
  name: arn:aws:iam::123456789:role/BackendTeamDeveloper # This must match the principal ARN
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: backend-team-developer-role
  apiGroup: rbac.authorization.k8s.io

```

```yaml
# This Role defines permissions for the frontend team within their namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: frontend-team-developer-role
  namespace: frontend-team
rules:
- apiGroups: ["", "apps", "extensions"]
  resources: ["pods", "deployments", "services", "configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
# This RoleBinding links the IAM principal to the Role
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: frontend-team-developer-rolebinding
  namespace: frontend-team
subjects:
- kind: User
 name: arn:aws:iam::123456789:role/FrontendTeamDeveloper # This must match the principal ARN
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: frontend-team-developer-role
  apiGroup: rbac.authorization.k8s.io

```

Apply these files to your cluster:

```shell
kubectl apply -f backend-team-rbac.yaml
kubectl apply -f frontend-team-rbac.yaml
```

### Step 5: Demoing the Isolation

Let's see how this works in practice.First, assume the BackendTeamDeveloper IAM role using the AWS CLI.

```shell
aws sts assume-role --role-arn arn:aws:iam::123456789012:role/BackendTeamDeveloper --role-session-name BackendTeamSession
```

Use the returned credentials to configure your AWS CLI session and verify identity

```shell
aws sts get-caller-identity
```

Now, try to deploy an Nginx server into the backend-team namespace.

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-app
  namespace: backend-team
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend-app
  template:
    metadata:
      labels:
        app: backend-app
    spec:
      containers:
      - name: nginx
        image: nginx:latest
```

Deploy the application:

```shell
kubectl apply -f backend-app.yaml
```

This should work perfectly. The pod will be created in the backend-team namespace.

Now, with the same IAM role (BackendTeamDeveloper), try to list pods in the frontend-team namespace:

```plaintext
Error from server (Forbidden): pods is forbidden: User "arn:aws:sts::123456789:assumed-role/BackendTeamDeveloper/..." cannot list resource "pods" in API group "" in the namespace "frontend-team"
```

Again, a Forbidden error confirms our security model is working perfectly.

### **Conclusion**

This hands-on guide confirms that secure multi-tenancy on AWS EKS is built on a two-step process: using eksctl to map IAM roles to Kubernetes identities, then using Kubernetes RBAC to enforce granular permissions. The Forbidden errors we encountered were the ultimate proof of a successful setup, confirming that our security model is fully functional and providing a robust foundation for shared EKS clusters.
