Sitemap
AWS Tip

Best AWS, DevOps, Serverless, and more from top Medium writers .

Getting Started with Amazon CloudWatch for Bedrock AgentCore Observability

11 min readOct 26, 2026

--

Press enter or click to view image in full size

Introduction

This article is part of a series I am writing about different aspects of Amazon Bedrock AgentCore. In the previous articles, each component was introduced on its own and attached to the same used car dealership assistant. Here, we bring all of them together into a single agent and observe the complete system running end to end. For a broader understanding of AgentCore and its components, check out the other articles in this series:

This article is different from the previous ones. Every component has already been described in isolation, so here we do not configure any of them again by hand. Instead, we stand up a single agent that wires all of them together and watch the whole system run end to end. The focus is the consolidated view: one agent, all modules connected, observed from the outside.

Because each piece was covered separately before, this article assumes you already know how each one is configured. We will not repeat any console walkthrough. What was missing from the series is exactly this: seeing the orchestration of the complete agent and reading its behavior through observability.

To make the whole thing reproducible, the companion repository provisions everything with Terraform. A single terraform apply brings up the Runtime, the Gateway and its targets, the Code Interpreter, the Browser, the Memory, the Knowledge Base, the Cognito identity layer, the DynamoDB tables, and the IAM roles, all connected to each other. The same apply also builds and pushes the agent image, seeds the demo data, and writes the testbench configuration, so there is nothing to wire by hand.

What We Are Building

We reuse the used car dealership assistant from the series, now as one integrated deployment:

  • The agent is written with LangGraph instead of the Strands Agents SDK used elsewhere in the series. This is deliberate: AgentCore Runtime is framework agnostic, so a bring-your-own-container agent works the same way.
  • It is deployed on AgentCore Runtime as an ARM64 container in Amazon ECR, the same pattern as the first article.
  • It connects every element from the series: tools through Gateway (a Lambda inventory tool, a Knowledge Base connector, and Web Search), the Code Interpreter for calculations, the Browser, Memory for cross-session recall, and Identity for access control, all under AgentCore observability.
Press enter or click to view image in full size

How the Pieces Connect

The request flow ties the whole series together in one path:

  1. A user signs in to Amazon Cognito and receives an ID token carrying the cognito:groups claim (Identity).
  2. The testbench calls the Runtime endpoint with Authorization: Bearer <id-token>. The Runtime JWT authorizer validates the token at the edge and rejects anyone whose group is not customer or employee.
  3. Inside the container, the LangGraph agent reads the validated token, resolves the caller’s role, and registers tools accordingly (role-based access control).
  4. For inventory, knowledge, and web search, the agent connects to a single AgentCore Gateway over MCP using SigV4, and the Gateway routes each call to the right target.
  5. For exact math, the agent calls the Code Interpreter. For a specific URL, it calls the Browser.
  6. Before and after each turn, the agent recalls and writes durable facts to Memory.
  7. Every one of these calls is emitted to Amazon CloudWatch: service metrics and structured logs from the platform, plus OpenTelemetry traces and spans from the instrumented container, giving a single consolidated view of the run.

The Companion Repository

The full implementation is available on GitHub. The repository is organized as a fullstack Terraform project:

  • backend/infrastructure holds one Terraform file per AWS service (aws_cognito.tf, aws_dynamodb.tf, aws_agentcore_gateway.tf, aws_agentcore_runtime.tf, and so on).
  • agent/ holds the LangGraph container (agent.py, Dockerfile, requirements.txt).
  • testbench/ holds the ways to exercise the agent: a browser chat UI with a local proxy, and a traffic generator script.
  • seed/ holds the sample data and the Knowledge Base documents.

The agent orchestration logic lives in agent/agent.py. It reads the JWT, filters tools by role, loads the Gateway tools over MCP, and adds the Code Interpreter and Browser as local tools. The whole graph is a standard LangGraph create_react_agent, which shows how little glue code the platform requires.

One design choice worth calling out: the entire stack is provisioned as infrastructure as code, including the AgentCore resources themselves. The AWS Terraform provider now exposes native AgentCore resources (aws_bedrockagentcore_agent_runtime, aws_bedrockagentcore_gateway, aws_bedrockagentcore_gateway_target, aws_bedrockagentcore_memory, aws_bedrockagentcore_code_interpreter, and aws_bedrockagentcore_browser), so there is no console clicking to reproduce the environment. Terraform even builds and pushes the image and seeds the data during the apply, driven by a toggle described next.

Step 1: Provision Everything

Provision the full stack with Terraform. By default (auto_bootstrap = true) a single terraform apply does everything: it provisions the infrastructure, builds and pushes the agent image, seeds the demo data, and writes testbench/.env. Because it builds the image locally, you need Docker with buildx and the AWS CLI on the machine running Terraform.

git clone https://github.com/biagolini/TerraformAwsBedrockAgentCoreIntegratedAgent.git
cd TerraformAwsBedrockAgentCoreIntegratedAgent/backend/environments/dev
cp backend.hcl.example backend.hcl # your state bucket and profile
cp terraform.tfvars.example terraform.tfvars # your region and profile
export AWS_PROFILE=<your-profile>
terraform init -backend-config=backend.hcl
terraform apply

Knowledge Base ingestion runs asynchronously, so wait two to three minutes after the apply before asking knowledge-base questions. If you prefer to control the build and seeding yourself (for example in CI, or without Docker), set auto_bootstrap = false and run agent/build_and_push.sh and seed/seed.sh manually.

Step 2: Generate Traffic

Before the observability views have anything to show, the agent needs to be exercised. The repository includes a traffic generator for this:

cd testbench
python3 generate_traffic.py

It reads the generated .env and drives a steady stream of requests (2 to 5 per minute over 20 minutes by default), picking a user and a prompt at random. The user mix is weighted about 45/45/10 across employee, customer, and no-group, one session per user so Memory accumulates context, and the prompts cover every component: inventory (Gateway plus Lambda), financing math (Code Interpreter), knowledge base questions, web search, and the employee-only cost tool.

If you would rather send prompts by hand and read the answers, run python3 proxy.py instead and open the chat UI at http://localhost:8080. Signing in as jane (employee), john (customer), and alex (no group) and asking the same employee-only question, for example "What was the acquisition cost of the Ford Explorer?", is the quickest way to see the access control from the Identity article: jane gets the number, john is declined, and alex is rejected before the container even runs.

Step 3: Observe the Whole System in CloudWatch

This is where the integrated view pays off. Because the agent runs on AgentCore Runtime and the container is instrumented with the AWS Distro for OpenTelemetry, its metrics, logs, and traces all flow to Amazon CloudWatch generative AI observability. Every component reports under the same account, so you can read the entire orchestration from one place. For the underlying one-time setup (Transaction Search and per-resource log delivery) see the Observability article; this stack already enables all of it in Terraform.

Get Carlos Biagolini’s stories in your inbox

Join Medium for free to get updates from this writer.

Open the console at CloudWatch > GenAI Observability > Bedrock AgentCore. The landing page has four tabs that move from the aggregate to the individual event:

  • All capabilities groups the data by AgentCore capability, with a sub-tab for each: Agents, Built-in tools, Gateways, Harnesses, Identity, Memory, Payments, and Runtime.
  • All sessions lists conversations. A session is a complete user interaction, correlated by the session id.
  • All traces lists request-response cycles. Each trace is one invocation of the agent, from the incoming prompt to the final answer.
  • All spans lists the individual operations inside those traces: a reasoning step, a model call, a tool invocation, a memory lookup.

The sub-tabs under All capabilities are covered next, in console order. Not every capability is used by this project, but it is worth seeing what each dashboard looks like.

3.1 Agents

The agent scorecard, populated from the instrumented container’s spans: OTEL sessions, traces, tokens, cost, and error rate. This is the closest thing to a single summary of the agent’s behavior.

Press enter or click to view image in full size
Agents sub-tab showing OTEL sessions, traces, token usage, and error rate
Agents sub-tab showing OTEL sessions, traces, token usage, and error rate

3.2 Built-in tools

Usage of the Code Interpreter and Browser tools. The traffic generator sends financing questions that the agent runs through the Code Interpreter, so its sandbox executions show up here. One gotcha: per-resource delivery differs by tool. The Code Interpreter accepts logs and traces (both configured in Terraform); the Browser accepts traces only, so the stack sends its traces to X-Ray with no dedicated log stream

Press enter or click to view image in full size
Built-in tools sub-tab showing Code Interpreter activity
Built-in tools sub-tab showing Code Interpreter activity

3.3 Gateways

Every tool call routed through the AgentCore Gateway, with error and throttle rates. This single view covers all three targets: the Lambda inventory tool, the Knowledge Base connector, and Web Search. The Knowledge Base is reached through the Gateway, so its retrieval calls appear here. The stack also wires per-resource delivery for it in Terraform (logs to CloudWatch Logs, traces to X-Ray), so its retrieval spans also surface under AgentCore observability, alongside its own metrics in the Amazon Bedrock console.

Press enter or click to view image in full size
Gateways sub-tab showing invocations, error rate, and throttle rate

3.4 Harnesses

The AgentCore Harness is the managed agent loop, an alternative to bringing your own container on Runtime. This project uses Runtime, not a Harness, so the dashboard reads zero. It is shown here because the Harness is a common way to run agents and you will see this tab in the console.

Press enter or click to view image in full size
Harnesses sub-tab with no data
Harnesses sub-tab with no data

3.5 Identity

This view reports outbound AgentCore Identity (an agent authenticating to external services), which this project does not use, so it reads zero. The inbound authorization this agent does rely on (including the rejected no-group user) is enforced at the Runtime edge and surfaces as Runtime metrics instead.

Press enter or click to view image in full size
Identity sub-tab overview with no data
Identity sub-tab overview with no data

3.6 Memory

Retrieval and event operations against AgentCore Memory, with their latencies. This is where cross-session recall becomes visible as traffic.

Press enter or click to view image in full size
Memory sub-tab showing memory operations
Memory sub-tab showing memory operations

3.7 Payments

AgentCore Payments tracks agent transactions. This project does not transact, so the dashboard is an empty overview, shown for completeness.

Press enter or click to view image in full size
Payments sub-tab with no data
Payments sub-tab with no data

3.8 Runtime

The hosting environment for the agent: runtime sessions, invocations, errors, throttles, and the CPU and memory consumed. This is the operational health of the agent process itself.

Press enter or click to view image in full size
Runtime sub-tab showing sessions, invocations, and resource consumption
Runtime sub-tab showing sessions, invocations, and resource consumption

3.9 All sessions

A session is one complete user interaction, correlated by the session id that the client sends. This tab lists the sessions and lets you drill into any of them. Because the traffic generator keeps one session per user, you can follow a user’s whole visit here, including how the Memory component accumulates context across turns.

Press enter or click to view image in full size
All sessions tab listing agent sessions

3.10 All traces

A trace is one request-response cycle: a single invocation of the agent, from the incoming prompt to the final answer. This tab lists the traces with their latency and status, which is the fastest way to spot a slow or failed turn.

Press enter or click to view image in full size
All traces tab listing request-response cycles with latency and status
All traces tab listing request-response cycles with latency and status

3.11 All spans

A span is one operation inside a trace: a reasoning step, a model call, a tool invocation, a memory lookup. Opening a trace breaks it into its spans, each with its own duration and token count. This per-step attribution across components is what no single service view gives you, and it is where you look when you need to know exactly where a request spent its time.

Press enter or click to view image in full size
All spans tab showing individual operations within traces
All spans tab showing individual operations within traces

Step 4: Clean Up

Everything in this article is infrastructure as code, so tearing it down is a single command. From the environment directory:

export AWS_PROFILE=<your-profile>
terraform destroy

For pricing details on the services involved, check the AgentCore pricing page and the Amazon Bedrock pricing page.

Conclusion

The earlier articles answered the question “how do I configure this one component?” This one answers the question the series had left open: “what does it look like when all of them run together?”

The consolidated build makes a few things clear:

  • A single AgentCore agent can combine Gateway tools, Code Interpreter, Web Search, Browser, Memory, Knowledge Bases, and Identity, with very little orchestration code. The LangGraph agent is a standard reactive agent; the platform does the heavy lifting.
  • Infrastructure as code covers the AgentCore resources themselves now, so the entire environment, including the Runtime, Gateway, and tools, is reproducible with Terraform.
  • Observability is where the integrated system becomes legible. From one CloudWatch namespace you can see which tool the agent chose, how long each call took, how tokens were spent, and whether access control did its job, all attributed to the right component.

The most useful takeaway is that the value of these components compounds when they are combined. Identity decides who gets in, Gateway routes to the right tool, the Knowledge Base and Web Search ground the answer, the Code Interpreter makes the math exact, Memory personalizes across visits, and Observability lets you see the whole chain. Building each one in isolation teaches you the mechanics. Watching them run together is what shows you the system.

References

Stay Connected

If you found this article helpful and want to learn more about AWS, cloud architecture, AI, infrastructure as code, and cloud security, follow the author for future content and tutorials:

Stay tuned for more practical walkthroughs and solutions for cloud infrastructure and DevOps challenges.

Happy building on AWS! 🚀☁️

--

Carlos Biagolini
Carlos Biagolini

Written by Carlos Biagolini

Cloud Architect | Writing about AWS, AI/ML, and hands-on cloud solutions | AWS Community Builder

AWS Tip
AWS Tip

Published in AWS Tip

Best AWS, DevOps, Serverless, and more from top Medium writers .