Use Case: Setting Up IRSA (IAM Roles for Service Accounts) in EKS Cluster Using Terraform

Use Case: Setting Up IRSA (IAM Roles for Service Accounts) in EKS Cluster Using Terraform

Let’s walk through a use case in the STAR (Situation, Task, Action, Result) method for setting up IAM Roles for Service Accounts (IRSA) in an AWS EKS cluster using Terraform. We will also explore best practices and benefits for this approach.


Use Case in STAR Method:

Situation:

You have an EKS cluster running in AWS, and you want to grant specific AWS permissions to workloads running inside the cluster (such as an application in a pod) securely. These workloads need to access AWS resources like S3 buckets, DynamoDB tables, or other AWS services. Instead of granting these permissions to EC2 instances or Kubernetes nodes, you need a more granular, pod-level permission model.

You decide to implement IAM Roles for Service Accounts (IRSA) in your EKS cluster to enable pods to assume IAM roles securely, following AWS best practices.


Task:

The goal is to:

  1. Set up IRSA for EKS workloads to assume IAM roles and securely interact with AWS resources without needing hardcoded AWS credentials.
  2. Use Terraform to automate the configuration of IRSA, making the solution repeatable and manageable at scale.
  3. Ensure that specific services within Kubernetes pods can access only the AWS resources they need, minimizing the blast radius of any potential security breach.

Action:

To implement this, you will:

  1. Create an OIDC identity provider for the EKS cluster.
  2. Create IAM roles with policies that grant the necessary AWS permissions.
  3. Create a Kubernetes service account that will assume the IAM role using IRSA.
  4. Use Terraform to automate the entire process.


Here’s the Terraform code to set up IRSA in an EKS cluster:

Sample Terraform Code for IRSA Setup:

provider "aws" {
  region = "us-west-2"
}

# EKS cluster setup
module "eks" {
  source          = "terraform-aws-modules/eks/aws"
  cluster_name    = "example-eks-cluster"
  cluster_version = "1.26"
  vpc_id          = "vpc-abcde123"
  subnets         = ["subnet-12345", "subnet-67890"]
}

# Create OIDC identity provider for the EKS cluster
resource "aws_iam_openid_connect_provider" "eks_oidc" {
  url = "https://oidc.eks.${module.eks.cluster_endpoint}:/idp/eks/${module.eks.cluster_name}"
  
  client_id_list = ["sts.amazonaws.com"]
  
  thumbprint_list = [
    "9a5d5a3beeb57414988dadd9b49d9b86949a9a9f"  # This is an example thumbprint; it should be updated accordingly
  ]
}

# Create IAM policy for the service account
resource "aws_iam_policy" "eks_s3_access_policy" {
  name        = "EKS-S3-Access-Policy"
  description = "Policy to allow access to S3 buckets"
  
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action   = "s3:ListBucket"
        Effect   = "Allow"
        Resource = "arn:aws:s3:::your-bucket-name"
      },
      {
        Action   = "s3:GetObject"
        Effect   = "Allow"
        Resource = "arn:aws:s3:::your-bucket-name/*"
      }
    ]
  })
}

# Create IAM role for the service account
resource "aws_iam_role" "eks_s3_access_role" {
  name               = "EKS-S3-Access-Role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect    = "Allow"
        Principal = {
          Federated = aws_iam_openid_connect_provider.eks_oidc.arn
        }
        Action    = "sts:AssumeRoleWithWebIdentity"
        Condition = {
          StringEquals = {
            "oidc.eks.${module.eks.cluster_endpoint}:sub" = "system:serviceaccount:default:s3-access-sa"
          }
        }
      }
    ]
  })
}

# Attach the policy to the IAM role
resource "aws_iam_role_policy_attachment" "eks_s3_access_attachment" {
  role       = aws_iam_role.eks_s3_access_role.name
  policy_arn = aws_iam_policy.eks_s3_access_policy.arn
}

# Create the Kubernetes service account that will assume the IAM role
resource "kubernetes_service_account" "s3_access_sa" {
  metadata = {
    name      = "s3-access-sa"
    namespace = "default"
  }
  automount_service_account_token = true
}

# Annotate the service account with the IAM role ARN
resource "kubernetes_service_account_iam_role_binding" "s3_access_binding" {
  metadata {
    name      = "s3-access-binding"
    namespace = kubernetes_service_account.s3_access_sa.metadata[0].namespace
  }

  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "Role"
    name      = aws_iam_role.eks_s3_access_role.name
  }

  subjects {
    kind      = "ServiceAccount"
    name      = kubernetes_service_account.s3_access_sa.metadata[0].name
    namespace = kubernetes_service_account.s3_access_sa.metadata[0].namespace
  }
}        

Explanation of the Terraform Code:

  1. aws_iam_openid_connect_provider: Creates an OIDC identity provider for the EKS cluster to allow the service account to assume the IAM role.
  2. IAM Policy: Defines a policy granting access to specific AWS resources (like S3).
  3. IAM Role: The IAM role is created with a trust relationship allowing the service account to assume it via OIDC.
  4. Kubernetes Service Account: This service account will assume the IAM role and be able to access AWS resources.
  5. IAM Role Binding: Binds the Kubernetes service account to the IAM role.

Result:

  1. Secure Permissions: The pod in the default namespace using the s3-access-sa service account now has the necessary permissions to access S3 resources securely.
  2. Granular Access: The access granted to the pod is specific to the resources it needs (in this case, access to a specific S3 bucket), reducing the risk of over-permissioning.
  3. Seamless Management: By using Terraform, the setup is automated, repeatable, and manageable as code, making future updates easy to handle without manual intervention.

Best Practices for IRSA Setup:

  1. Least Privilege: Always apply the principle of least privilege when defining IAM roles and policies. Only grant permissions required for the application to function.
  2. Use Specific Service Accounts: Create a separate service account for each application or service, and assign them only the permissions they need. This avoids the risk of over-permissioning.
  3. Use Role Policies Instead of Node Instance Profiles: Avoid assigning permissions to the EKS node instance profile. Use IRSA to assign specific roles to Kubernetes pods instead of granting EC2 instances broad access to AWS resources.
  4. Monitor IAM Roles and Service Accounts: Regularly review and audit the IAM roles and Kubernetes service accounts for compliance with security policies.
  5. Automate Updates Using Infrastructure-as-Code (IaC): Always manage your IRSA setup using Terraform or other IaC tools to ensure consistent and reproducible configurations.

Benefits of Using IRSA with EKS and Terraform:

  1. Security: IRSA allows your workloads to access AWS resources without needing to manage long-term AWS credentials (like access keys), significantly improving security.
  2. Granular Permissions: By using service accounts and IAM roles, you can assign fine-grained permissions to Kubernetes workloads, ensuring they can only access the specific resources they need.
  3. Simplified Role Management: IRSA simplifies the process of granting and managing access to AWS services for Kubernetes workloads. Terraform allows you to manage this configuration in a controlled and reproducible way.
  4. No Hardcoded Credentials: You don’t need to hardcode AWS credentials inside Kubernetes pods, which reduces the risk of exposing sensitive data.
  5. Scalability: As your application grows, managing permissions via IRSA scales more effectively compared to managing access on EC2 instances or node groups.
  6. Auditability: Using IAM roles for service accounts ensures that AWS resource access can be tracked and audited, providing better visibility into access controls.

By following best practices and implementing IRSA using Terraform, you can secure your AWS EKS workloads and enable them to interact with AWS resources in a way that is both scalable and manageable. This approach reduces the security risks associated with managing AWS credentials and access for Kubernetes workloads.


Join me in exploring the latest in AWS DevSecOps! Subscribe to the newsletter and follow for more insights. ????

?? Book 1:1 Connect: https://lnkd.in/dCgmt2hw

?? Join the AWS DevSecOps Community: https://lnkd.in/dDsf4rCv

?? Follow me on LinkedIn for more insights: https://lnkd.in/gy8xy2Gb

?? Subscribe to my YouTube channel for comprehensive content: https://lnkd.in/deiCTySg


Reference Link: https://platformwale.blog/2023/08/02/iam-roles-for-service-accounts-irsa-in-aws-eks-within-and-cross-aws-accounts/

Bonus Video for AWS/DevOps my AMA session : https://www.youtube.com/watch?v=ijAgPQoHMrI&t=2388s


Remember, like, share, and comment to help spread valuable knowledge further. Let's keep learning and growing together. ???? hashtag#AWS hashtag#DevSecOps hashtag#AI hashtag#ML hashtag#Data

Pravin Karde

Systems Architect at EPAM

4 个月

Nice content, concisely explained.

Soumyadip Chatterjee

?? Multi-Cloud & DevOps Strategist | OCI DevOps Engineer | GenAI Enthusiast | 2x OCI | 2x AWS | 1x GCP | 1x Azure| Kubernetes ?? | Terraform ??? | Helm ?? | Docker ?? | Prisma Cloud ?? | DevSecOps ? | Ex-TCS

4 个月

Insightful!

Prasad G

DevOps Engineer | ?? AWS Cloud | ?? Git | ?? Jenkins CI/CD | ?? Kubernetes | ?? Docker | ?? Ansible | ??? Terraform (Certified) | ?? Linux | ?? Grafana | ?? Python | ?? Jira | Banking ?? | Payments ?? | Healthcare ??

4 个月

Very informative,and useful tips.

要查看或添加评论,请登录

Ramandeep Chandna的更多文章

社区洞察

其他会员也浏览了