aws / aws/aws-cdk

eks: ServiceAccount (IdentityType.POD_IDENTITY) should accept an existing IAM role via optional `role` prop

Open
#37,299 1 comment 0 reactions 0 assignees View on GitHub
@aws-cdk/aws-iam effort/medium feature-request p2
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
2d 3h
Merged PRs (30d)
83

Description

### Describe the feature

When using `ServiceAccount` with `IdentityType.POD_IDENTITY`, the CDK automatically
creates an IAM role internally. There is currently no way to pass a pre-existing IAM
role (e.g., created via `iam.Role`, `iam.Role.fromRoleArn()`, or `iam.Role.fromLookup()`)
to be used in the underlying `PodIdentityAssociation`.

### Use Case

### 1. Centralized IAM role management

Projects that consolidate all IAM role definitions in a dedicated construct
(e.g., `IamConstruct`) cannot use `ServiceAccount` with `IdentityType.POD_IDENTITY`,
because the auto-generated role falls outside that construct's control.
This makes it impossible to call `grantRead()` or attach policies in one place.

### 2. Reusing an existing IAM role

When an IAM role already exists (imported via `Role.fromRoleArn()` or
`Role.fromLookup()`), there is no L2 way to associate it with a Pod Identity.
Developers are forced to fall back to the L1 construct `CfnPodIdentityAssociation`.

### Proposed Solution

Add an optional `role` property to `ServiceAccountOptions`:

```typescript
export interface ServiceAccountOptions {
// ... existing props ...

/**
* An existing IAM role to associate with this service account via Pod Identity.
* Only valid when `identityType` is `IdentityType.POD_IDENTITY`.
*
* When specified, the provided role is used instead of auto-generating one.
* When omitted, the current behavior (auto-generating an IAM role) is preserved.
*
* @default - a new IAM role is created automatically
*/
readonly role?: iam.IRole;
}

Example usage:

// IAM role defined and managed separately
const appRole = new iam.Role(this, 'AppRole', {
assumedBy: new iam.SessionTagsPrincipal(
new iam.ServicePrincipal('pods.eks.amazonaws.com'),
),
});
appRole.addManagedPolicy(...);

// Pass the existing role to ServiceAccount
new eks.ServiceAccount(this, 'AppSA', {
cluster: this.cluster,
name: 'app-sa',
namespace: 'production',
identityType: IdentityType.POD_IDENTITY,
role: appRole, // use pre-existing role instead of auto-generating
});

Backward Compatibility

This change is fully backward compatible:
- If role is not specified, behavior remains unchanged (IAM role is auto-generated).
- If role is specified, the provided role is used instead.
- A validation error should be thrown if role is specified when
identityType is not IdentityType.POD_IDENTITY.

Current Workaround

Using the L1 construct directly:

const pia = new CfnPodIdentityAssociation(this, 'AppPIA', {
clusterName: cluster.clusterName,
namespace: 'production',
serviceAccount: 'app-sa',
roleArn: appRole.roleArn,
});

This works but loses the ergonomics and CDK-level dependency management
that the L2 ServiceAccount construct provides.

### Other Information

Related

- #30519 — original Pod Identity L2 support issue (closed)

### Acknowledgements

- [x] I may be able to implement this feature request
- [ ] This feature might incur a breaking change

### AWS CDK Library version (aws-cdk-lib)

2.243.0

### AWS CDK CLI version

2.1111.0 (build 69089a7)

### Environment details (OS name and version, etc.)

Ubuntu 24.04

Contributor guide

Open the contributing guide

Research direction

Start at the ServiceAccount and ServiceAccountOptions entry points, then trace the existing IdentityType.POD_IDENTITY path and its PodIdentityAssociation setup. Done means an optional existing IAM role is accepted for POD_IDENTITY, omitted roles retain current behavior, and non-POD_IDENTITY usage is rejected; add or update focused tests for these cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, kubernetes, typescript
Domain
cloud, infrastructure
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.