aws-samples / aws-samples/sample-agent-assisted-sdlc

feat: add observability (APPLICATION_LOGS + X-Ray + Identity) to AgentCore Gateway

Open
#88 6 comments 0 reactions 1 assignee Claimed by @EashanKaushik View on GitHub
agent:pr-completed
Dominant language
Python
Stars
42
Forks
9
PR merge metrics
No merged PRs in 30d

Description

## Description

Add observability delivery to the AgentCore Gateway using the existing `RuntimeObservability` construct. The gateway has a different log group pattern than runtimes and does NOT have USAGE_LOGS.

## Context

PRs #80 and #86 deployed observability for the coding assistant and MCP server runtimes respectively. The gateway is the last resource without observability configured.

**Key difference from runtimes:**
- Gateway log group: `/aws/vendedlogs/bedrock-agentcore/gateway/APPLICATION_LOGS/{GatewayID}`
- Runtime log group: `/aws/vendedlogs/bedrock-agentcore/runtime/APPLICATION_LOGS/{runtimeId}`
- Gateway does **NOT** have `USAGE_LOGS` (only runtimes do)

## What to do

### 1. Generalize `RuntimeObservability` construct

Add a `resourceType` prop to `lib/constructs/observability/runtime-observability.ts`:

```typescript
interface RuntimeObservabilityProps {
runtimeArn: string;
runtimeId: string;
resourceType?: "runtime" | "gateway"; // default: "runtime"
logRetentionDays?: number;
enableIdentityLogs?: boolean;
}
```

When `resourceType = "gateway"`:
- APPLICATION_LOGS log group: `/aws/vendedlogs/bedrock-agentcore/gateway/APPLICATION_LOGS/{runtimeId}` (use `gateway` instead of `runtime`)
- Skip USAGE_LOGS entirely (don't create LogGroup, DeliverySource, DeliveryDestination, Delivery for usage)
- X-Ray TRACES: same pattern as runtime (custom resource Lambda)
- Identity: same pattern (shared `/aws/vendedlogs/bedrock-agentcore/workload-identity-directory/APPLICATION_LOGS/default`)

### 2. Add IAM to gateway role

In `lib/constructs/gateway/mcp-gateway.ts`, add to the gateway role:
```typescript
gatewayRole.addToPolicy(new iam.PolicyStatement({
actions: ["bedrock-agentcore:AllowVendedLogDeliveryForResource"],
resources: ["*"],
}));
gatewayRole.addToPolicy(new iam.PolicyStatement({
actions: ["cloudwatch:PutMetricData"],
resources: ["*"],
conditions: { StringEquals: { "cloudwatch:namespace": "bedrock-agentcore" } },
}));
```

### 3. Instantiate in gateway stack

In `lib/nested/gateway-stack.ts`:
```typescript
import { RuntimeObservability } from "../constructs/observability/runtime-observability";

new RuntimeObservability(this, "Observability", {
runtimeArn: this.gateway.gatewayArn,
runtimeId: this.gateway.gatewayId,
resourceType: "gateway",
logRetentionDays: 30,
});
```

## Gateway deliveries (3 total)

| Tab | Log Type | Destination | Log Group |
|-----|----------|-------------|-----------|
| Gateway | `APPLICATION_LOGS` | CWL | `/aws/vendedlogs/bedrock-agentcore/gateway/APPLICATION_LOGS/{gatewayId}` |
| Gateway | `TRACES` | X-Ray | (custom resource) |
| Identity | `APPLICATION_LOGS` | CWL | `/aws/vendedlogs/bedrock-agentcore/workload-identity-directory/APPLICATION_LOGS/default` (shared) |

## Acceptance Criteria

- [ ] `RuntimeObservability` accepts `resourceType?: "runtime" | "gateway"` prop (default: `"runtime"`)
- [ ] When `resourceType = "gateway"`: log group uses `/gateway/APPLICATION_LOGS/` prefix, no USAGE_LOGS created
- [ ] Gateway role has `AllowVendedLogDeliveryForResource` + `cloudwatch:PutMetricData`
- [ ] `RuntimeObservability` instantiated in gateway stack with `resourceType: "gateway"`
- [ ] Existing runtime observability (assistant + MCP servers) unchanged (default `resourceType: "runtime"`)
- [ ] `npx cdk synth --quiet` passes
- [ ] All delivery source/destination names ≤60 chars
- [ ] Post-deploy: Gateway shows APPLICATION_LOGS + TRACES in AgentCore console

## Files to modify

```
lib/constructs/observability/runtime-observability.ts MODIFY — add resourceType prop, conditional USAGE_LOGS
lib/constructs/gateway/mcp-gateway.ts MODIFY — add IAM for observability
lib/nested/gateway-stack.ts MODIFY — instantiate RuntimeObservability
```

## Constraints

- The `gatewayId` is already exposed by `McpGateway` construct (`this.gateway.gatewayId`)
- The `gatewayArn` is already exposed (`this.gateway.gatewayArn`)
- Shared Identity log group is idempotent (custom resource handles it)
- Do NOT break existing runtime/MCP server observability

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.