A simple, complete example of using AWS IAM authentication with Confluent Cloud from Amazon EKS. This is example code for educational purposes.
- Python Kafka producer running on Amazon EKS
- EKS Pod Identity for automatic credential management with AWS IAM
- OAuth token generation using AWS STS
- Complete setup automation with shell scripts
producer.py- Python Kafka producer application with AWS IAM OAuthrequirements.txt- Python dependenciesDockerfile- Container image definitionsetup-aws.sh- Automated AWS infrastructure setup scriptbuild-and-push.sh- Script to build and push Docker image to ECRdeploy.sh- Script to deploy application to EKSkubernetes/- Kubernetes manifestsnamespace.yaml- Kubernetes namespaceserviceaccount.yaml- ServiceAccount for Pod Identityconfigmap.yaml- Application configurationjob.yaml- One-time job deploymentdeployment.yaml- Continuous deployment
This is a demonstration producer designed to validate AWS IAM authentication to Confluent Cloud. Here's what it does:
- Produces a fixed number of messages (default: 100, configurable via
MESSAGE_COUNTenv var) - Then exits - this is a one-shot demo, not a continuous streaming application
- Rate-limited to ~10 messages/second (0.1s delay between messages)
- Execution time: ~10 seconds for 100 messages
Each message is a JSON payload with the following structure:
{
"timestamp": "2024-03-15T10:30:45.123456+00:00",
"message_number": 42,
"value": 73,
"source": "aws-iam-producer"
}Fields:
timestamp: UTC timestamp when the message was created (ISO 8601 format)message_number: Sequence number (1 to MESSAGE_COUNT)value: Random integer between 1 and 100source: Always"aws-iam-producer"to identify the producer
Message Key: Each message has a unique key in the format key-{N} where N is the message number. Since keys are unique, messages will be distributed across topic partitions based on key hash.
- Job (recommended for testing): Runs once, produces messages, and exits. Pod status will show "Completed".
- Deployment: Runs continuously, but since the producer exits after sending messages, the pod will restart repeatedly. This mode is included for reference but not ideal for this specific demo code.
For a production streaming application, you'd modify producer.py to run in a continuous loop rather than exiting after N messages.
┌─────────────────────────────────────────────────────────┐
│ Amazon EKS Cluster │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ Pod: Confluent Producer │ │
│ │ │ │
│ │ 1. Get AWS IAM token from STS ────────┐ │ │
│ │ (via EKS Pod Identity) │ │ │
│ │ │ │ │
│ │ 2. Use token for OAuth with │ │ │
│ │ Confluent Cloud ────────────────┐ │ │ │
│ │ │ │ │ │
│ │ 3. Produce messages │ │ │ │
│ └────────────────────────────────────┼─┼──┘ │
│ │ │ │
└───────────────────────────────────────┼─┼──────────────┘
│ │
│ └──> AWS STS
│ (GetWebIdentityToken)
│
└────> Confluent Cloud
(Kafka Cluster)
┌────────────────────────────────────────────────────────────────────────────┐
│ STEP 1: Pod Initialization │
│ ─────────────────────────────────────────────────────────────────────── │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ EKS Pod (Confluent Producer) │ │
│ │ • Namespace: confluent-producer │ │
│ │ • ServiceAccount: confluent-producer-sa │ │
│ │ • producer.py running │ │
│ └──────────────────┬──────────────────────┘ │
│ │ │
│ │ EKS Pod Identity automatically │
│ │ injects AWS credentials │
│ ↓ │
│ ┌─────────────────────────────────────────┐ │
│ │ AWS Credentials Available in Pod │ │
│ │ • AWS_REGION │ │
│ │ • AWS_ROLE_ARN │ │
│ │ • AWS_WEB_IDENTITY_TOKEN_FILE │ │
│ └─────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐
│ STEP 2: Request AWS IAM Token │
│ ─────────────────────────────────────────────────────────────────────── │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ producer.py │ │
│ │ │ │
│ │ boto3.client('sts') │ │
│ │ .get_web_identity_token( │ │
│ │ Audience=[AWS_ACCOUNT_ID], │ │
│ │ SigningAlgorithm='ES384', │ │
│ │ DurationSeconds=3600 │ │
│ │ ) │ │
│ └──────────────────┬──────────────────────┘ │
│ │ │
│ │ HTTPS Request │
│ ↓ │
│ ┌─────────────────────────────────────────┐ │
│ │ AWS STS (Security Token Service) │ │
│ │ • Validates pod identity │ │
│ │ • Validates IAM role permissions │ │
│ │ • Signs JWT token with AWS private key │ │
│ └──────────────────┬──────────────────────┘ │
│ │ │
│ │ Returns signed JWT │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ JWT Token (Simplified Example) │ │
│ │ ──────────────────────────────────────────────────────────────── │ │
│ │ Header: │ │
│ │ { │ │
│ │ "alg": "ES384", │ │
│ │ "kid": "abcd1234...", │ │
│ │ "typ": "JWT" │ │
│ │ } │ │
│ │ │ │
│ │ Payload: │ │
│ │ { │ │
│ │ "iss": "https://UUID.tokens.sts.global.api.aws", │ │
│ │ "sub": "123456789012", ← Your AWS Account ID │ │
│ │ "aud": ["123456789012"], │ │
│ │ "exp": 1234567890, │ │
│ │ "iat": 1234564290 │ │
│ │ } │ │
│ │ │ │
│ │ Signature: [signed by AWS private key] │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐
│ STEP 3: Connect to Confluent Cloud with OAuth │
│ ─────────────────────────────────────────────────────────────────────── │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ Kafka Producer (confluent-kafka) │ │
│ │ │ │
│ │ Producer.connect() with: │ │
│ │ • security.protocol: SASL_SSL │ │
│ │ • sasl.mechanisms: OAUTHBEARER │ │
│ │ • oauth_cb: returns AWS IAM token │ │
│ │ │ │
│ └──────────────────┬──────────────────────┘ │
│ │ │
│ │ TLS Connection with SASL OAUTHBEARER │
│ │ Bearer Token: <JWT from Step 2> │
│ │ Extensions: logicalCluster=lkc-xxxxx │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Confluent Cloud - Kafka Broker │ │
│ │ • Receives connection with OAuth token │ │
│ │ • Extracts JWT token │ │
│ │ • Reads "iss" (issuer) from token │ │
│ └──────────────────┬──────────────────────────────────────────────────┘ │
│ │ │
│ ↓ │
└────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐
│ STEP 4: Token Validation │
│ ─────────────────────────────────────────────────────────────────────── │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Confluent Cloud - Identity Provider Lookup │ │
│ │ │ │
│ │ 1. Extract issuer from JWT: │ │
│ │ iss = "https://UUID.tokens.sts.global.api.aws" │ │
│ │ │ │
│ │ 2. Find matching Identity Provider: │ │
│ │ → Lookup provider with matching issuer URL │ │
│ │ → Found: "AWS IAM" provider │ │
│ │ │ │
│ │ 3. Get JWKS (public keys) from provider: │ │
│ │ → Fetch: https://UUID.tokens.sts.global.api.aws/ │ │
│ │ .well-known/jwks.json │ │
│ │ → Cache public keys │ │
│ └──────────────────┬──────────────────────────────────────────────────┘ │
│ │ │
│ │ HTTPS GET │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ AWS OIDC Endpoint (Managed by AWS) │ │
│ │ https://UUID.tokens.sts.global.api.aws/.well-known/jwks.json │ │
│ │ │ │
│ │ Returns: │ │
│ │ { │ │
│ │ "keys": [ │ │
│ │ { │ │
│ │ "kid": "abcd1234...", │ │
│ │ "kty": "EC", │ │
│ │ "use": "sig", │ │
│ │ "crv": "P-384", │ │
│ │ "x": "...", │ │
│ │ "y": "..." ← AWS public key │ │
│ │ } │ │
│ │ ] │ │
│ │ } │ │
│ └──────────────────┬──────────────────────────────────────────────────┘ │
│ │ │
│ │ Public key returned │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Confluent Cloud - Verify JWT Signature │ │
│ │ │ │
│ │ ✓ Verify signature using AWS public key │ │
│ │ ✓ Verify token not expired (exp claim) │ │
│ │ ✓ Verify audience matches (aud claim) │ │
│ │ ✓ Extract subject: sub = "123456789012" │ │
│ │ └─ This is the AWS Account ID │ │
│ └──────────────────┬──────────────────────────────────────────────────┘ │
│ │ │
│ ↓ │
└────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐
│ STEP 5: Identity Pool Mapping │
│ ─────────────────────────────────────────────────────────────────────── │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Confluent Cloud - Find Identity Pool │ │
│ │ │ │
│ │ Token sub (subject) = "123456789012" │ │
│ │ │ │
│ │ Look for Identity Pool where: │ │
│ │ • Provider = "AWS IAM" (from issuer match) │ │
│ │ • Pool ID = "123456789012" (matches token subject) │ │
│ │ • Filter = <empty> (accepts all tokens from provider) │ │
│ │ │ │
│ │ ✓ Found matching pool! │ │
│ └──────────────────┬──────────────────────────────────────────────────┘ │
│ │ │
│ ↓ │
└────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐
│ STEP 6: Check Permissions (RBAC) │
│ ─────────────────────────────────────────────────────────────────────── │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Confluent Cloud - Role Binding Check │ │
│ │ │ │
│ │ Check role bindings for: │ │
│ │ • Principal: Identity Pool "123456789012" │ │
│ │ • Resource: Topic "test_topic" │ │
│ │ • Cluster: lkc-xxxxx │ │
│ │ • Operation: WRITE (produce messages) │ │
│ │ │ │
│ │ Role Binding Found: │ │
│ │ • Role: CloudClusterAdmin │ │
│ │ • Allows: All operations on all topics │ │
│ │ │ │
│ │ ✓ Authorization successful! │ │
│ └──────────────────┬──────────────────────────────────────────────────┘ │
│ │ │
│ ↓ │
└────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐
│ STEP 7: Produce Messages │
│ ─────────────────────────────────────────────────────────────────────── │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ Kafka Producer │ │
│ │ │ │
│ │ producer.produce( │ │
│ │ topic='test_topic', │ │
│ │ key='key-1', │ │
│ │ value='{"msg": "hello"}' │ │
│ │ ) │ │
│ └──────────────────┬──────────────────────┘ │
│ │ │
│ │ Kafka Protocol (over authenticated connection) │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Confluent Cloud - Kafka Broker │ │
│ │ │ │
│ │ • Receives message │ │
│ │ • Appends to topic partition │ │
│ │ • Returns acknowledgment │ │
│ │ │ │
│ │ ✓ Message stored at offset 42 │ │
│ └──────────────────┬──────────────────────────────────────────────────┘ │
│ │ │
│ │ Success response │
│ ↓ │
│ ┌─────────────────────────────────────────┐ │
│ │ Producer receives acknowledgment │ │
│ │ ✅ Message delivered to topic[0] @42 │ │
│ └─────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────────┘
Key Points:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• No API keys or secrets stored anywhere
• AWS credentials automatically managed by EKS Pod Identity
• JWT tokens are short-lived (15-60 minutes) and auto-refreshed
• Token validation happens via standard OIDC/OAuth flow
• Identity pools map AWS accounts to Kafka permissions
• All authentication handled transparently by the Kafka client
Before starting this example, ensure you have the following prerequisites in place.
- Python 3.8+ - Required for local development and testing
python3 --version # Should be 3.8 or higher - AWS CLI (v2+) - Install Guide
aws --version # Should be 2.x+ - kubectl - Install Guide
kubectl version --client
- eksctl - Install Guide
eksctl version
- Docker - Install Guide
docker --version
Your AWS account must have:
-
Administrative access or permissions to create:
- EKS clusters
- IAM roles and policies
- ECR repositories
- Pod Identity associations
-
AWS CLI configured with valid credentials:
aws configure # Or use AWS SSO: aws sso login # Verify access: aws sts get-caller-identity
-
Outbound Identity Federation enabled (see Step 1 below)
- This feature must be explicitly enabled in your AWS account
- Creates a unique OIDC issuer URL for your account
- Required permission:
iam:CreateOutboundIdentityFederation
You'll need:
- Active Confluent Cloud account - Sign up here
- Organization Admin access - Required to create OAuth identity providers
- A Kafka cluster - Can be in any cloud provider (AWS, Azure, GCP)
- Cluster information:
- Bootstrap server (e.g.,
pkc-xxxxx.us-west-2.aws.confluent.cloud:9092) - Logical cluster ID (starts with
lkc-, e.g.,lkc-abc123) - Kafka topic name
- Bootstrap server (e.g.,
The EKS cluster needs outbound internet access to communicate with:
-
Confluent Cloud Kafka brokers (port 9092)
- Example:
pkc-xxxxx.us-west-2.aws.confluent.cloud:9092
- Example:
-
AWS STS endpoints for token generation
- Example:
sts.us-west-2.amazonaws.com(HTTPS port 443)
- Example:
-
AWS Outbound Identity Federation JWKS endpoint
- Example:
https://{UUID}.tokens.sts.global.api.aws/.well-known/jwks.json
- Example:
Important: The setup-aws.sh script creates an EKS cluster with:
- 3 NAT Gateways (one per availability zone) - This is a paid AWS resource
- Public and private subnets
- Internet Gateway for outbound connectivity
This example requires:
confluent-kafka>=2.3.0- Kafka client library with SASL OAUTHBEARER supportboto3>=1.41.0- AWS SDK for Python
These are automatically installed in the Docker container via requirements.txt.
For local testing:
pip install -r requirements.txt- Open the AWS IAM Console
- Navigate to Access management → Account settings
- Find Outbound identity federation section
- Click Enable
- AWS generates a unique issuer URL for your account:
- Issuer:
https://{UUID}.tokens.sts.global.api.aws - JWKS URI:
https://{UUID}.tokens.sts.global.api.aws/.well-known/jwks.json
- Issuer:
- Save these URLs — you'll need them for Confluent Cloud setup
Note: The
{UUID}is a unique identifier generated by AWS for your account. It is not your AWS account ID.
Test that your OIDC endpoints are accessible:
# Replace {UUID} with your actual UUID from step 1.1
curl -s "https://{UUID}.tokens.sts.global.api.aws/.well-known/openid-configuration" | python3 -m json.toolYou should see a JSON response with issuer, jwks_uri, and token_endpoint fields.
Example response:
{
"issuer": "https://12345678-1234-1234-1234-123456789abc.tokens.sts.global.api.aws",
"jwks_uri": "https://12345678-1234-1234-1234-123456789abc.tokens.sts.global.api.aws/.well-known/jwks.json",
...
}Before setting up AWS resources, you need to configure Confluent Cloud to accept your AWS IAM tenant as an identity provider.
aws sts get-caller-identity --query Account --output textSave this value - you'll need it in the next steps.
-
Log in to Confluent Cloud
-
Go to Accounts & Access → Workload identities
-
Click Add provider
-
Select OAuth/OIDC
-
Configure the provider:
Basic Settings:
- Name:
AWS IAM(or any descriptive name) - Description:
AWS STS identity provider for EKS
Identity Provider Settings:
Use the issuer and JWKS URI from Step 1 (these contain a UUID, not your AWS account ID):
- Issuer:
https://{UUID}.tokens.sts.global.api.aws - JWKS URI:
https://{UUID}.tokens.sts.global.api.aws/.well-known/jwks.json
- Name:
-
Click Save
After creating the provider:
- Click on the provider you just created
- Go to Identity pools tab
- Click Add pool
- Configure the pool:
- Pool ID:
{YOUR_AWS_ACCOUNT_ID}(same as your AWS account ID) - Description:
AWS IAM credentials for EKS pods - Filter:
true(for development purposes; for production you would want to set filters such as{claims.sub == "abc"})
- Pool ID:
- Go to your Kafka cluster → Data access
- Click Add role binding
- Configure permissions:
- Role:
CloudClusterAdmin(or select a suitable topic-level role)
- Role:
- Click Save
You'll need these values for the next steps:
# From Cluster Settings → General
BOOTSTRAP_SERVERS="pkc-xxxxx.region.aws.confluent.cloud:9092"
# From Cluster Settings → General (look for "Cluster ID")
LOGICAL_CLUSTER="lkc-xxxxxx"Run the automated setup script:
# Make script executable
chmod +x setup-aws.sh
# Run setup (takes 15-20 minutes due to EKS cluster creation)
./setup-aws.shThis script creates:
- EKS cluster with Pod Identity addon
- ECR repository for Docker images
- IAM role with STS and ECR permissions
- Pod Identity association
- Kubernetes namespace and ServiceAccount
Output: Configuration is saved to .aws-config for use by other scripts.
Edit kubernetes/configmap.yaml and replace the placeholder values:
data:
# From Step 2.5 - your Confluent Cloud cluster
BOOTSTRAP_SERVERS: "pkc-xxxxx.us-west-2.aws.confluent.cloud:9092"
LOGICAL_CLUSTER: "lkc-xxxxxx"
KAFKA_TOPIC: "test_topic" # Or your preferred topic name
# From Step 2.1 - your AWS account ID
AWS_ACCOUNT_ID: "123456789012"
# AWS region (should match your cluster)
AWS_DEFAULT_REGION: "us-west-2"
# Optional: number of test messages to produce
MESSAGE_COUNT: "100"Build the Docker image and push to ECR:
# Make script executable
chmod +x build-and-push.sh
# Build and push image to ECR
./build-and-push.shThis script:
- Authenticates with Amazon ECR
- Builds the Docker image for AMD64 platform
- Tags and pushes to your ECR repository
First, apply your ConfigMap changes:
kubectl apply -f kubernetes/configmap.yamlThen deploy the producer:
# Make script executable
chmod +x deploy.sh
# Deploy as a one-time Job (recommended for testing)
./deploy.sh job
# OR deploy as a continuous Deployment
./deploy.sh deployment# View job status
kubectl get jobs -n confluent-producer
# View pod logs
kubectl logs -n confluent-producer -l app=confluent-producer -fYou should see logs like:
==========================================
Confluent Cloud Producer with AWS IAM Authentication
==========================================
[timestamp] Initializing producer...
Bootstrap: pkc-xxxxx.us-west-2.aws.confluent.cloud:9092
Cluster: lkc-xxxxxx
AWS Account: 123456789012
[timestamp] Requesting AWS IAM token...
[timestamp] ✅ Got token (expires in 3600s)
[timestamp] Starting to produce 100 messages to 'test_topic'
[timestamp] ✅ Message delivered to test_topic[0] @ offset 42
[timestamp] ✅ Message delivered to test_topic[1] @ offset 15
...
[timestamp] Flushing remaining messages...
==========================================
✅ SUCCESS! All messages produced using AWS IAM authentication
==========================================
- Go to your cluster in Confluent Cloud
- Navigate to Topics → Select your topic
- Click Messages tab
- You should see the test messages produced by the application
IMPORTANT: There are TWO different values to keep track of:
-
UUID (from Step 1) - Used for:
- Issuer URL in Confluent Cloud:
https://{UUID}.tokens.sts.global.api.aws - JWKS URI in Confluent Cloud:
https://{UUID}.tokens.sts.global.api.aws/.well-known/jwks.json - Format:
12345678-1234-1234-1234-123456789abc(hyphenated)
- Issuer URL in Confluent Cloud:
-
AWS Account ID (from Step 2.1) - Used for:
- Identity Pool ID in Confluent Cloud (must match exactly)
- ConfigMap
AWS_ACCOUNT_IDsetting - Format:
123456789012(12 digits, no hyphens)
Do NOT mix these up! The issuer URL uses the UUID, not the AWS account ID.
Error: Authentication failed
Check:
- ConfigMap has correct AWS_ACCOUNT_ID:
kubectl get configmap confluent-producer-config -n confluent-producer -o yaml
Error: Identity pool not found
- Ensure you created the identity pool in Step 2.3
- Ensure that the claims from the AWS token matches at least one identity pool based on the configured filter
Error: JWT_HEADER_KID_LOOKUP_FAILED
This means Confluent Cloud cannot verify the JWT signature. Check:
-
JWKS endpoint is reachable:
curl -s "https://{UUID}.tokens.sts.global.api.aws/.well-known/jwks.json" -
Wait a few minutes after creating a new Identity Provider — JWKS key caching may take time
-
Verify outbound identity federation is enabled:
- AWS IAM Console → Account settings → Outbound identity federation should show "Enabled"
Error: Unable to locate credentials
Check Pod Identity association:
source .aws-config
aws eks list-pod-identity-associations \
--cluster-name "$CLUSTER_NAME" \
--region "$AWS_REGION"Verify the association exists for:
- Namespace:
confluent-producer - ServiceAccount:
confluent-producer-sa
Error: AccessDenied for GetWebIdentityToken
Check IAM role permissions:
source .aws-config
aws iam get-role-policy \
--role-name "$ROLE_NAME" \
--policy-name STSAccessShould include: sts:GetWebIdentityToken
Error: Failed to connect to broker
-
Check bootstrap servers:
kubectl get configmap confluent-producer-config -n confluent-producer -o yaml | grep BOOTSTRAP -
Verify from pod:
kubectl run -it --rm debug --image=alpine --restart=Never -n confluent-producer -- sh # apk add curl # curl -v telnet://pkc-xxxxx.us-west-2.aws.confluent.cloud:9092
-
Check Confluent Cloud cluster status in the web console
Error: Not authorized to access topics
- Go to Confluent Cloud → Your Cluster → Data access
- Verify role binding exists for your identity pool
- Check the role has produce permissions for your topic
Error: unauthorized: authentication required
Re-authenticate with ECR:
source .aws-config
aws ecr get-login-password --region "$AWS_REGION" | \
docker login --username AWS --password-stdin \
"$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com"Error: repository does not exist
Create the ECR repository:
source .aws-config
aws ecr create-repository \
--repository-name "$ECR_REPO" \
--region "$AWS_REGION"Get detailed logs:
# Job logs
kubectl logs -n confluent-producer -l app=confluent-producer -f
# Describe pod for events
kubectl describe pod -n confluent-producer -l app=confluent-producer
# Check pod environment variables
kubectl exec -n confluent-producer -l app=confluent-producer -- env | grep -E 'BOOTSTRAP|CLUSTER|AWS'You can also create the identity provider and pool using the Confluent CLI instead of the web UI:
# Create identity provider (replace {UUID} with your value from Step 1)
confluent iam provider create "AWS-IAM" \
--description "AWS IAM outbound identity federation for EKS" \
--issuer-uri "https://{UUID}.tokens.sts.global.api.aws" \
--jwks-uri "https://{UUID}.tokens.sts.global.api.aws/.well-known/jwks.json" \
--identity-claim "claims.sub"
# Note the provider ID (e.g., op-xxxxx) from the output
# Create identity pool (replace {YOUR_AWS_ACCOUNT_ID} with your AWS account ID)
confluent iam pool create "AWS-Pool" \
--provider <PROVIDER_ID> \
--description "Identity pool for AWS IAM principals from EKS" \
--identity-claim "claims.sub" \
--filter "true"
# Note the pool ID (e.g., pool-xxxxx) from the output
# Grant access to your cluster
confluent iam rbac role-binding create \
--principal "User:<POOL_ID>" \
--role CloudClusterAdmin \
--environment <ENV_ID> \
--cloud-cluster <CLUSTER_ID>Delete all AWS resources:
source .aws-config
# Delete Kubernetes resources
kubectl delete namespace confluent-producer
# Delete Pod Identity association
aws eks delete-pod-identity-association \
--cluster-name "$CLUSTER_NAME" \
--association-id "$ASSOCIATION_ID" \
--region "$AWS_REGION"
# Delete EKS cluster (takes 10-15 minutes)
eksctl delete cluster --name "$CLUSTER_NAME" --region "$AWS_REGION"
# Delete IAM role and policies
aws iam delete-role-policy --role-name "$ROLE_NAME" --policy-name STSAccess
aws iam delete-role-policy --role-name "$ROLE_NAME" --policy-name ECRAccess
aws iam delete-role --role-name "$ROLE_NAME"
# Delete ECR repository
aws ecr delete-repository \
--repository-name "$ECR_REPO" \
--region "$AWS_REGION" \
--force
# Remove local config
rm -f .aws-config
**In Confluent Cloud:**
1. Go to **Accounts & Access** → **Workload identities**
2. Delete the AWS IAM provider identity pools, then the provider itself