0-Home
Github
TraceMyPodsOfficial
TMP-docs
EKS-Deploy-README
Irsa S3

πŸ” Secure S3 Access from EKS Pod using IRSA (IAM Roles for Service Accounts)

Deliver Api needs s3 access to upload the customer invoices

To securely give your microservice in Amazon EKS access to S3 without using access keys or secret keys, use IAM Roles for Service Accounts (IRSA). This method enables your pod to assume an IAM role with defined permissions via a Kubernetes service account, eliminating the need to hardcode credentials.


βœ… Step-by-Step Guide to Configure IRSA for S3 Access

πŸ“Œ 1. Enable OIDC Provider for Your EKS Cluster

First, associate your EKS cluster with an IAM OIDC provider:

eksctl utils associate-iam-oidc-provider \
  --region ap-south-1 \
  --cluster <your-cluster-name> \
  --approve

πŸ“Œ 2. Create an IAM Policy for S3 Access

Define a policy that grants access to the required S3 bucket:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:*"],
      "Resource": [
        "arn:aws:s3:::tracemypods",
        "arn:aws:s3:::tracemypods/*"
      ]
    }
  ]
}

Save this to a file (e.g., s3-access-policy.json) and create the policy via AWS CLI:

aws iam create-policy \
  --policy-name tracemypods-invoices3-policy \
  --policy-document file://tracemypods-invoices3-policy.json

πŸ“Œ 3. Create IAM Role & Kubernetes Service Account with Policy

Create the Kubernetes service account and attach the IAM policy:

eksctl create iamserviceaccount \
  --name tracemypods-invoices3-sa \
  --namespace ai-assistant \
  --cluster <your-cluster-name> \
  --attach-policy-arn arn:aws:iam::<account-id>:policy/tracemypods-invoices3-policy \
  --approve \
  --override-existing-serviceaccounts

This command creates:

  • A Kubernetes service account (tracemypods-invoices3-sa)
  • An IAM role linked to it
  • An OIDC trust relationship for secure role assumption

πŸ“Œ 4. Annotate the Kubernetes Deployment

Update your deployment YAML to use the new service account:

Filename: deliverapi.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tracemypods-depliverapi   # only this api need s3 bucket access to upload the invoices
spec:
  replicas: 1
  template:
    spec:
      serviceAccountName: tracemypods-invoices3-sa
      containers:
        - name: your-container
          image: your-image

[x] Terraform for IRSA

Filename: s3-sa.tf

 
# --------------------------------------------------------
# Terraform to setup IRSA for Deliver API in EKS
# --------------------------------------------------------
 
provider "aws" {
  region = "ap-south-1"
}
 
# ------------------------------------------
# 1. Fetch OIDC provider from EKS Cluster
# ------------------------------------------
data "aws_eks_cluster" "cluster" {
  name = var.cluster_name
}
 
data "aws_eks_cluster_auth" "cluster" {
  name = var.cluster_name
}
 
resource "aws_iam_openid_connect_provider" "oidc" {
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = [data.aws_eks_cluster.cluster.certificate_authority[0].data]
  url             = data.aws_eks_cluster.cluster.identity[0].oidc[0].issuer
}
 
# ------------------------------------------
# 2. Create IAM Policy for S3 Access
# ------------------------------------------
resource "aws_iam_policy" "s3_access_policy" {
  name        = "tracemypods-invoices3-policy"
  description = "Policy to allow Deliver API access to S3 bucket tracemypods"
 
  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect   = "Allow",
        Action   = ["s3:*"]
        Resource = [
          "arn:aws:s3:::tracemypods",
          "arn:aws:s3:::tracemypods/*"
        ]
      }
    ]
  })
}
 
# ------------------------------------------
# 3. Create IAM Role for Service Account
# ------------------------------------------
resource "aws_iam_role" "irsa_role" {
  name = "tracemypods-invoices3-role"
 
  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect = "Allow",
        Principal = {
          Federated = aws_iam_openid_connect_provider.oidc.arn
        },
        Action = "sts:AssumeRoleWithWebIdentity",
        Condition = {
          StringEquals = {
            "${replace(data.aws_eks_cluster.cluster.identity[0].oidc[0].issuer, "https://", "")}:sub" = "system:serviceaccount:ai-assistant:tracemypods-invoices3-sa"
          }
        }
      }
    ]
  })
}
 
resource "aws_iam_role_policy_attachment" "attach_s3_policy" {
  role       = aws_iam_role.irsa_role.name
  policy_arn = aws_iam_policy.s3_access_policy.arn
}
 
# ------------------------------------------
# 4. Create Kubernetes Service Account
# ------------------------------------------
resource "kubernetes_service_account" "irsa_sa" {
  metadata {
    name      = "tracemypods-invoices3-sa"
    namespace = "ai-assistant"
    annotations = {
      "eks.amazonaws.com/role-arn" = aws_iam_role.irsa_role.arn
    }
  }
}
 
# ------------------------------------------------------
# Variables
# ------------------------------------------------------
variable "cluster_name" {
  description = "EKS cluster name"
  type        = string
}
 
# ------------------------------------------------------
# Output
# ------------------------------------------------------
output "irsa_role_arn" {
  value = aws_iam_role.irsa_role.arn
}

πŸ’¬ Need a Quick Summary?

Hey! Don't have time to read everything? I get it. 😊
Click below and I'll give you the main points and what matters most on this page.
Takes about 5 seconds β€’ Uses Perplexity AI