🔒💻 Master EKS IRSA and Terraform for Fine-Grained AWS Resource Access Control on Kubernetes.🚀
Tags: tutorial, devops, aws, eks
Published: 2023-02-22 16:29:21

> [IRSA (IAM Roles for Service Accounts)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) is a feature of EKS (Amazon Elastic Kubernetes Service) that allows you to grant Kubernetes pods and containers permissions to AWS resources using IAM roles. This allows you to use IAM policies to control access to your AWS resources from your Kubernetes applications.

## Prerequisites
An AWS account with permissions to create EKS clusters and IAM roles.
The [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) are installed on your local machine.
A running EKS cluster with at least one node group. You can use [eksctl](https://eksctl.io/) or [terraform eks module](https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/latest) to spin up the EKS cluster

Let us begin by describing the steps we must follow to implement IRSA on the EKS cluster.

### Step 1: Create an IAM policy
The first step is to create an IAM policy that grants the necessary permissions to your EKS pods. You can use the following example policy as a starting point:

```hcl
resource "aws_iam_policy" "s3_access_policy" {
  name_prefix = "eks-s3-access-policy-"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect   = "Allow"
        Action   = [
          "s3:Get*",
          "s3:List*",
        ]
        Resource = "*"
      },
    ]
  })
}
```
This policy allows your pods to read and list objects in all S3 buckets in your AWS account. Replace the resource ARN with the ARN of the specific resource you want to grant access to.

### Step 2: Create an IAM role
Next, create an IAM role that your EKS pods can assume to gain the permissions defined in the IAM policy. You can use the following Terraform code to create a new IAM role:

```hcl
resource "aws_iam_role" "s3_access_role" {
  name               = "eks-s3-access"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect    = "Allow"
        Principal = {
          Service = "eks.amazonaws.com"
        }
        Action = "sts:AssumeRole"
      },
    ]
  })
}
```
Replace `eks-s3-access` with a name of your choice.

### Step 3: Attach the IAM policy to the IAM role
Once you've created the IAM role, attach the IAM policy you created in step 1 to the role using the following Terraform code:

```hcl
resource "aws_iam_role_policy_attachment" "s3_access_policy_attachment" {
  policy_arn = aws_iam_policy.s3_access_policy.arn
  role       = aws_iam_role.s3_access_role.name
}
```
Replace `aws_iam_policy.s3_access_policy.arn` with the ARN of the IAM policy you created in step 1, and `aws_iam_role.s3_access_role.name` with the name of the IAM role you created in step 2.

### Step 4: Create a Kubernetes service account
Next, create a Kubernetes service account that you can associate with the IAM role you created in step 2. Use the following Terraform code to create a new service account:

```hcl
resource "kubernetes_service_account" "s3_access_sa" {
  metadata {
    name = "s3-access-sa"
  }
}
```
> Note: If you want to create Kubernetes service account using terraform, you must use [Kubernetes Provider](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs) by terraform.

### Step 5: Annotate the service account with the IAM role ARN
To associate the Kubernetes service account with the IAM role you created in step 2, annotate the service account with the ARN of the role using the following Terraform code:


```hcl
resource "kubernetes_service_account_annotation" "s3_access_sa_annotation" {
  metadata {
    name = kubernetes_service_account.s3_access_sa.metadata.0.name
    namespace = "default"
  }
  annotations = {
    "eks.amazonaws.com/role-arn" = aws_iam_role.s3_access_role.arn
  }
}
```
Replace `aws_iam_role.s3_access_role.arn` with the ARN of the IAM role you created in step 2, and `kubernetes_service_account.s3_access_sa.metadata.0.name` with the name of the Kubernetes service account you created in step 4.

### Step 6: Deploy a sample pod
Finally, deploy a sample pod that uses the IAM role you created in step 2 to access an AWS resource. Use the following Terraform code to deploy a sample pod:

```hcl
resource "kubernetes_manifest" "sample_pod" {
  manifest = jsonencode({
    apiVersion = "v1"
    kind       = "Pod"
    metadata = {
      name = "sample-pod"
    }
    spec = {
      containers = [
        {
          name  = "sample-container"
          image = "nginx"
          volumeMounts = [
            {
              name      = "aws-credentials"
              mountPath = "/var/run/secrets/aws"
            },
          ]
          env = [
            {
              name  = "AWS_REGION"
              value = "us-west-2"
            },
          ]
        },
      ]
      volumes = [
        {
          name = "aws-credentials"
          projected = {
            sources = [
              {
                serviceAccountToken = {
                  path = "aws-credentials"
                  expirationSeconds = 86400
                }
              },
            ]
          }
        },
      ]
      serviceAccountName = kubernetes_service_account.s3_access_sa.metadata.0.name
    }
  })
}
```
This deploys a sample Nginx container that mounts the AWS credentials from the Kubernetes service account and sets the AWS region environment variable. Replace `kubernetes_service_account.s3_access_sa.metadata.0.name` with the name of the Kubernetes service account you created in step 4.
That's it! Once you apply these Terraform configurations, you should have a Kubernetes pod that has access to the AWS resource specified in the IAM policy you created in step 1, using the IAM role you created in step 2.

## Conclusion
In conclusion, EKS IRSA is a powerful feature that allows you to achieve fine-grained access control to AWS resources on Kubernetes clusters. With Terraform, you can easily automate the process of creating and managing IAM roles, Kubernetes service accounts, and their association, allowing you to streamline your infrastructure management workflow. By following this step-by-step guide, you can implement EKS IRSA with Terraform and take advantage of its benefits to achieve greater security and efficiency in your Kubernetes environment.