DEV Community

Rajganesh Pandurangan
Rajganesh Pandurangan

Posted on

TEST

EKS End-to-End Scenario: Pod Identity with AWS Services

This scenario demonstrates deploying a web application on Amazon EKS that interacts with AWS S3 and DynamoDB using EKS Pod Identity for secure, fine-grained IAM access.

Use Case Overview

  • Deploy a Python Flask app in EKS.
  • App stores/retrieves files in S3 and reads/writes data in DynamoDB.
  • Access to AWS services is managed using EKS Pod Identity—no static AWS credentials in pods.

Step 1: Prerequisites

  • AWS CLI and kubectl installed and configured.
  • eksctl installed.
  • An AWS account with permissions to create EKS clusters, IAM roles, S3, and DynamoDB.

Step 2: Create the EKS Cluster

eksctl create cluster \
  --name eks-pod-identity-demo \
  --region us-west-2 \
  --nodes 2 \
  --node-type t3.medium
Enter fullscreen mode Exit fullscreen mode

Step 3: Enable EKS Pod Identity

  1. Associate Pod Identity with your cluster:
eksctl utils associate-iam-oidc-provider \
  --region us-west-2 \
  --cluster eks-pod-identity-demo \
  --approve
Enter fullscreen mode Exit fullscreen mode
  1. Install the EKS Pod Identity Agent:
kubectl apply -f https://github.com/aws/amazon-eks-pod-identity-webhook/releases/latest/download/deployment.yaml
Enter fullscreen mode Exit fullscreen mode

Step 4: Create AWS Resources

  • S3 Bucket:
    • Create a bucket (e.g., eks-pod-identity-demo-bucket).
  • DynamoDB Table:
    • Create a table (e.g., EKSAppTable) with a primary key (id).

Step 5: Create IAM Role for Service Account (IRSA)

  1. Create an IAM policy:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::eks-pod-identity-demo-bucket/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:PutItem",
        "dynamodb:GetItem"
      ],
      "Resource": "arn:aws:dynamodb:us-west-2:YOUR_ACCOUNT_ID:table/EKSAppTable"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode
  1. Create the IAM role and associate with Kubernetes service account:
eksctl create iamserviceaccount \
  --name eks-app-sa \
  --namespace default \
  --cluster eks-pod-identity-demo \
  --attach-policy-arn arn:aws:iam::YOUR_ACCOUNT_ID:policy/eks-app-policy \
  --approve
Enter fullscreen mode Exit fullscreen mode

Step 6: Deploy the Application

  1. Create a Kubernetes deployment using the service account:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: flask-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: flask-app
  template:
    metadata:
      labels:
        app: flask-app
    spec:
      serviceAccountName: eks-app-sa
      containers:
      - name: flask-app
        image: YOUR_ECR_REPO/flask-app:latest
        env:
        - name: S3_BUCKET
          value: eks-pod-identity-demo-bucket
        - name: DDB_TABLE
          value: EKSAppTable
        ports:
        - containerPort: 5000
Enter fullscreen mode Exit fullscreen mode
  1. Expose the app via a LoadBalancer:
apiVersion: v1
kind: Service
metadata:
  name: flask-app-service
spec:
  type: LoadBalancer
  selector:
    app: flask-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5000
Enter fullscreen mode Exit fullscreen mode

Step 7: Application Logic (Python Example)

import boto3
import os
from flask import Flask, request

app = Flask(__name__)
s3 = boto3.client('s3')
ddb = boto3.resource('dynamodb')
bucket = os.environ['S3_BUCKET']
table = ddb.Table(os.environ['DDB_TABLE'])

@app.route('/upload', methods=['POST'])
def upload():
    file = request.files['file']
    s3.upload_fileobj(file, bucket, file.filename)
    table.put_item(Item={'id': file.filename, 'status': 'uploaded'})
    return 'Uploaded', 200

@app.route('/download/<filename>', methods=['GET'])
def download(filename):
    s3.download_file(bucket, filename, f'/tmp/{filename}')
    return open(f'/tmp/{filename}', 'rb').read(), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0')
Enter fullscreen mode Exit fullscreen mode

Step 8: Test the Setup

  • Upload and download files via the app endpoint.
  • Check S3 and DynamoDB for data.
  • Confirm no AWS credentials are present in the pod—access is via Pod Identity.

Summary Table

Component AWS Service Purpose Access Managed By
EKS Cluster EKS Orchestrates containers eksctl
Storage S3 File storage Pod Identity (IRSA)
Database DynamoDB Key-value data store Pod Identity (IRSA)
App Deployment EKS Runs Flask app in pods K8s Service Account

This workflow demonstrates a secure, production-grade pattern for cloud-native applications on AWS using EKS, Pod Identity, and tightly scoped IAM permissions—no hardcoded credentials, all access is managed by Kubernetes-native identities.


can you use cdk to set uthi up

Yes, you can use AWS CDK (Cloud Development Kit) to set up the entire EKS scenario—including the cluster, Pod Identity, IAM roles, S3 bucket, DynamoDB table, and Kubernetes resources. CDK enables you to define your infrastructure as code in Python, TypeScript, or other supported languages.

Below is a high-level outline of how you would implement this scenario using CDK (Python example):

1. Initialize Your CDK Project

cdk init app --language python
pip install aws-cdk-lib constructs
Enter fullscreen mode Exit fullscreen mode

2. Define the Stack in CDK

a. Create the EKS Cluster

from aws_cdk import (
    Stack,
    aws_eks as eks,
    aws_iam as iam,
    aws_s3 as s3,
    aws_dynamodb as dynamodb,
)
from constructs import Construct

class EksPodIdentityStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs):
        super().__init__(scope, construct_id, **kwargs)

        # S3 bucket
        bucket = s3.Bucket(self, "EksAppBucket")

        # DynamoDB table
        table = dynamodb.Table(
            self, "EksAppTable",
            partition_key=dynamodb.Attribute(name="id", type=dynamodb.AttributeType.STRING)
        )

        # EKS cluster
        cluster = eks.Cluster(
            self, "EksCluster",
            version=eks.KubernetesVersion.V1_29,
            default_capacity=2,
        )

        # IAM policy for pod access
        policy = iam.PolicyStatement(
            actions=[
                "s3:GetObject", "s3:PutObject",
                "dynamodb:PutItem", "dynamodb:GetItem"
            ],
            resources=[
                bucket.bucket_arn + "/*",
                table.table_arn
            ]
        )

        # Service account with IAM role (Pod Identity)
        sa = cluster.add_service_account("EksAppServiceAccount")
        sa.add_to_principal_policy(policy)

        # Output values
        self.bucket = bucket
        self.table = table
        self.cluster = cluster
        self.sa = sa
Enter fullscreen mode Exit fullscreen mode

b. Deploy the Stack

cdk deploy
Enter fullscreen mode Exit fullscreen mode

3. Deploy Your Application to EKS

  • Build and push your Docker image to ECR.
  • Use CDK to apply a Kubernetes manifest (or use kubectl):
app_manifest = {
    "apiVersion": "apps/v1",
    "kind": "Deployment",
    "metadata": {"name": "flask-app"},
    "spec": {
        "replicas": 2,
        "selector": {"matchLabels": {"app": "flask-app"}},
        "template": {
            "metadata": {"labels": {"app": "flask-app"}},
            "spec": {
                "serviceAccountName": sa.service_account_name,
                "containers": [{
                    "name": "flask-app",
                    "image": "YOUR_ECR_REPO/flask-app:latest",
                    "env": [
                        {"name": "S3_BUCKET", "value": bucket.bucket_name},
                        {"name": "DDB_TABLE", "value": table.table_name}
                    ],
                    "ports": [{"containerPort": 5000}]
                }]
            }
        }
    }
}

cluster.add_manifest("FlaskAppDeployment", app_manifest)
Enter fullscreen mode Exit fullscreen mode
  • Similarly, add a manifest for the LoadBalancer service.

4. Summary

  • All AWS resources (EKS, S3, DynamoDB, IAM roles) are provisioned via CDK.
  • Pod Identity (IAM role for service account) is set up with least-privilege permissions.
  • Kubernetes manifests can be deployed via CDK or post-deployment with kubectl.

This approach gives you a fully automated, repeatable infrastructure deployment using modern infrastructure-as-code best practices.


can you use python

Yes, you can use Python with AWS CDK to set up your EKS cluster, configure Pod Identity, and provision all supporting AWS resources. The AWS CDK natively supports Python as one of its primary languages, allowing you to define and automate your infrastructure using Python code12345.

Key Points

  • AWS CDK supports Python: You can define EKS clusters, IAM roles, S3 buckets, DynamoDB tables, and Kubernetes manifests directly in Python code12345.
  • Full automation: Using Python with CDK, you can automate the entire lifecycle of your infrastructure, including cluster creation, IAM role association for Pod Identity, and application deployment1345.
  • Example Workflow:
    • Initialize your CDK project with cdk init app --language python45.
    • Use the aws_cdk.aws_eks module to define your EKS cluster and add Kubernetes resources35.
    • Define IAM roles and policies in Python and associate them with Kubernetes service accounts for Pod Identity.
    • Use CDK to deploy S3, DynamoDB, and other AWS resources as needed.
    • Deploy Kubernetes manifests (such as Deployments and Services) using cluster.add_manifest() in your Python CDK code35.

Example CDK Project Structure (Python)

mkdir eks
cd eks
mkdir cluster cdk8s
cd cluster
cdk init app --language=python
Enter fullscreen mode Exit fullscreen mode

This sets up your Python-based CDK project for EKS provisioning45.

Documentation and Guides

  • The AWS EKS Construct Library documentation provides Python examples for defining clusters and applying Kubernetes manifests3.
  • Tutorials and guides, such as those on AWS and developer blogs, demonstrate end-to-end EKS automation using Python and CDK, including integration with Helm and other tools45.

In summary: Python is a fully supported and commonly used language for AWS CDK, enabling you to automate EKS and related AWS resource setup, including Pod Identity, entirely in Python code12345.


where is the python code

Here is a concise Python AWS CDK example that provisions:

  • An EKS cluster
  • An S3 bucket
  • A DynamoDB table
  • An IAM role for Pod Identity (IRSA) and a Kubernetes service account
  • Deploys a simple app using that service account

This is a minimal, illustrative example. You can expand it for production use.

from aws_cdk import (
    core,
    aws_eks as eks,
    aws_iam as iam,
    aws_s3 as s3,
    aws_dynamodb as dynamodb,
)

class EksPodIdentityStack(core.Stack):
    def __init__(self, scope: core.Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)

        # S3 bucket
        bucket = s3.Bucket(self, "EksAppBucket")

        # DynamoDB table
        table = dynamodb.Table(
            self, "EksAppTable",
            partition_key=dynamodb.Attribute(name="id", type=dynamodb.AttributeType.STRING)
        )

        # EKS Cluster
        cluster = eks.Cluster(
            self, "EksCluster",
            version=eks.KubernetesVersion.V1_29,
            default_capacity=2,
        )

        # IAM policy for pod access
        policy = iam.PolicyStatement(
            actions=[
                "s3:GetObject", "s3:PutObject",
                "dynamodb:PutItem", "dynamodb:GetItem"
            ],
            resources=[
                bucket.bucket_arn + "/*",
                table.table_arn
            ]
        )

        # Service account with IAM role (Pod Identity)
        sa = cluster.add_service_account("EksAppServiceAccount")
        sa.add_to_principal_policy(policy)

        # Deploy your app (placeholder manifest)
        app_manifest = {
            "apiVersion": "apps/v1",
            "kind": "Deployment",
            "metadata": {"name": "flask-app"},
            "spec": {
                "replicas": 2,
                "selector": {"matchLabels": {"app": "flask-app"}},
                "template": {
                    "metadata": {"labels": {"app": "flask-app"}},
                    "spec": {
                        "serviceAccountName": sa.service_account_name,
                        "containers": [{
                            "name": "flask-app",
                            "image": "YOUR_ECR_REPO/flask-app:latest",
                            "env": [
                                {"name": "S3_BUCKET", "value": bucket.bucket_name},
                                {"name": "DDB_TABLE", "value": table.table_name}
                            ],
                            "ports": [{"containerPort": 5000}]
                        }]
                    }
                }
            }
        }
        cluster.add_manifest("FlaskAppDeployment", app_manifest)

        # Expose the app (placeholder manifest)
        service_manifest = {
            "apiVersion": "v1",
            "kind": "Service",
            "metadata": {"name": "flask-app-service"},
            "spec": {
                "type": "LoadBalancer",
                "selector": {"app": "flask-app"},
                "ports": [{"protocol": "TCP", "port": 80, "targetPort": 5000}]
            }
        }
        cluster.add_manifest("FlaskAppService", service_manifest)
Enter fullscreen mode Exit fullscreen mode

Usage:

  • Place this in your CDK app (e.g., app.py and eks_pod_identity_stack.py).
  • Replace "YOUR_ECR_REPO/flask-app:latest" with your actual container image.
  • Run cdk deploy.

References:

  • [CDK EKS Python documentation]6
  • [Example of IRSA with CDK and Python]7

67


  1. https://isjem.com/download/from-code-to-cloud-automating-continuous-deployment-with-aws-cloud-development-kit-cdk-and-infrastructure-as-code-iac/ 

  2. https://ieeexplore.ieee.org/document/10516612/ 

  3. https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_eks/README.html 

  4. https://aws.amazon.com/tutorials/deploy-webapp-eks/module-one/ 

  5. https://dev.to/marocz/automating-eks-deployment-and-nginx-setup-using-helm-with-aws-cdk-in-python-27mn 

  6. https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_eks/README.html 

  7. https://aws.plainenglish.io/deploying-an-eks-cluster-with-aws-cloud-development-kit-cdk-afdb96ce3a83 

Top comments (0)