Skip to content

bedrock-agentcore: addToRolePolicy for runtime with imported role destroys and recreates policies on every deployment #35844

@go-to-k

Description

@go-to-k

Describe the bug

The current addToRolePolicy for Runtime with imported role destroys and recreates policies on every deployment.

The reason is that Date.now() is used for a construct ID of a new Policy in the situation:

https://github.com/aws/aws-cdk/blob/v2.221.0/packages/%40aws-cdk/aws-bedrock-agentcore-alpha/agentcore/runtime/runtime-base.ts#L253

  public addToRolePolicy(statement: iam.PolicyStatement): IBedrockAgentRuntime {
    // Check if role is a concrete Role instance
    if (this.role instanceof iam.Role) {
      this.role.addToPolicy(statement);
    } else {
      // For imported roles (IRole), we need to attach via a new policy
      const policy = new iam.Policy(this, `CustomPolicy${Date.now()}`, {
        statements: [statement],
      });

Regression Issue

  • Select this option if this issue appears to be a regression.

Last Known Working CDK Library Version

No response

Expected Behavior

The diff will not occur.

Current Behavior

The diff will occur and destroy / recreate the policies.

Reproduction Steps

  1. Deploy your stack with the following CDK code:
const app = new cdk.App();
const stack = new cdk.Stack(app, 'aws-cdk-bedrock-agentcore-runtime-with-imported-role');

const runtimeArtifact = agentcore.AgentRuntimeArtifact.fromAsset(
  path.join(__dirname, 'testArtifact'),
);

const role = new iam.Role(stack, 'ExecutionRole', {
  assumedBy: new iam.ServicePrincipal('bedrock-agentcore.amazonaws.com'),
});
const imported = iam.Role.fromRoleArn(stack, 'ImportedRole', role.roleArn);

const runtime = new agentcore.Runtime(stack, 'TestRuntime', {
  runtimeName: 'integ_test_runtime',
  agentRuntimeArtifact: runtimeArtifact,
  executionRole: imported,
});

runtime.addToRolePolicy(new iam.PolicyStatement({
  actions: ['dynamodb:Query'],
  resources: ['arn:aws:dynamodb:us-east-1:123456789012:table/my-table'],
}));
  1. Deploy or diff the stack with the same CDK code again.

  2. The change will occur:

      [-] AWS::IAM::Policy TestRuntimeCustomPolicy1761380931769044921D2 destroy
      [+] AWS::IAM::Policy TestRuntimeCustomPolicy1761381522330E0DC0D40

Possible Solution

Add a policy counter and change the construct ID with the counter:

  /**
   * Counter for policies attached to imported roles
   * @internal
   */
  private _policyCounter: number = 0;
    } else {
      // For imported roles (IRole), we need to attach via a new policy
-      const policy = new iam.Policy(this, `CustomPolicy${Date.now()}`, {
+      const policy = new iam.Policy(this, `CustomPolicy${this._policyCounter++}`, {
        statements: [statement],
      });

The approach has already been used in lambda:

Additional Information/Context

No response

AWS CDK Library version (aws-cdk-lib)

v2.221.0

AWS CDK CLI version

2.1030.0

Node.js Version

v22.14.0

OS

Mac

Language

TypeScript

Language Version

No response

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    @aws-cdk/aws-iamRelated to AWS Identity and Access ManagementbugThis issue is a bug.effort/mediumMedium work item – several days of effortp2

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions