@aws-cdk/aws-bedrock-agentcore-alpha: Runtime tracingEnabled creates per-stack AWS::XRay::ResourcePolicy, exhausts regional quota in multi-stack deployments
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the feature
`agentcore-alpha.Runtime`, when constructed with `tracingEnabled: true`, auto-creates an `AWS::XRay::ResourcePolicy` via `configureTracingDelivery` ([`lib/runtime/observability.ts`](https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/aws-bedrock-agentcore-alpha/lib/runtime/observability.ts)). The construct uses a per-stack singleton (`stack.node.tryFindChild('CdkXRayLogsDeliveryPolicy')`), so multiple Runtimes in one stack share a policy — but every stack gets its own.
The AWS `AWS::XRay::ResourcePolicy` quota is **10/account/region** (not exposed in Service Quotas — only raisable via Support). For workloads that deploy AgentCore Runtimes across many CFN stacks (per-PR feature stacks, multi-tenant deploys, etc.), this exhausts the regional quota with `ServiceLimitExceeded` and blocks all further deploys.
Request: a way to opt out of the per-stack policy creation so users can provide a single shared policy that satisfies all Runtimes in the account.
### Use Case
We deploy a CDK-managed AI assistant on Bedrock AgentCore with ~6–10 PR feature-branch stacks open at any time, plus main + preview + a separate conversation-analysis app. Each stack with `tracingEnabled: true` creates its own `AWS::XRay::ResourcePolicy`, even though one wildcard-scoped policy covering all AgentCore Runtimes in the account would suffice — that's actually the pattern AWS's own docs recommend ("[one wildcard policy per resource type, account-wide](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AWS-logs-infrastructure-V2-XRayTraces.html)").
Concrete failure mode:
```
HandlerErrorCode: ServiceLimitExceeded
"Limit exceeded for resource of type 'AWS::XRay::ResourcePolicy'.
The account 021459051137 has reached the maximum number of resource policies."
```
The L2's per-stack scoping means once we exceed 10 stacks with AgentCore Runtimes in a region, every new deploy fails — regardless of how many Runtimes each stack actually has.
### Proposed Solution
Add a `tracingResourcePolicy` prop on `RuntimeProps` matching existing L2 enum-mode patterns:
```ts
new Runtime(this, 'X', {
tracingEnabled: true,
tracingResourcePolicy: { mode: 'NONE' }, // do not create a policy; caller manages it elsewhere
// ...
});
```
Modes:
- `'AUTO'` (default, current behavior): per-stack singleton, as today.
- `'NONE'`: skip policy creation entirely. Caller is responsible for ensuring an X-Ray ResourcePolicy exists in the account/region that authorizes `delivery.logs.amazonaws.com` to write traces from the relevant runtime ARNs.
- `'SHARED'` (optional, nice-to-have): accept an `IResourcePolicy` or import token and reference it instead of creating one.
The minimal viable change is just `'AUTO' | 'NONE'` — the `'SHARED'` form is a refinement.
### Other Information
**Current workaround we're implementing:** a CDK `IAspect` that strips the `AWS::XRay::ResourcePolicy` resource from each feature stack's synthesized template at construct time, paired with one shared `xray.CfnResourcePolicy` in a dedicated infrastructure stack that has a broad-wildcard `LogGeneratingResourceArns` (`arn:aws:bedrock-agentcore:*::runtime/*`). This works but relies on the Aspect mechanism rather than a public opt-out API. We'd happily delete the Aspect once a real prop ships.
Filter key for the Aspect (which is what we'd love to replace with a prop):
```ts
if (node instanceof xray.CfnResourcePolicy && node.node.path.includes('CdkXRayLogsDeliveryPolicy')) {
node.node.scope?.node.tryRemoveChild(node.node.id);
}
```
**Verified against the L2 source:**
- Gating in [`runtime.ts:394`](https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/aws-bedrock-agentcore-alpha/lib/runtime/runtime.ts): `if (props.tracingEnabled) { configureTracingDelivery(this, this.agentRuntimeArn); }`
- Per-stack singleton in `observability.ts::configureTracingDelivery`: `stack.node.tryFindChild('CdkXRayLogsDeliveryPolicy')`
- Confirmed `tracingEnabled: false` cleanly skips all observability resources (`runtime.test.ts:3127`)
- The auto-policy schema (`runtime.test.ts:3111`) uses `delivery.logs.amazonaws.com` principal + `xray:PutTraceSegments` + `ForAllValues:ArnLike` on `logs:LogGeneratingResourceArns` — a single account-wide policy with a broad wildcard for that field would functionally subsume per-stack policies.
**Related:** #36596 — the original feature request that added `tracingEnabled` to the L2. Not a duplicate; this is the next-step refinement of that feature for multi-stack deployments.
### 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)
aws-cdk-lib@2.251.0, @aws-cdk/aws-bedrock-agentcore-alpha@2.251.0-alpha.0
### AWS CDK CLI version
2.1124.1
### Environment details (OS name and version, etc.)
macOS 15.x; CDK app deployed via GitHub Actions on Ubuntu runners against us-east-1.
Contributor guide
Research direction
Start with the tracing hook in packages/@aws-cdk/aws-bedrock-agentcore-alpha/lib/runtime/runtime.ts and read configureTracingDelivery in lib/runtime/observability.ts. Use the existing cases in lib/runtime/runtime.test.ts, including the tracingEnabled tests, to verify the default behavior and the opt-out behavior for synthesized X-Ray policies.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud, infrastructure
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100