<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Evgeny Anikiev</title>
    <description>The latest articles on DEV Community by Evgeny Anikiev (@evgeny_anikiev).</description>
    <link>https://dev.to/evgeny_anikiev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4061302%2F414277a4-4f95-403c-8647-575ca465dfcf.jpg</url>
      <title>DEV Community: Evgeny Anikiev</title>
      <link>https://dev.to/evgeny_anikiev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/evgeny_anikiev"/>
    <language>en</language>
    <item>
      <title>Bedrock Managed Agents vs AgentCore: Which Should Run Your Agents?</title>
      <dc:creator>Evgeny Anikiev</dc:creator>
      <pubDate>Mon, 26 Oct 2026 16:03:52 +0000</pubDate>
      <link>https://dev.to/evgeny_anikiev/bedrock-managed-agents-vs-agentcore-which-should-run-your-agents-59bg</link>
      <guid>https://dev.to/evgeny_anikiev/bedrock-managed-agents-vs-agentcore-which-should-run-your-agents-59bg</guid>
      <description>&lt;p&gt;&lt;strong&gt;AWS now offers two ways to run AI agents: an OpenAI agent loop that Amazon Bedrock manages for you, or your own agent code on AgentCore. Here is what each one does, what the preview can't do yet, and how to choose.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Evgeny Anikiev, AWS-certified DevOps engineer with 10+ years running build automation, CI/CD, and Kubernetes in production. Checked against the Amazon Bedrock and AgentCore documentation on October 26, 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Amazon Bedrock Managed Agents, powered by OpenAI, is a managed agent loop. You send instructions, skills, and a message, and AWS runs the conversation with an OpenAI model while the tools run on compute you provide. Amazon Bedrock AgentCore is a set of services for agents you build yourself, with any framework and any model: Runtime, Gateway, Memory, Identity, Policy, Observability, and Evaluations. Pick Managed Agents for internal agents on OpenAI models that work on files and run shell commands, and accept that it is a preview in three US Regions with no subagents or long-term memory. Pick AgentCore for customer-facing agents, non-OpenAI models, or anything that needs Cedar policy checks on tool calls. The two also combine: Managed Agents can run its tools inside AgentCore Runtime.&lt;/p&gt;

&lt;p&gt;What this post covers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What each service is, in one paragraph each.&lt;/li&gt;
&lt;li&gt;A side-by-side table: models, Regions, tools, memory, security, and pricing.&lt;/li&gt;
&lt;li&gt;What the Managed Agents preview does not support yet.&lt;/li&gt;
&lt;li&gt;How to start a Managed Agents session, with the IAM role it needs.&lt;/li&gt;
&lt;li&gt;A worked example: three agents, three choices.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What is Amazon Bedrock Managed Agents?
&lt;/h2&gt;

&lt;p&gt;Amazon Bedrock Managed Agents, powered by OpenAI (BMA in the AWS docs), runs OpenAI-model agents in your AWS account. AWS announced the public preview at the end of September 2026. It is built on a customized version of OpenAI's Agents API, adapted to use AWS identities and resources.&lt;/p&gt;

&lt;p&gt;The documentation describes how the work splits: "The service manages the agent's conversation and model interactions. Tools execute in the compute environment that you provide." You do not write the agent loop. You write instructions, add skills (folders with a &lt;code&gt;SKILL.md&lt;/code&gt; file) and local MCP servers, and point the session at an execution environment.&lt;/p&gt;

&lt;p&gt;That environment is one of two types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;self_hosted&lt;/code&gt;&lt;/strong&gt;: a &lt;code&gt;codex exec-server&lt;/code&gt; process on a machine or container you run. It opens an outbound HTTPS and WebSocket connection to the service, so it needs no inbound ports.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;aws_bedrock_agentcore&lt;/code&gt;&lt;/strong&gt;: an AgentCore Runtime that contains the exec server. AWS's example CDK app creates the Runtime, storage, and networking for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Model inference runs in the Bedrock service on the &lt;code&gt;bedrock-mantle&lt;/code&gt; endpoint. Your environment only runs the tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Amazon Bedrock AgentCore?
&lt;/h2&gt;

&lt;p&gt;Amazon Bedrock AgentCore is a set of services for running agents that you write. AgentCore Runtime is framework-agnostic: AWS documents agents built with Strands Agents, LangGraph, and CrewAI running on it, and the agent can call models on Bedrock or from other providers. Each Runtime session gets its own microVM, lasts up to 8 hours, and ends after 15 minutes of inactivity by default.&lt;/p&gt;

&lt;p&gt;Around Runtime sit the other parts, and you use only the ones you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gateway&lt;/strong&gt; turns APIs and Lambda functions into MCP tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policy&lt;/strong&gt; checks every tool call through Gateway against Cedar rules. It became generally available on March 3, 2026.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt; keeps short-term conversation state and long-term records per user.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity&lt;/strong&gt; handles inbound auth and outbound credentials, so tools don't need keys in code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability&lt;/strong&gt; sends traces to Amazon CloudWatch in your account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluations&lt;/strong&gt; scores live traces with 13 built-in evaluators. It became generally available on March 31, 2026.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With AgentCore you own the loop: which model to call, when to call a tool, how to retry, and what to store. If you're moving an existing agent there, my &lt;a href="https://medium.com/@anikievev/migrating-ai-agents-to-aws-15-bedrock-and-agentcore-checks-482b7c664962" rel="noopener noreferrer"&gt;15-check AgentCore readiness score&lt;/a&gt; covers what to prepare.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bedrock Managed Agents vs AgentCore: side by side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Bedrock Managed Agents (preview)&lt;/th&gt;
&lt;th&gt;AgentCore (your own agent)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Who writes the agent loop&lt;/td&gt;
&lt;td&gt;AWS and OpenAI&lt;/td&gt;
&lt;td&gt;You, with Strands, LangGraph, CrewAI, or your own code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Models&lt;/td&gt;
&lt;td&gt;OpenAI models available in the Region&lt;/td&gt;
&lt;td&gt;Any model on Bedrock or from another provider&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Status&lt;/td&gt;
&lt;td&gt;Public preview; "Preview functionality and APIs can change"&lt;/td&gt;
&lt;td&gt;Runtime, Gateway, Policy, and Evaluations generally available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regions&lt;/td&gt;
&lt;td&gt;US East (N. Virginia), US West (Oregon), US East (Ohio)&lt;/td&gt;
&lt;td&gt;More Regions; check the AgentCore Region list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Endpoint&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;bedrock-mantle&lt;/code&gt;, path &lt;code&gt;/openai/v1/agents/sessions&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bedrock-agentcore&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Where tools run&lt;/td&gt;
&lt;td&gt;Your machine or container, or AgentCore Runtime&lt;/td&gt;
&lt;td&gt;AgentCore Runtime (microVM per session)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tools&lt;/td&gt;
&lt;td&gt;Skills (&lt;code&gt;SKILL.md&lt;/code&gt; folders) and STDIO MCP servers; shell commands in the environment&lt;/td&gt;
&lt;td&gt;Gateway MCP tools, plus whatever your framework supports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool-call policy&lt;/td&gt;
&lt;td&gt;Not described in the BMA docs&lt;/td&gt;
&lt;td&gt;Cedar rules in AgentCore Policy, enforced at Gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;Session context only; "No built-in long-term memory integration"&lt;/td&gt;
&lt;td&gt;AgentCore Memory, short-term and long-term&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Subagents&lt;/td&gt;
&lt;td&gt;"Not supported"&lt;/td&gt;
&lt;td&gt;Whatever your framework supports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input&lt;/td&gt;
&lt;td&gt;Text&lt;/td&gt;
&lt;td&gt;Whatever your code accepts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Console&lt;/td&gt;
&lt;td&gt;None; APIs and deployment examples only&lt;/td&gt;
&lt;td&gt;Console, CLI, and SDKs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pricing&lt;/td&gt;
&lt;td&gt;Model inference plus the AWS resources you use&lt;/td&gt;
&lt;td&gt;Model inference plus a meter per AgentCore service&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The table comes down to who owns the agent code. With Managed Agents, AWS and OpenAI own it, and you supply the workspace and the skills. With AgentCore, you own it, and AWS supplies the hosting and the governance parts around it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What can't Bedrock Managed Agents do yet?
&lt;/h2&gt;

&lt;p&gt;The preview's limitations page lists these, and each one decides a use case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No subagents.&lt;/strong&gt; One agent per session. If your design hands work from a planner to specialist agents, build it on AgentCore.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No cross-Region inference profiles.&lt;/strong&gt; Inference runs in the Region you call, and you can't route it to other Regions for extra capacity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text input only.&lt;/strong&gt; No images or files in the session input. Files go into the workspace instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No long-term memory.&lt;/strong&gt; A session keeps its conversation, and that's all. Anything the agent should remember across sessions has to live in files or your own store.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No turn list or turn retrieval API.&lt;/strong&gt; You follow progress through the event stream and the &lt;code&gt;turn_id&lt;/code&gt; on each item.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No service-managed KMS key option for session data&lt;/strong&gt; and no programmatic tool calling (code mode).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No console.&lt;/strong&gt; Everything goes through the API and the example scripts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two behaviors matter in production. Deleting a session does not delete files in your workspace, S3 data, or the AgentCore Runtime stack, so clean those up yourself. Cancelling a turn does not undo what a tool already did: if the agent ran a command that changed something, cancel stops the next step, not that one.&lt;/p&gt;




&lt;h2&gt;
  
  
  How do I start a Bedrock Managed Agents session?
&lt;/h2&gt;

&lt;p&gt;You need three pieces: a session role that the service assumes to call the model, permissions for your client, and an execution environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The session role
&lt;/h3&gt;

&lt;p&gt;The trust policy lets the &lt;code&gt;bedrock-mantle&lt;/code&gt; service assume the role, scoped to your account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bedrock-mantle.amazonaws.com"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"StringEquals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"aws:SourceAccount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123456789012"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ArnLike"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"aws:SourceArn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:bedrock-mantle:*:123456789012:*"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The permissions policy allows inference on one model only. This is where you pin the model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bedrock-mantle:CreateInference"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"StringEquals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"bedrock-mantle:Model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"openai.gpt-5.6-luna"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Client permissions
&lt;/h3&gt;

&lt;p&gt;The caller needs &lt;code&gt;bedrock-mantle:CreateAgentSession&lt;/code&gt;, &lt;code&gt;GetAgentSession&lt;/code&gt;, &lt;code&gt;ListAgentSessions&lt;/code&gt;, &lt;code&gt;CreateAgentSessionEvent&lt;/code&gt;, &lt;code&gt;ListAgentSessionEvents&lt;/code&gt;, &lt;code&gt;ListAgentSessionItems&lt;/code&gt;, and &lt;code&gt;DeleteAgentSession&lt;/code&gt;. It also needs &lt;code&gt;iam:PassRole&lt;/code&gt; on the session role, with the condition &lt;code&gt;"iam:PassedToService": "bedrock-mantle.amazonaws.com"&lt;/code&gt;. A self-hosted exec server additionally needs &lt;code&gt;bedrock-mantle:RegisterEnvironment&lt;/code&gt; and &lt;code&gt;bedrock-mantle:ConnectEnvironment&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Create the session and send a message
&lt;/h3&gt;

&lt;p&gt;Requests are signed with SigV4 for the service name &lt;code&gt;bedrock-mantle&lt;/code&gt;. curl can sign them with &lt;code&gt;--aws-sigv4&lt;/code&gt;. With temporary credentials, pass the session token as a header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;ENDPOINT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://bedrock-mantle.us-east-1.api.aws
&lt;span class="nv"&gt;SIGN&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="nt"&gt;--aws-sigv4&lt;/span&gt; &lt;span class="s2"&gt;"aws:amz:us-east-1:bedrock-mantle"&lt;/span&gt;
      &lt;span class="nt"&gt;--user&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-amz-security-token: &lt;/span&gt;&lt;span class="nv"&gt;$AWS_SESSION_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SIGN&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENDPOINT&lt;/span&gt;&lt;span class="s2"&gt;/openai/v1/agents/sessions"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
  "agent": {
    "model": "openai.gpt-5.6-luna",
    "instructions": "Use the workspace tools to complete the user'&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;'s task."
  },
  "environment": {
    "type": "self_hosted",
    "workspace_directory": "/srv/agent/workspace",
    "capability_directories": ["/srv/agent/workspace/skills"]
  },
  "role_arn": "arn:aws:iam::123456789012:role/BedrockManagedAgentsSessionRole",
  "stream": false
}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take the session ID from the response, then submit a message as an event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;SESSION_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;&lt;span class="nb"&gt;id &lt;/span&gt;from the response&amp;gt;

curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SIGN&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENDPOINT&lt;/span&gt;&lt;span class="s2"&gt;/openai/v1/agents/sessions/&lt;/span&gt;&lt;span class="nv"&gt;$SESSION_ID&lt;/span&gt;&lt;span class="s2"&gt;/events"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
  "events": [{
    "type": "agent.session.input.message",
    "input": [{"role": "user", "content": [
      {"type": "input_text", "text": "Find the failing test in this repo and propose a fix."}
    ]}]
  }]
}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow progress with &lt;code&gt;GET .../events&lt;/code&gt; (a &lt;code&gt;text/event-stream&lt;/code&gt;) and read the results with &lt;code&gt;GET .../items&lt;/code&gt;, which returns messages, reasoning summaries, command executions, and MCP calls, 20 per page by default. The session status moves between &lt;code&gt;idle&lt;/code&gt;, &lt;code&gt;in_progress&lt;/code&gt;, and &lt;code&gt;failed&lt;/code&gt;. To run tools in AgentCore Runtime instead of your own host, set &lt;code&gt;"type": "aws_bedrock_agentcore"&lt;/code&gt; with a &lt;code&gt;runtime_arn&lt;/code&gt; and a &lt;code&gt;runtime_qualifier&lt;/code&gt; such as &lt;code&gt;DEFAULT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One rule from the API reference is worth putting in your client: after a network error, check whether the create or submit call was accepted before you retry it, or you get a duplicate session or a duplicate turn.&lt;/p&gt;




&lt;h2&gt;
  
  
  How much do Bedrock Managed Agents and AgentCore cost?
&lt;/h2&gt;

&lt;p&gt;The Managed Agents documentation lists two charges: model inference and the AWS resources your application uses. When I checked the Bedrock pricing page on October 26, it had no separate Managed Agents line. Pricing can change when the service reaches general availability.&lt;/p&gt;

&lt;p&gt;The "AWS resources" part is not zero. AWS's AgentCore example creates a NAT gateway, which bills every hour whether or not a turn is running, and the Runtime bills for the compute your sessions use.&lt;/p&gt;

&lt;p&gt;AgentCore has a meter per service. List prices from the AgentCore pricing page:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;AgentCore service&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Runtime microVM (v1), CPU&lt;/td&gt;
&lt;td&gt;$0.0895 per vCPU-hour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime microVM (v1), memory&lt;/td&gt;
&lt;td&gt;$0.00945 per GB-hour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gateway, tool invocations&lt;/td&gt;
&lt;td&gt;$0.005 per 1,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Policy&lt;/td&gt;
&lt;td&gt;$0.000025 per request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory, long-term records (built-in)&lt;/td&gt;
&lt;td&gt;$0.75 per 1,000 records per month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evaluations, custom&lt;/td&gt;
&lt;td&gt;$1.50 per 1,000 evaluations, plus model usage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Runtime microVMs bill per second with a 1-second minimum. For scale: a session using 1 vCPU and 2 GB for one hour costs $0.0895 + 2 × $0.00945 = $0.1084 on v1. One million tool calls through Gateway cost $5, and a Policy check on each of them adds $25. Put these next to your monthly token spend in Cost Explorer before you decide which meter is worth optimizing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Should I use Bedrock Managed Agents or AgentCore?
&lt;/h2&gt;

&lt;p&gt;Use Managed Agents when the agent is internal, OpenAI-based, and workspace-shaped. Use AgentCore when you need a different model, memory, or policy on tool calls, or when customers see the output.&lt;/p&gt;

&lt;p&gt;Here is how that plays out for a platform team with three agents to place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. A repo maintenance agent for engineers.&lt;/strong&gt; It reads code, runs tests, and proposes fixes. Users are internal, the team already uses OpenAI models, and the work is files and shell commands. &lt;strong&gt;Choice: Managed Agents, self-hosted.&lt;/strong&gt; The exec server runs in a build container with a checkout of the repo. Skills hold the team's conventions. There is no agent code to maintain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A customer support agent with refunds.&lt;/strong&gt; It runs on a Claude model, remembers each customer between conversations, and calls a refund API. &lt;strong&gt;Choice: AgentCore.&lt;/strong&gt; It needs a non-OpenAI model, long-term memory, and a Cedar rule that blocks refunds above a set amount at Gateway. The preview offers none of those three.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. A nightly data quality agent.&lt;/strong&gt; It runs for up to six hours on an OpenAI model and should not run on anyone's laptop. &lt;strong&gt;Choice: Managed Agents with the AgentCore environment.&lt;/strong&gt; The session fits inside a Runtime session's 8-hour limit, and the tools run in an isolated microVM in the team's account. The team deletes the Runtime stack and the NAT gateway when they retire the agent, because deleting the session does not.&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is Bedrock Managed Agents the same as Amazon Bedrock Agents?&lt;/strong&gt;&lt;br&gt;
No. Amazon Bedrock Agents is the earlier Bedrock feature for building agents with action groups and knowledge bases. Bedrock Managed Agents, powered by OpenAI, is a separate preview service on the &lt;code&gt;bedrock-mantle&lt;/code&gt; endpoint that runs OpenAI's agent loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can Bedrock Managed Agents use Claude or other non-OpenAI models?&lt;/strong&gt;&lt;br&gt;
The preview documentation only covers OpenAI models supported in the Region and account. For Claude, Llama, or other models, build the agent on AgentCore Runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Bedrock Managed Agents replace AgentCore?&lt;/strong&gt;&lt;br&gt;
No. Managed Agents can use AgentCore Runtime as its execution environment. AgentCore remains the place for agents with your own code, other models, Gateway tools, Memory, and Policy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which Regions support Bedrock Managed Agents?&lt;/strong&gt;&lt;br&gt;
During the preview: US East (N. Virginia), US West (Oregon), and US East (Ohio), through regional &lt;code&gt;bedrock-mantle&lt;/code&gt; endpoints such as &lt;code&gt;https://bedrock-mantle.us-east-1.api.aws&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Bedrock Managed Agents production-ready?&lt;/strong&gt;&lt;br&gt;
It is a public preview, and AWS says preview APIs can change. It has no subagents, no long-term memory, and no console. Use it for internal agents with a fallback, and plan for API changes before general availability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does Bedrock Managed Agents cost?&lt;/strong&gt;&lt;br&gt;
The docs list model inference plus the AWS resources you use, such as AgentCore Runtime compute or your own servers. No separate agent fee appeared on the Bedrock pricing page as of October 26, 2026.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use MCP tools with Bedrock Managed Agents?&lt;/strong&gt;&lt;br&gt;
Yes, as STDIO MCP servers that run in the execution environment, configured in &lt;code&gt;agent.tools&lt;/code&gt; or the &lt;code&gt;BMA_MCP_SERVERS_JSON&lt;/code&gt; variable, each with an &lt;code&gt;allowed_tools&lt;/code&gt; list. The preview docs do not describe remote MCP servers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/migrating-ai-agents-to-aws-15-bedrock-and-agentcore-checks-482b7c664962" rel="noopener noreferrer"&gt;Migrating AI Agents to AWS: 15 Bedrock and AgentCore Checks&lt;/a&gt;: a readiness score for moving an agent to AgentCore, with Policy, Evaluations, and rollback.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/track-amazon-bedrock-costs-per-team-3-methods-compared-b71679f8a020" rel="noopener noreferrer"&gt;Track Amazon Bedrock Costs per Team: 3 Methods Compared&lt;/a&gt;: IAM principal cost allocation covers &lt;code&gt;bedrock-mantle&lt;/code&gt;, the endpoint Managed Agents uses.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/bedrock-vs-self-hosted-llms-on-eks-the-break-even-math-75f9a0b0df3d" rel="noopener noreferrer"&gt;Bedrock vs Self-Hosted LLMs on EKS: The Break-Even Math&lt;/a&gt;: when your own GPUs cost less than per-token pricing.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/cut-aws-nat-gateway-costs-7-fixes-for-platform-teams-5057570fc82d" rel="noopener noreferrer"&gt;Cut AWS NAT Gateway Costs: 7 Fixes for Platform Teams&lt;/a&gt;: the AgentCore example for Managed Agents creates a NAT gateway.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/bedrock-managed-agents-openai.html" rel="noopener noreferrer"&gt;Amazon Bedrock Managed Agents, powered by OpenAI (Amazon Bedrock User Guide)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/bedrock-managed-agents-openai-quotas-limitations.html" rel="noopener noreferrer"&gt;Preview availability and limitations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/bedrock-managed-agents-openai-api-reference.md" rel="noopener noreferrer"&gt;Managed Agents API reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/bedrock-managed-agents-openai-security.md" rel="noopener noreferrer"&gt;Managed Agents security and IAM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/bedrock-managed-agents-openai-sessions.md" rel="noopener noreferrer"&gt;Managed Agents sessions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/bedrock-managed-agents-openai-skills-tools.md" rel="noopener noreferrer"&gt;Managed Agents skills and tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/aws/aws-weekly-roundup-amazon-bedrock-managed-agents-powered-by-openai-q3-service-availability-updates-kiro-workflows-and-more-october-5-2026/" rel="noopener noreferrer"&gt;AWS Weekly Roundup, October 5, 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/what-is-bedrock-agentcore.html" rel="noopener noreferrer"&gt;Amazon Bedrock AgentCore overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-sessions.html" rel="noopener noreferrer"&gt;AgentCore Runtime: isolated sessions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/bedrock/agentcore/pricing/" rel="noopener noreferrer"&gt;Amazon Bedrock AgentCore pricing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Choosing where your agents run? I set up Bedrock and AgentCore foundations for AI teams at &lt;a href="https://devopscloudconsult.com/" rel="noopener noreferrer"&gt;DevOps Cloud Consult&lt;/a&gt;: IAM roles, networking without surprise NAT bills, observability, and cost tracking per team. Send me the agent you want to move and I'll tell you which side of this table it lands on.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Get one AWS cost fix every two weeks: &lt;a href="https://evgenyanikiev.substack.com/" rel="noopener noreferrer"&gt;subscribe on Substack&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>openai</category>
      <category>llm</category>
    </item>
    <item>
      <title>Track Amazon Bedrock Costs per Team: 3 Methods Compared</title>
      <dc:creator>Evgeny Anikiev</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:32:14 +0000</pubDate>
      <link>https://dev.to/evgeny_anikiev/track-amazon-bedrock-costs-per-team-3-methods-compared-4937</link>
      <guid>https://dev.to/evgeny_anikiev/track-amazon-bedrock-costs-per-team-3-methods-compared-4937</guid>
      <description>&lt;p&gt;&lt;strong&gt;Your Bedrock bill shows models, Regions, and tokens, with no team names. Here is how to split it by team with IAM principals, application inference profiles, or Projects, and how to put a budget on each team.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Evgeny Anikiev, AWS-certified DevOps engineer with 10+ years running build automation, CI/CD, and Kubernetes in production. Checked against the Amazon Bedrock documentation and AWS announcements on October 26, 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Amazon Bedrock cost allocation now works three ways, and each one charges inference cost to a team. &lt;strong&gt;IAM principal cost allocation&lt;/strong&gt; charges each request to the IAM user or role that made it. If each team calls Bedrock with its own role, it needs no code change. &lt;strong&gt;Application inference profiles&lt;/strong&gt; carry tags for InvokeModel and Converse calls on the bedrock-runtime endpoint. &lt;strong&gt;Projects&lt;/strong&gt; carry tags for Responses and Chat Completions calls on the bedrock-mantle endpoint. Start with IAM principals, add profiles or Projects where several teams share one role, and put an AWS Budget on each team's tag. Cost Anomaly Detection does not cover AWS Marketplace charges, so do not rely on it alone.&lt;/p&gt;

&lt;p&gt;What this post covers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Why the default Bedrock bill can't answer "which team spent this".&lt;/li&gt;
&lt;li&gt;The three methods side by side, with the endpoints each one covers.&lt;/li&gt;
&lt;li&gt;Setup commands for each method.&lt;/li&gt;
&lt;li&gt;A per-team budget with the AWS CLI.&lt;/li&gt;
&lt;li&gt;The limits: delays, the payer account, and what CUR does not show.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Why doesn't my Bedrock bill show which team spent the money?
&lt;/h2&gt;

&lt;p&gt;By default, Cost Explorer and the Cost and Usage Report (CUR) group Bedrock spend by model, Region, and token type. A usage type such as &lt;code&gt;USE1-Claude4.6Sonnet-input-tokens&lt;/code&gt; tells you what was used and where, but nothing on that line says who sent the request. When three teams share one AWS account and one model, their spend lands on the same lines.&lt;/p&gt;

&lt;p&gt;You can't fix this by tagging the model. On-demand foundation models are AWS-owned resources, so there is nothing of yours to tag. AWS added three ways around that, and each one covers different APIs.&lt;/p&gt;

&lt;p&gt;In May 2026, The Register reported on a reader who ran Claude Opus through Bedrock and received a $30,141.33 bill for April. Cost Anomaly Detection was set up and never fired. AWS told the publication that AWS Marketplace charges are not supported by Cost Anomaly Detection, and that AWS Budgets does cover Bedrock spend billed through Marketplace. A budget on that spend is the alert that would have covered it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Which Bedrock cost allocation method should I use?
&lt;/h2&gt;

&lt;p&gt;Use IAM principal cost allocation first, because it needs no code change when each team or application already has its own IAM role. Add application inference profiles when several teams share one role and call InvokeModel or Converse. Use Projects for apps on the OpenAI-compatible Responses or Chat Completions APIs. You can run all three in one account.&lt;/p&gt;

&lt;p&gt;The three methods, side by side:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What cost is charged to:&lt;/strong&gt; IAM principals charge the IAM user or role that made the call. Application inference profiles charge the profile the app called. Projects charge the project ID the app sent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Endpoints and APIs:&lt;/strong&gt; IAM principals cover bedrock-runtime (since April 9, 2026) and bedrock-mantle (since August 11, 2026). Application inference profiles cover InvokeModel and Converse on bedrock-runtime. Projects cover Responses and Chat Completions on bedrock-mantle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code change:&lt;/strong&gt; IAM principals need none if each team has its own role. Profiles need the app to call the profile ARN in place of the model ID. Projects need the app to send a project ID.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where you see it:&lt;/strong&gt; IAM principal data needs a CUR 2.0 export with caller identity turned on, and principal tags also show in Cost Explorer. Profile and Project tags show in Cost Explorer, classic CUR, and CUR 2.0.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scaling limit:&lt;/strong&gt; IAM principals and session tags allow up to 50 tags per user or role. Application inference profiles are tied to one model, so you need one profile per model, team, and tag set. Projects allow up to 1,000 per account and are not tied to a model.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Method 1: How do I allocate Bedrock costs by IAM role?
&lt;/h2&gt;

&lt;p&gt;Tag the IAM roles and users that call Bedrock and activate those tags in the management account. Then turn on caller identity data in a CUR 2.0 export. Bedrock records the caller's ARN on each CUR line and copies the role's tags with an &lt;code&gt;iamPrincipal/&lt;/code&gt; prefix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Tag each role that calls Bedrock.&lt;/strong&gt; One role per team or per application keeps this simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws iam tag-role &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--role-name&lt;/span&gt; support-agent-prod &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tags&lt;/span&gt; &lt;span class="nv"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;team,Value&lt;span class="o"&gt;=&lt;/span&gt;support &lt;span class="nv"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;cost-center,Value&lt;span class="o"&gt;=&lt;/span&gt;cc-1042
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Pass session tags for shared roles.&lt;/strong&gt; When one role serves many teams or tenants, pass tags when the caller assumes the role. A session tag overrides a principal tag with the same key for that session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws sts assume-role &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--role-arn&lt;/span&gt; arn:aws:iam::123456789012:role/bedrock-shared &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--role-session-name&lt;/span&gt; tenant-acme &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tags&lt;/span&gt; &lt;span class="nv"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tenant,Value&lt;span class="o"&gt;=&lt;/span&gt;acme
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The role's trust policy must allow &lt;code&gt;sts:TagSession&lt;/code&gt; for this to work. Federated users from an identity provider such as Okta or Microsoft Entra ID can carry session tags the same way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Activate the tags.&lt;/strong&gt; In the Billing and Cost Management console, open &lt;strong&gt;Cost allocation tags&lt;/strong&gt;, select the &lt;code&gt;iamPrincipal/&lt;/code&gt; tags, and choose &lt;strong&gt;Activate&lt;/strong&gt;. Do this from the management (payer) account. Member accounts can't activate them. A tag only appears in the list after that principal has made at least one Bedrock call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Turn on caller identity in CUR 2.0.&lt;/strong&gt; In &lt;strong&gt;Data Exports&lt;/strong&gt;, create a CUR 2.0 export and select &lt;strong&gt;Include caller identity (IAM principal) allocation data&lt;/strong&gt;. Legacy CUR does not carry these fields, and existing exports don't pick up identity data for past periods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Query it.&lt;/strong&gt; CUR 2.0 adds a &lt;code&gt;line_item_iam_principal&lt;/code&gt; column with the caller's ARN, such as &lt;code&gt;arn:aws:sts::123456789012:assumed-role/support-agent-prod/session-123&lt;/code&gt;. In Athena, group by it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;line_item_iam_principal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;line_item_product_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_item_unblended_cost&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;cost_usd&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;   &lt;span class="n"&gt;cur2_export&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt;  &lt;span class="n"&gt;line_item_iam_principal&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt;  &lt;span class="n"&gt;line_item_usage_start_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="s1"&gt;'2026-10-01 00:00:00'&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt;  &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt;  &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;cost_usd&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;cur2_export&lt;/code&gt; with your export's table name. In Cost Explorer, principal tags appear under the &lt;strong&gt;IAM&lt;/strong&gt; category of the Tags filter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Method 2: How do I tag Bedrock usage with application inference profiles?
&lt;/h2&gt;

&lt;p&gt;An application inference profile is a copy of a model ID that you own and can tag. Create one per team and model, then have each team's app call its profile ARN. The profile's tags go onto the billing record for every request made through it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create the profile.&lt;/strong&gt; The source can be a foundation model or a cross-Region (system-defined) inference profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws bedrock create-inference-profile &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--inference-profile-name&lt;/span&gt; support-agent-gpt-oss-120b &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--model-source&lt;/span&gt; &lt;span class="nv"&gt;copyFrom&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:bedrock:us-east-1::foundation-model/openai.gpt-oss-120b-1:0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tags&lt;/span&gt; &lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;team,value&lt;span class="o"&gt;=&lt;/span&gt;support &lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;cost-center,value&lt;span class="o"&gt;=&lt;/span&gt;cc-1042
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response returns &lt;code&gt;inferenceProfileArn&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Call the profile ARN in place of the model ID:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="n"&gt;bedrock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bedrock-runtime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;converse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arn:aws:bedrock:us-east-1:123456789012:inference-profile/abc123example&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarize ticket 4821&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}]}],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Activate the tags&lt;/strong&gt; (&lt;code&gt;team&lt;/code&gt;, &lt;code&gt;cost-center&lt;/code&gt;) in &lt;strong&gt;Cost allocation tags&lt;/strong&gt;, the same as in Method 1.&lt;/p&gt;

&lt;p&gt;Application inference profiles don't work with the Responses or Chat Completions APIs on either endpoint. A request to those APIs that names a profile is rejected with a 400 error. Profiles also add up, since three teams on two models need six profiles. Keep them in Terraform or CloudFormation so the list stays readable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Method 3: How do I track Bedrock costs with Projects?
&lt;/h2&gt;

&lt;p&gt;Projects are the tagging method for the bedrock-mantle endpoint, which serves the OpenAI-compatible Responses and Chat Completions APIs. Create a project per team or application, tag it, and have the client send the project ID. A project is not tied to a model, so one project covers every model the team calls.&lt;/p&gt;

&lt;p&gt;You manage projects through the Projects API under the mantle base URL. &lt;code&gt;POST /organization/projects&lt;/code&gt; with a name and tags creates a project. &lt;code&gt;POST /organization/projects/{id}&lt;/code&gt; with &lt;code&gt;add_tags&lt;/code&gt; or &lt;code&gt;remove_tag_keys&lt;/code&gt; changes its tags. There is no operation that replaces the whole tag set at once.&lt;/p&gt;

&lt;p&gt;The client sends the project ID with each request. With the OpenAI Python SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;proj_123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# base_url and API key for bedrock-mantle set as usual
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With plain HTTP, send the header &lt;code&gt;OpenAI-Project: proj_123&lt;/code&gt;. Requests without a project ID go to your account's default project, which can't be tagged. An archived project rejects new requests and keeps its metrics for 30 days.&lt;/p&gt;




&lt;h2&gt;
  
  
  How do I set a Bedrock budget per team?
&lt;/h2&gt;

&lt;p&gt;Create one AWS Budget per team with a tag filter. Budgets covers Bedrock spend billed through AWS Marketplace, which Cost Anomaly Detection does not. Use the tag key exactly as it appears in Cost Explorer's tag list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws budgets create-budget &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--account-id&lt;/span&gt; 123456789012 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--budget&lt;/span&gt; &lt;span class="s1"&gt;'{
    "BudgetName": "bedrock-support-monthly",
    "BudgetLimit": {"Amount": "2000", "Unit": "USD"},
    "TimeUnit": "MONTHLY",
    "BudgetType": "COST",
    "FilterExpression": {
      "Tags": {"Key": "team", "Values": ["support"], "MatchOptions": ["EQUALS"]}
    },
    "Metrics": ["UnblendedCost"]
  }'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--notifications-with-subscribers&lt;/span&gt; &lt;span class="s1"&gt;'[{
    "Notification": {
      "NotificationType": "FORECASTED",
      "ComparisonOperator": "GREATER_THAN",
      "Threshold": 80,
      "ThresholdType": "PERCENTAGE"
    },
    "Subscribers": [{"SubscriptionType": "EMAIL", "Address": "support-leads@example.com"}]
  }]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A forecast alert at 80% gives the team warning before the month ends. Add a second notification of type &lt;code&gt;ACTUAL&lt;/code&gt; at 100% for the hard line.&lt;/p&gt;

&lt;p&gt;To see all teams at once, group Cost Explorer by the same tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ce get-cost-and-usage &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--time-period&lt;/span&gt; &lt;span class="nv"&gt;Start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2026-10-01,End&lt;span class="o"&gt;=&lt;/span&gt;2026-11-01 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--granularity&lt;/span&gt; MONTHLY &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--metrics&lt;/span&gt; UnblendedCost &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group-by&lt;/span&gt; &lt;span class="nv"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;TAG,Key&lt;span class="o"&gt;=&lt;/span&gt;team
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What can't Bedrock cost allocation tell you?
&lt;/h2&gt;

&lt;p&gt;All three methods report cost per team per day or per hour. None of them gives cost per request or per prompt. Plan around these limits before you promise finance a number:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Delay:&lt;/strong&gt; Tags take up to 24 hours to appear in Cost Explorer and CUR after activation. AWS's launch blog says 24 to 48 hours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not retroactive:&lt;/strong&gt; Cost allocation tags only apply from activation onward. Spend before that stays untagged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payer account only:&lt;/strong&gt; Tag activation happens in the management account. If you're a team in a member account, ask whoever owns billing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No per-request cost:&lt;/strong&gt; CUR rows are aggregated by usage type and time period, with no request ID. For per-request or per-prompt cost, use model invocation logs and join them to CUR at the model and usage-type level. Session tags are not written to invocation logs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;STS limits:&lt;/strong&gt; If you pass a session tag per tenant, every tenant switch is an AssumeRole call. The default STS quota is 500 AssumeRole calls per second per account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marketplace alerts:&lt;/strong&gt; Cost Anomaly Detection does not support AWS Marketplace charges. Check how your model's charges are billed, and use Budgets for alerts.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Worked example: three teams in one Bedrock account
&lt;/h2&gt;

&lt;p&gt;A company runs three AI workloads in one AWS account:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The support agent&lt;/strong&gt; runs on EKS under the IAM role &lt;code&gt;support-agent-prod&lt;/code&gt; and calls Converse. The role gets &lt;code&gt;team=support&lt;/code&gt;. That is Method 1, with no code change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The data science team&lt;/strong&gt; signs in through Okta and runs notebooks against several models. Their identity provider passes &lt;code&gt;team=data-science&lt;/code&gt; as a session tag. That is Method 1 again, with no code change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The internal chatbot&lt;/strong&gt; is built on the OpenAI SDK and calls the Responses API on bedrock-mantle. It gets a project tagged &lt;code&gt;team=platform&lt;/code&gt;. That is Method 3, with one line of client config.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Application inference profiles enter only if the support agent and a second app later share one role. Each team gets a budget filtered on &lt;code&gt;team&lt;/code&gt;. Finance gets one Cost Explorer view grouped by &lt;code&gt;team&lt;/code&gt;, with every Bedrock dollar assigned to a team.&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can I tag an Amazon Bedrock foundation model directly?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. On-demand foundation models belong to AWS, so you can't tag them. Tag the IAM principal that calls the model, call it through a tagged application inference profile, or send a tagged project ID on bedrock-mantle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long until Bedrock cost allocation tags show up in Cost Explorer?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Up to 24 hours after you activate the tags. AWS's launch blog says 24 to 48 hours. IAM principal tags only appear after that principal has made at least one Bedrock call. Tags don't apply to spend from before activation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need CUR 2.0 for Bedrock cost allocation by IAM role?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, for line-item caller data. The &lt;code&gt;line_item_iam_principal&lt;/code&gt; column and principal tag data exist only in CUR 2.0 exports with "Include caller identity (IAM principal) allocation data" selected. Legacy CUR does not have them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do application inference profiles work with cross-Region inference?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Create the application inference profile from a cross-Region (system-defined) inference profile in place of a single-Region foundation model. Requests then route across Regions, and the profile's tags still apply.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I get the cost of a single Bedrock request?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not from CUR or Cost Explorer. Both aggregate by usage type over an hour or a day. Use model invocation logs for token counts per request, multiply by the model's price, and reconcile the total against CUR.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does AWS Cost Anomaly Detection catch Bedrock cost spikes?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not when the charges are billed through AWS Marketplace. AWS told The Register in May 2026 that Cost Anomaly Detection does not support Marketplace charges, after a reader's $30,141.33 Claude bill raised no alert. AWS Budgets does cover Bedrock spend billed through Marketplace, so set a budget per team as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I split Bedrock costs per tenant in a SaaS product?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pass the tenant as a session tag when your service assumes the Bedrock role. On bedrock-mantle, you can give each tenant its own project instead. Watch the STS quota of 500 AssumeRole calls per second if you assume a role per request.&lt;/p&gt;




&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/bedrock-vs-self-hosted-llms-on-eks-the-break-even-math-75f9a0b0df3d" rel="noopener noreferrer"&gt;Bedrock vs Self-Hosted LLMs on EKS: The Break-Even Math&lt;/a&gt;: when your own GPUs cost less than per-token pricing.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/migrating-ai-agents-to-aws-15-bedrock-and-agentcore-checks-482b7c664962" rel="noopener noreferrer"&gt;Migrating AI Agents to AWS: 15 Bedrock and AgentCore Checks&lt;/a&gt;: a readiness score for AI teams moving agents to Bedrock and AgentCore, cost tracking included.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/cut-aws-nat-gateway-costs-7-fixes-for-platform-teams-5057570fc82d" rel="noopener noreferrer"&gt;Cut AWS NAT Gateway Costs: 7 Fixes for Platform Teams&lt;/a&gt;: model weights and container images pulled through a NAT gateway pay $0.045 per GB in US East.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/eks-1-37-upgrade-checklist-what-breaks-and-how-to-test-it-1a08b9f2fe05" rel="noopener noreferrer"&gt;EKS 1.37 Upgrade Checklist: What Breaks and How to Test It&lt;/a&gt;: for the clusters your Bedrock callers run on.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/cost-mgmt-application-inference-profiles.html" rel="noopener noreferrer"&gt;Application inference profiles (Amazon Bedrock User Guide)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-create.html" rel="noopener noreferrer"&gt;Create an application inference profile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/cost-mgmt-projects.html" rel="noopener noreferrer"&gt;Projects (Amazon Bedrock User Guide)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/cost-mgmt-understanding-cur-data.html" rel="noopener noreferrer"&gt;Understanding your Amazon Bedrock Cost and Usage Report data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/04/bedrock-iam-cost-allocation" rel="noopener noreferrer"&gt;Amazon Bedrock now supports cost allocation by IAM user and role (April 9, 2026)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/08/amazon-bedrock-expands-iam-principal-cost-allocation-bedrock-mantle/" rel="noopener noreferrer"&gt;Amazon Bedrock expands IAM principal cost allocation to the bedrock-mantle endpoint (August 11, 2026)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/machine-learning/introducing-granular-cost-attribution-for-amazon-bedrock/" rel="noopener noreferrer"&gt;Introducing granular cost attribution for Amazon Bedrock (AWS Machine Learning Blog, April 17, 2026)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.theregister.com/saas/2026/05/14/bedrock-and-a-hard-place-claude-adventure-leaves-aws-user-staring-down-30k-invoice/5238153" rel="noopener noreferrer"&gt;Bedrock and a hard place: Claude adventure leaves AWS user staring down $30K invoice (The Register, May 14, 2026)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/reference/bedrock/create-inference-profile.html" rel="noopener noreferrer"&gt;AWS CLI: bedrock create-inference-profile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/reference/budgets/create-budget.html" rel="noopener noreferrer"&gt;AWS CLI: budgets create-budget&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Can't tell which team spent last month's Bedrock bill? I set up cost allocation and budgets for AI teams on AWS at &lt;a href="https://devopscloudconsult.com/" rel="noopener noreferrer"&gt;DevOps Cloud Consult&lt;/a&gt;. Send me your Bedrock line from Cost Explorer and I'll map which method fits each workload.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Get one AWS cost fix every two weeks: &lt;a href="https://evgenyanikiev.substack.com/" rel="noopener noreferrer"&gt;subscribe on Substack&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>finops</category>
      <category>llm</category>
      <category>devops</category>
    </item>
    <item>
      <title>Bedrock vs Self-Hosted LLMs on EKS: The Break-Even Math</title>
      <dc:creator>Evgeny Anikiev</dc:creator>
      <pubDate>Fri, 23 Oct 2026 09:51:49 +0000</pubDate>
      <link>https://dev.to/evgeny_anikiev/bedrock-vs-self-hosted-llms-on-eks-the-break-even-math-5627</link>
      <guid>https://dev.to/evgeny_anikiev/bedrock-vs-self-hosted-llms-on-eks-the-break-even-math-5627</guid>
      <description>&lt;p&gt;&lt;strong&gt;When do your own GPUs beat Amazon Bedrock for the same open-weight model? Official AWS prices, the tokens per second you need to break even, and the Karpenter and vLLM config to test it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Evgeny Anikiev, AWS-certified DevOps engineer with 10+ years running build automation, CI/CD, and Kubernetes in production. Prices pulled from the AWS Price List API on October 23, 2026 (US East, N. Virginia, on-demand list prices).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; The same open-weight model costs per token on Bedrock and per hour on your own GPUs. One H100 on a &lt;code&gt;p5.4xlarge&lt;/code&gt; running gpt-oss-120b costs $5,022 a month. To beat Bedrock's price for that model, it has to process about 7,300 tokens per second, around the clock, every day of the month. Unless your traffic is that high and that steady, Bedrock costs less. Self-hosting also makes sense when you need a model Bedrock doesn't offer.&lt;/p&gt;

&lt;p&gt;The numbers in this post:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Bedrock prices for gpt-oss-120b, gpt-oss-20b, and Llama 3.3 70B.&lt;/li&gt;
&lt;li&gt;EC2 GPU instance prices for the instances that fit each model.&lt;/li&gt;
&lt;li&gt;The break-even volume in tokens per month and tokens per second.&lt;/li&gt;
&lt;li&gt;The costs a per-token price hides and a per-hour price doesn't.&lt;/li&gt;
&lt;li&gt;A Karpenter NodePool and vLLM Deployment to run your own benchmark.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Which costs less: Amazon Bedrock or self-hosting on EKS?
&lt;/h2&gt;

&lt;p&gt;Unless a GPU stays busy around the clock, Bedrock costs less. Bedrock bills per token and costs nothing when idle. A self-hosted model on EKS bills per GPU-hour whether it serves traffic or not. Self-hosting only wins when a GPU stays busy enough that its hourly cost divided by its tokens drops below Bedrock's per-token price. For gpt-oss-120b on one H100, that point is about 19 billion tokens a month.&lt;/p&gt;

&lt;p&gt;Bedrock and self-hosting on EKS, side by side:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Billing:&lt;/strong&gt; Bedrock charges per million tokens. EKS charges per GPU-hour, plus $73 a month for the cluster control plane.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Idle cost:&lt;/strong&gt; zero on Bedrock. Full hourly price on EKS until the node is removed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scaling:&lt;/strong&gt; Bedrock scales within your tokens-per-minute quota. On EKS, you scale GPU nodes yourself, with cold starts of several minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Models:&lt;/strong&gt; Bedrock offers its catalog plus Custom Model Import. EKS runs any open-weight model that fits your GPUs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operations:&lt;/strong&gt; AWS runs Bedrock. On EKS, your team owns drivers, the serving engine, autoscaling, and on-call.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What does each option cost?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bedrock: per token
&lt;/h3&gt;

&lt;p&gt;These are on-demand (Standard tier) prices per million tokens in US East, from the AWS Price List API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;gpt-oss-120b:&lt;/strong&gt; $0.15 input, $0.60 output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gpt-oss-20b:&lt;/strong&gt; $0.07 input, $0.30 output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Llama 3.3 70B Instruct:&lt;/strong&gt; $0.72 input, $0.72 output.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Batch inference and the Flex tier halve these prices for work that can wait, for example $0.075 input and $0.30 output for gpt-oss-120b.&lt;/p&gt;

&lt;p&gt;Agents send far more input than they get back, because every call resends the conversation and tool results. With 3 input tokens for every output token, the blended price per million tokens is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;gpt-oss-120b: &lt;strong&gt;$0.2625&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;gpt-oss-20b: &lt;strong&gt;$0.1275&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Llama 3.3 70B: &lt;strong&gt;$0.72&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Self-hosted: per GPU-hour
&lt;/h3&gt;

&lt;p&gt;On-demand Linux prices in US East:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;g6e.xlarge&lt;/code&gt;&lt;/strong&gt; (1× NVIDIA L40S, 48 GB): $1.861 per hour, about $1,359 a month.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;p5.4xlarge&lt;/code&gt;&lt;/strong&gt; (1× NVIDIA H100, 80 GB): $6.88 per hour, about $5,022 a month.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;g6e.12xlarge&lt;/code&gt;&lt;/strong&gt; (4× L40S, 192 GB total): $10.49 per hour, about $7,660 a month.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which instance fits which model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;gpt-oss-20b&lt;/strong&gt; fits on one L40S (&lt;code&gt;g6e.xlarge&lt;/code&gt;). OpenAI says it runs within 16 GB of memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gpt-oss-120b&lt;/strong&gt; fits on one 80 GB GPU, per OpenAI, so one H100 (&lt;code&gt;p5.4xlarge&lt;/code&gt;) works. Four L40S GPUs (&lt;code&gt;g6e.12xlarge&lt;/code&gt;) also fit it, at a higher hourly price.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Llama 3.3 70B&lt;/strong&gt; needs about 140 GB for its weights at 16-bit precision, so it needs &lt;code&gt;g6e.12xlarge&lt;/code&gt; or larger.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Where is the break-even point?
&lt;/h2&gt;

&lt;p&gt;Divide the monthly instance cost by Bedrock's blended price. The result is how many tokens the instance has to process each month to cost the same as Bedrock. Divide by the seconds in a month to get the tokens per second it has to sustain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;HOURS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;730&lt;/span&gt;  &lt;span class="c1"&gt;# hours in an average month
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;break_even&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance_per_hour&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bedrock_in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bedrock_out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ratio&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Prices: instance in USD/hour, Bedrock in USD per million tokens.
    ratio = input tokens per output token.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;blended&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;bedrock_in&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;bedrock_out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;monthly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;instance_per_hour&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;HOURS&lt;/span&gt;
    &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;monthly&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;blended&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1_000_000&lt;/span&gt;
    &lt;span class="n"&gt;per_second&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HOURS&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;monthly&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;1e9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;per_second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;break_even&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;6.88&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.60&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;      &lt;span class="c1"&gt;# gpt-oss-120b on p5.4xlarge:   (5022, 19.1, 7280)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;break_even&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.861&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.07&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.30&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;     &lt;span class="c1"&gt;# gpt-oss-20b on g6e.xlarge:    (1359, 10.7, 4054)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;break_even&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;10.49264&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.72&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# Llama 3.3 70B on g6e.12xlarge: (7660, 10.6, 4048)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each instance has to sustain this load 24 hours a day to match Bedrock:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;gpt-oss-120b on one H100:&lt;/strong&gt; 19.1 billion tokens a month, about &lt;strong&gt;7,300 tokens per second&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gpt-oss-20b on one L40S:&lt;/strong&gt; 10.7 billion tokens a month, about &lt;strong&gt;4,100 tokens per second&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Llama 3.3 70B on four L40S:&lt;/strong&gt; 10.6 billion tokens a month, about &lt;strong&gt;4,000 tokens per second&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two adjustments make the bar higher:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real traffic isn't flat.&lt;/strong&gt; If your GPU is busy 40% of the time on average, it needs to handle 2.5 times the break-even rate at peak. For gpt-oss-120b, that is about 18,000 tokens per second.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If your workload can wait, compare against Batch or Flex.&lt;/strong&gt; Both are half price, which doubles every break-even number above.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether one GPU can hit these rates depends on your prompts, context length, batch size, and serving engine. Measure it. The config at the end of this post sets up that test.&lt;/p&gt;




&lt;h2&gt;
  
  
  Worked example: the support agent from the readiness checklist
&lt;/h2&gt;

&lt;p&gt;This example is hypothetical. The support agent from my &lt;a href="https://medium.com/@anikievev/migrating-ai-agents-to-aws-15-bedrock-and-agentcore-checks-482b7c664962" rel="noopener noreferrer"&gt;AI agents readiness checklist&lt;/a&gt; handles 10,000 tasks a month, with 6 model calls per task, 8,000 input tokens and 1,000 output tokens per call:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input: 480 million tokens a month.&lt;/li&gt;
&lt;li&gt;Output: 60 million tokens a month.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On Bedrock:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;gpt-oss-120b:&lt;/strong&gt; 480 × $0.15 + 60 × $0.60 = &lt;strong&gt;$108 a month&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gpt-oss-20b:&lt;/strong&gt; 480 × $0.07 + 60 × $0.30 = &lt;strong&gt;$51.60 a month&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Self-hosting the same agent on one &lt;code&gt;p5.4xlarge&lt;/code&gt; costs &lt;strong&gt;$5,022 a month&lt;/strong&gt;, about 46 times more. Its 540 million tokens are under 3% of the 19.1 billion the H100 needs to break even, so the agent would need about 35 times its current volume before that GPU paid for itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  What costs does the per-hour price leave out?
&lt;/h2&gt;

&lt;p&gt;Add these to the GPU-hour:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The EKS control plane:&lt;/strong&gt; $0.10 per hour, $73 a month per cluster, if you don't already run one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model downloads.&lt;/strong&gt; gpt-oss-120b weights are tens of gigabytes. Every new node pulls them. If that goes through a NAT gateway from S3 or the internet, you pay NAT processing on every pull. An S3 gateway endpoint makes the S3 part free; see &lt;a href="https://medium.com/@anikievev/cut-aws-nat-gateway-costs-7-fixes-for-platform-teams-5057570fc82d" rel="noopener noreferrer"&gt;Cut AWS NAT Gateway Costs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cold starts.&lt;/strong&gt; Scaling GPU nodes to zero saves money but means minutes of waiting for a node, an image, and the weights before the first answer. Keeping one node warm puts you back on the 24-hour cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quotas.&lt;/strong&gt; EC2 limits GPU instances through vCPU quotas for G and P instances. Check them before you plan on &lt;code&gt;p5&lt;/code&gt; instances, since an increase request can take days.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;People.&lt;/strong&gt; Someone owns the serving engine upgrades, GPU drivers, autoscaling, and on-call. Bedrock includes that in the token price.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Savings Plans and EC2 Capacity Blocks lower the hourly price for steady GPU use, which moves the break-even point down. Price them for your term and Region before deciding.&lt;/p&gt;




&lt;h2&gt;
  
  
  When does self-hosting on EKS make sense?
&lt;/h2&gt;

&lt;p&gt;Self-host when at least one of these is true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Steady, high volume.&lt;/strong&gt; Your measured traffic stays above the break-even rate for most of the day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A model Bedrock doesn't have.&lt;/strong&gt; A fine-tuned or niche open-weight model that isn't on Bedrock and can't be imported.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control over the serving stack.&lt;/strong&gt; You need a specific engine, quantization, or batching setup that a managed API doesn't expose.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay on Bedrock when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Traffic is spiky or still growing.&lt;/strong&gt; Paying per token means idle hours cost nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You switch models often.&lt;/strong&gt; Bedrock lets you change the model ID instead of resizing GPU node pools.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nobody on the team wants GPU on-call.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A practical path is to prototype on Bedrock, measure real token volume for a month, then run the break-even function above with real numbers.&lt;/p&gt;




&lt;h2&gt;
  
  
  How do I test self-hosting on EKS?
&lt;/h2&gt;

&lt;p&gt;Two pieces: a Karpenter NodePool that launches GPU nodes only when a GPU pod is waiting, and a vLLM Deployment that serves the model with an OpenAI-compatible API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;karpenter.sh/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NodePool&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpu-inference&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;nodeClassRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;karpenter.k8s.aws&lt;/span&gt;
        &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;EC2NodeClass&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
      &lt;span class="na"&gt;requirements&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;karpenter.k8s.aws/instance-family&lt;/span&gt;
          &lt;span class="na"&gt;operator&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;In&lt;/span&gt;
          &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;g6e"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;karpenter.sh/capacity-type&lt;/span&gt;
          &lt;span class="na"&gt;operator&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;In&lt;/span&gt;
          &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;on-demand"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;taints&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nvidia.com/gpu&lt;/span&gt;
          &lt;span class="na"&gt;effect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NoSchedule&lt;/span&gt;
  &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;nvidia.com/gpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
  &lt;span class="na"&gt;disruption&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;consolidationPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;WhenEmpty&lt;/span&gt;
    &lt;span class="na"&gt;consolidateAfter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The taint keeps other pods off GPU nodes. &lt;code&gt;WhenEmpty&lt;/code&gt; removes a GPU node 10 minutes after its last pod leaves, so a test cluster doesn't bill GPU hours overnight. The &lt;code&gt;limits&lt;/code&gt; block caps the pool at four GPUs, which stops a runaway Deployment from launching more.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-oss-20b&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-oss-20b&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-oss-20b&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;tolerations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nvidia.com/gpu&lt;/span&gt;
          &lt;span class="na"&gt;operator&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Exists&lt;/span&gt;
          &lt;span class="na"&gt;effect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NoSchedule&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vllm&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vllm/vllm-openai:latest&lt;/span&gt;
          &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--model"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;openai/gpt-oss-20b"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8000&lt;/span&gt;
          &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;nvidia.com/gpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pin the vLLM image to a specific version once your test works. Then replay a day of real prompts against both endpoints, measure sustained tokens per second at your latency target, and put that number next to the break-even rate.&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is Amazon Bedrock cheaper than running an LLM on EC2?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unless the GPU stays busy around the clock, yes. Bedrock charges only for tokens processed, while an EC2 GPU instance charges every hour it runs. A single H100 serving gpt-oss-120b has to sustain about 7,300 tokens per second, 24 hours a day, to match Bedrock's on-demand price for that model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does it cost to run gpt-oss-120b on AWS?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On Bedrock, $0.15 per million input tokens and $0.60 per million output tokens on demand in US East, or half that with Batch or Flex. Self-hosted on one &lt;code&gt;p5.4xlarge&lt;/code&gt; (one H100), $6.88 per hour, about $5,022 a month on demand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What EC2 instance do I need for gpt-oss-20b?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One GPU with at least 16 GB of memory. A &lt;code&gt;g6e.xlarge&lt;/code&gt; with one NVIDIA L40S (48 GB) costs $1.861 per hour on demand in US East and leaves room for long contexts and batching.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I scale GPU nodes to zero on EKS?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Karpenter removes empty nodes based on the NodePool's disruption policy and launches new ones when a GPU pod is pending. The trade-off is cold start time, since a new node has to boot, pull the container image, and load the model weights before serving.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is SageMaker cheaper than EKS for self-hosting an LLM?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The break-even logic is the same. A SageMaker real-time endpoint also bills per instance-hour while it runs, so it has to stay as busy as an EKS GPU node to beat Bedrock's per-token price. Compare the instance-hour prices for your Region, then run the same calculation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Bedrock have a cheaper option for steady high volume?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Bedrock's Reserved service tier commits to a fixed tokens-per-minute capacity, with a minimum of 100,000 input and 10,000 output tokens per minute, arranged through your AWS account team. If your volume is close to the self-hosting break-even point, get a Reserved quote before buying GPUs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Bedrock offer the same open-weight models I can self-host?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some of them. gpt-oss-120b, gpt-oss-20b, and Llama 3.3 70B are available on Bedrock as serverless models. For a model Bedrock doesn't list, check Bedrock Custom Model Import before deciding to self-host.&lt;/p&gt;




&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/migrating-ai-agents-to-aws-15-bedrock-and-agentcore-checks-482b7c664962" rel="noopener noreferrer"&gt;Migrating AI Agents to AWS: 15 Bedrock and AgentCore Checks&lt;/a&gt;: a readiness score for AI teams moving agents to Bedrock and AgentCore.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/cut-aws-nat-gateway-costs-7-fixes-for-platform-teams-5057570fc82d" rel="noopener noreferrer"&gt;Cut AWS NAT Gateway Costs: 7 Fixes for Platform Teams&lt;/a&gt;: model weights pulled through a NAT gateway pay processing fees on every node launch.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/eks-1-37-upgrade-checklist-what-breaks-and-how-to-test-it-1a08b9f2fe05" rel="noopener noreferrer"&gt;EKS 1.37 Upgrade Checklist: What Breaks and How to Test It&lt;/a&gt;: for clusters that will host GPU workloads.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/bedrock/pricing/" rel="noopener noreferrer"&gt;Amazon Bedrock pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/ec2/pricing/on-demand/" rel="noopener noreferrer"&gt;Amazon EC2 On-Demand pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/ec2/instance-types/g6e/" rel="noopener noreferrer"&gt;Amazon EC2 G6e instances&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/ec2/instance-types/p5/" rel="noopener noreferrer"&gt;Amazon EC2 P5 instances&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openai.com/index/introducing-gpt-oss/" rel="noopener noreferrer"&gt;Introducing gpt-oss (OpenAI)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://karpenter.sh/docs/concepts/nodepools/" rel="noopener noreferrer"&gt;Karpenter NodePools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html" rel="noopener noreferrer"&gt;vLLM OpenAI-compatible server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/eks/pricing/" rel="noopener noreferrer"&gt;Amazon EKS pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/service-tiers-inference.html" rel="noopener noreferrer"&gt;Service tiers for Amazon Bedrock inference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Deciding between Bedrock and your own GPUs? I run cost reviews and build EKS platforms for AI teams at &lt;a href="https://devopscloudconsult.com/" rel="noopener noreferrer"&gt;DevOps Cloud Consult&lt;/a&gt;. Bring a month of token counts and I'll run the break-even for your workload.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Get one AWS cost fix every two weeks: &lt;a href="https://evgenyanikiev.substack.com/" rel="noopener noreferrer"&gt;subscribe on Substack&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>kubernetes</category>
      <category>llm</category>
      <category>finops</category>
    </item>
    <item>
      <title>EKS 1.37 Upgrade Checklist: What Breaks and How to Test It</title>
      <dc:creator>Evgeny Anikiev</dc:creator>
      <pubDate>Thu, 22 Oct 2026 14:11:39 +0000</pubDate>
      <link>https://dev.to/evgeny_anikiev/eks-137-upgrade-checklist-what-breaks-and-how-to-test-it-2b1b</link>
      <guid>https://dev.to/evgeny_anikiev/eks-137-upgrade-checklist-what-breaks-and-how-to-test-it-2b1b</guid>
      <description>&lt;p&gt;&lt;strong&gt;Seven changes that break Amazon EKS clusters going from 1.36 to 1.37, with a test command for each.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Evgeny Anikiev, AWS-certified DevOps engineer with 10+ years running build automation, CI/CD, and Kubernetes in production. Last verified: October 22, 2026, against the Amazon EKS 1.37 documentation.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Amazon EKS has supported Kubernetes 1.37 since October 2, 2026. Most of the release is additive, but seven changes can break running workloads. Test each one with the command in its section, rehearse on a staging cluster, then upgrade the control plane, add-ons, and nodes in that order.&lt;/p&gt;

&lt;p&gt;The seven changes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SELinux mount labeling is on by default.&lt;/li&gt;
&lt;li&gt;Static pods can no longer reference Secrets or ConfigMaps.&lt;/li&gt;
&lt;li&gt;The kubelet refuses to start with deprecated cAdvisor flags.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eventRecordQPS: 0&lt;/code&gt; now means "no limit".&lt;/li&gt;
&lt;li&gt;EKS Auto Mode defaults new NodePools to &lt;code&gt;Balanced&lt;/code&gt; consolidation.&lt;/li&gt;
&lt;li&gt;HPA scale-to-zero is enabled by default.&lt;/li&gt;
&lt;li&gt;kube-proxy IPVS mode is deprecated.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What is new in Kubernetes 1.37 on EKS?
&lt;/h2&gt;

&lt;p&gt;Kubernetes v1.37 ("Garhwal") shipped upstream on August 26, 2026, with 67 enhancements: 16 graduated to Stable, 23 to Beta, 27 new Alpha features, and 1 deprecation/removal. Amazon EKS and EKS Distro followed on October 2, 2026, in all commercial and GovCloud (US) regions.&lt;/p&gt;

&lt;p&gt;Headline items for EKS users:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Metrics API GA:&lt;/strong&gt; &lt;code&gt;metrics.k8s.io/v1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DRA device taints and tolerations GA.&lt;/strong&gt; EKS does not install a DRA driver for you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HPA configurable tolerance GA:&lt;/strong&gt; per-HPA tolerance for scale-up and scale-down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HPA scale-to-zero Beta, enabled by default&lt;/strong&gt; (&lt;code&gt;HPAScaleToZero&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pod Certificates and ClusterTrustBundles GA.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;StatefulSet &lt;code&gt;maxUnavailable&lt;/code&gt; re-enabled by default&lt;/strong&gt; after a bug held it back in 1.36.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of those break you on their own. The list below is where upgrades actually fail.&lt;/p&gt;




&lt;h2&gt;
  
  
  The EKS 1.37 breaking-change checklist
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. SELinux mount labeling is on by default (&lt;code&gt;SELinuxMount&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What changed:&lt;/strong&gt; When a Pod sets &lt;code&gt;seLinuxOptions&lt;/code&gt; and its CSI driver advertises &lt;code&gt;seLinuxMount: true&lt;/code&gt;, the kubelet now mounts the volume with &lt;code&gt;-o context=&amp;lt;label&amp;gt;&lt;/code&gt; instead of recursively relabeling every file. It is faster, but if two Pods share a volume with &lt;em&gt;different&lt;/em&gt; SELinux labels, change policies, or privilege levels, one of them can sit in &lt;code&gt;ContainerCreating&lt;/code&gt; indefinitely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who is affected:&lt;/strong&gt; Mostly Bottlerocket nodes (SELinux enforcing) and anyone setting &lt;code&gt;seLinuxOptions&lt;/code&gt; explicitly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to test:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Which CSI drivers opt into SELinux mount labeling?&lt;/span&gt;
kubectl get csidriver &lt;span class="nt"&gt;-o&lt;/span&gt; custom-columns&lt;span class="o"&gt;=&lt;/span&gt;NAME:.metadata.name,SELINUXMOUNT:.spec.seLinuxMount

&lt;span class="c"&gt;# Which Pods set SELinux options?&lt;/span&gt;
kubectl get pods &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; json | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'
  .items[] | select(.spec.securityContext.seLinuxOptions != null
    or any(.spec.containers[]; .securityContext.seLinuxOptions != null))
  | "\(.metadata.namespace)/\(.metadata.name)"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; For workloads that share volumes across differently labeled Pods, opt out per Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;securityContext&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;seLinuxChangePolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Recursive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Static pods can no longer reference Secrets or ConfigMaps
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What changed:&lt;/strong&gt; Static pods referencing API objects (&lt;code&gt;secretRef&lt;/code&gt;, &lt;code&gt;configMapRef&lt;/code&gt;, and similar) are now strictly prohibited, and the &lt;code&gt;PreventStaticPodAPIReferences&lt;/code&gt; feature gate that let you opt out has been &lt;strong&gt;removed&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who is affected:&lt;/strong&gt; Self-managed node groups with custom static pod manifests in &lt;code&gt;/etc/kubernetes/manifests&lt;/code&gt; (log shippers, security agents, node-local proxies). Managed node groups and Auto Mode rarely use static pods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to test:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# On a node (SSM session), look for API references in static pod manifests&lt;/span&gt;
&lt;span class="nb"&gt;sudo grep&lt;/span&gt; &lt;span class="nt"&gt;-rnE&lt;/span&gt; &lt;span class="s1"&gt;'secretRef|configMapRef|secretKeyRef|configMapKeyRef|projected'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /etc/kubernetes/manifests/ 2&amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Convert those static pods to DaemonSets, or render the values into files on the host at bootstrap time.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Kubelet refuses to start with deprecated cAdvisor flags
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What changed:&lt;/strong&gt; The kubelet no longer starts if a deprecated cAdvisor flag is set (except &lt;code&gt;--housekeeping-interval&lt;/code&gt;). It also drops three metrics: &lt;code&gt;container_cpu_load_average_10s&lt;/code&gt;, &lt;code&gt;container_cpu_load_d_average_10s&lt;/code&gt;, and &lt;code&gt;container_tasks_state&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who is affected:&lt;/strong&gt; Custom AMIs, custom launch templates with &lt;code&gt;--kubelet-extra-args&lt;/code&gt;, or Karpenter &lt;code&gt;kubelet&lt;/code&gt; blocks that inherited old flags. EKS-optimized AMIs do not set them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to test:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Inspect the live kubelet command line and config on a node&lt;/span&gt;
ps &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; kubelet | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'^--'&lt;/span&gt;

&lt;span class="c"&gt;# Grep dashboards/alerts for the removed metrics&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rnE&lt;/span&gt; &lt;span class="s1"&gt;'container_cpu_load_average_10s|container_cpu_load_d_average_10s|container_tasks_state'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  ./dashboards ./alerts ./prometheus-rules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Remove deprecated flags from user data and launch templates. Rewrite dashboards and alerts that use the dropped metrics.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;code&gt;eventRecordQPS: 0&lt;/code&gt; now means "no limit"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What changed:&lt;/strong&gt; Before 1.37, &lt;code&gt;eventRecordQPS: 0&lt;/code&gt; meant the default of 5 events/second. Now it means unlimited, so a noisy CrashLoopBackOff node can flood the API server with events.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to test:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get &lt;span class="nt"&gt;--raw&lt;/span&gt; &lt;span class="s2"&gt;"/api/v1/nodes/&amp;lt;node-name&amp;gt;/proxy/configz"&lt;/span&gt; | jq &lt;span class="s1"&gt;'.kubeletconfig.eventRecordQPS'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; If you set &lt;code&gt;0&lt;/code&gt; explicitly, change it to &lt;code&gt;5&lt;/code&gt; to keep the old behavior. EKS-optimized AMIs do not set this field.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. EKS Auto Mode: default consolidation policy is now &lt;code&gt;Balanced&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What changed:&lt;/strong&gt; New Auto Mode NodePools that don't set &lt;code&gt;consolidationPolicy&lt;/code&gt; default to &lt;code&gt;Balanced&lt;/code&gt; instead of &lt;code&gt;WhenEmptyOrUnderutilized&lt;/code&gt;. The built-in &lt;code&gt;general-purpose&lt;/code&gt; and &lt;code&gt;system&lt;/code&gt; NodePools also use &lt;code&gt;Balanced&lt;/code&gt;, and you cannot change that on them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it matters:&lt;/strong&gt; Bin-packing behavior and node churn change. Cost dashboards may move; PodDisruptionBudget pressure patterns change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to test:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodepools &lt;span class="nt"&gt;-o&lt;/span&gt; custom-columns&lt;span class="o"&gt;=&lt;/span&gt;NAME:.metadata.name,POLICY:.spec.disruption.consolidationPolicy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Any row showing &lt;code&gt;&amp;lt;none&amp;gt;&lt;/code&gt; will pick up the new default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Pin the old behavior explicitly on your own NodePools and target them from workloads that need it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;disruption&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;consolidationPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;WhenEmptyOrUnderutilized&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. HPA scale-to-zero is enabled by default
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What changed:&lt;/strong&gt; &lt;code&gt;HPAScaleToZero&lt;/code&gt; is Beta and on by default. An HPA with &lt;code&gt;minReplicas: 0&lt;/code&gt; on Object or External metrics can now drive a Deployment to zero replicas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who is affected:&lt;/strong&gt; Teams that templated &lt;code&gt;minReplicas: 0&lt;/code&gt; by accident (Helm defaults, copy-paste) where it was previously rejected or ignored. EKS does not install a metrics adapter, so this only applies if you run one (KEDA, Prometheus Adapter, CloudWatch adapter).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to test:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get hpa &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; json | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'
  .items[] | select(.spec.minReplicas == 0)
  | "\(.metadata.namespace)/\(.metadata.name)"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Set &lt;code&gt;minReplicas: 1&lt;/code&gt; anywhere zero is not intentional.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. kube-proxy IPVS mode is deprecated
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What changed:&lt;/strong&gt; kube-proxy in &lt;code&gt;ipvs&lt;/code&gt; mode now logs a deprecation warning on startup. Upstream plans to disable it by default around v1.40 and remove it around v1.43. Nothing breaks in 1.37, but this is the release to plan your move to &lt;code&gt;nftables&lt;/code&gt; (or &lt;code&gt;iptables&lt;/code&gt;), which now talks to the kernel through netlink instead of the &lt;code&gt;nft&lt;/code&gt; CLI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to test:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; kube-system get cm kube-proxy-config &lt;span class="nt"&gt;-o&lt;/span&gt; yaml | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; mode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Also on the radar
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;cgroup v1:&lt;/strong&gt; &lt;code&gt;failCgroupV1&lt;/code&gt; has defaulted to &lt;code&gt;true&lt;/code&gt; since 1.35. The temporary override still works in 1.37, but removal is coming. Move any remaining cgroup v1 nodes (old AL2 custom AMIs) to AL2023 or Bottlerocket.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;kube-dns:&lt;/strong&gt; No new packages expected after v1.40. EKS uses CoreDNS by default, so check that you are not running a legacy kube-dns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;kubectl run -f&lt;/code&gt;:&lt;/strong&gt; The &lt;code&gt;--filename/-f&lt;/code&gt; flag is deprecated. Fix scripts that use it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kubelet logs its full effective config at startup.&lt;/strong&gt; Useful for verifying the items above, but check that your log pipeline does not alert on it.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How to test an EKS 1.37 upgrade safely
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Run EKS Upgrade Insights
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws eks list-insights &lt;span class="nt"&gt;--cluster-name&lt;/span&gt; my-cluster &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="s1"&gt;'{"categories":["UPGRADE_READINESS"]}'&lt;/span&gt;

aws eks describe-insight &lt;span class="nt"&gt;--cluster-name&lt;/span&gt; my-cluster &lt;span class="nt"&gt;--id&lt;/span&gt; &amp;lt;insight-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Insights flag deprecated API usage seen in audit logs and add-on/version-skew problems. Treat any &lt;code&gt;ERROR&lt;/code&gt; as a blocker.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Scan manifests for deprecated APIs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Live cluster&lt;/span&gt;
kubent

&lt;span class="c"&gt;# Helm charts and GitOps repos&lt;/span&gt;
pluto detect-files &lt;span class="nt"&gt;-d&lt;/span&gt; ./k8s &lt;span class="nt"&gt;--target-versions&lt;/span&gt; &lt;span class="nv"&gt;k8s&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v1.37.0
pluto detect-helm &lt;span class="nt"&gt;-o&lt;/span&gt; wide &lt;span class="nt"&gt;--target-versions&lt;/span&gt; &lt;span class="nv"&gt;k8s&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v1.37.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Check add-on compatibility
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws eks describe-addon-versions &lt;span class="nt"&gt;--kubernetes-version&lt;/span&gt; 1.37 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'addons[].{name:addonName,default:addonVersions[?compatibilities[?defaultVersion==`true`]]|[0].addonVersion}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also check self-managed controllers: AWS Load Balancer Controller, Karpenter, cert-manager, external-dns, Istio/Cilium, the EBS/EFS CSI drivers, and your service mesh. Each publishes a supported-Kubernetes matrix; confirm 1.37 is on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Rehearse on a staging clone
&lt;/h3&gt;

&lt;p&gt;Create a staging cluster from the same IaC at 1.36, deploy production manifests, then upgrade it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;eksctl upgrade cluster &lt;span class="nt"&gt;--name&lt;/span&gt; staging &lt;span class="nt"&gt;--version&lt;/span&gt; 1.37 &lt;span class="nt"&gt;--approve&lt;/span&gt;
&lt;span class="c"&gt;# or Terraform: bump cluster_version = "1.37" and apply&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run the seven checks above, your smoke tests, and a synthetic load test. Watch for Pods stuck in &lt;code&gt;ContainerCreating&lt;/code&gt; (SELinux), nodes failing to join (kubelet flags), and event volume spikes (&lt;code&gt;eventRecordQPS&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Upgrade production in the right order
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Control plane:&lt;/strong&gt; one minor version at a time (1.36 → 1.37 only).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EKS add-ons:&lt;/strong&gt; VPC CNI, CoreDNS, kube-proxy, EBS CSI, Pod Identity Agent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data plane:&lt;/strong&gt; managed node groups (rolling), Karpenter (drift), or Auto Mode (automatic).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Self-managed controllers.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 6: Post-upgrade verification
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes &lt;span class="nt"&gt;-o&lt;/span&gt; wide                        &lt;span class="c"&gt;# all nodes Ready on v1.37&lt;/span&gt;
kubectl get pods &lt;span class="nt"&gt;-A&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-vE&lt;/span&gt; &lt;span class="s1"&gt;'Running|Completed'&lt;/span&gt;
kubectl get events &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.lastTimestamp | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt;
kubectl get apiservices | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; True          &lt;span class="c"&gt;# unhealthy aggregated APIs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  EKS 1.37 upgrade checklist (copy-paste)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] EKS Upgrade Insights: zero &lt;code&gt;ERROR&lt;/code&gt; findings&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;kubent&lt;/code&gt; / &lt;code&gt;pluto&lt;/code&gt; clean against v1.37&lt;/li&gt;
&lt;li&gt;[ ] All EKS add-ons on a 1.37-compatible version&lt;/li&gt;
&lt;li&gt;[ ] Third-party controllers confirm 1.37 support&lt;/li&gt;
&lt;li&gt;[ ] SELinux: CSI drivers and &lt;code&gt;seLinuxOptions&lt;/code&gt; Pods audited; &lt;code&gt;seLinuxChangePolicy: Recursive&lt;/code&gt; where needed&lt;/li&gt;
&lt;li&gt;[ ] Static pods: no Secret/ConfigMap references&lt;/li&gt;
&lt;li&gt;[ ] Kubelet: no deprecated cAdvisor flags; dashboards don't use dropped metrics&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;eventRecordQPS: 0&lt;/code&gt; replaced with &lt;code&gt;5&lt;/code&gt; where set&lt;/li&gt;
&lt;li&gt;[ ] Auto Mode NodePools: &lt;code&gt;consolidationPolicy&lt;/code&gt; set explicitly&lt;/li&gt;
&lt;li&gt;[ ] HPAs: no accidental &lt;code&gt;minReplicas: 0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] kube-proxy: IPVS migration plan logged&lt;/li&gt;
&lt;li&gt;[ ] No cgroup v1 nodes left&lt;/li&gt;
&lt;li&gt;[ ] Staging upgrade rehearsed, smoke + load tests passed&lt;/li&gt;
&lt;li&gt;[ ] Rollback plan: blue/green node groups ready (control plane cannot be downgraded)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When did Amazon EKS release Kubernetes 1.37?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;EKS and EKS Distro added Kubernetes 1.37 on October 2, 2026, about five weeks after the upstream release on August 26, 2026.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I downgrade an EKS cluster from 1.37 to 1.36?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. EKS control plane upgrades are one-way. Your rollback options are at the node level (keep a 1.36 node group until 1.37 nodes are proven) or a blue/green cluster migration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I skip from EKS 1.35 straight to 1.37?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. The control plane upgrades one minor version at a time: 1.35 → 1.36 → 1.37. Nodes may lag the control plane within the supported skew, but plan for both hops.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the biggest risk when upgrading to EKS 1.37?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For most clusters it is SELinux mount labeling on Bottlerocket nodes, followed by custom kubelet configuration (deprecated cAdvisor flags and &lt;code&gt;eventRecordQPS: 0&lt;/code&gt;). Auto Mode users should check the &lt;code&gt;Balanced&lt;/code&gt; consolidation default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does EKS 1.37 remove any APIs?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The upstream release lists one deprecation/removal. The practical removals are behavioral: the &lt;code&gt;PreventStaticPodAPIReferences&lt;/code&gt; gate is gone and deprecated kubelet cAdvisor flags now stop the kubelet from starting. Still run &lt;code&gt;kubent&lt;/code&gt; or &lt;code&gt;pluto&lt;/code&gt; to catch older deprecated APIs you never migrated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long is EKS 1.37 supported?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;EKS gives each version 14 months of standard support followed by 12 months of extended support. Check the official &lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html" rel="noopener noreferrer"&gt;EKS Kubernetes version lifecycle page&lt;/a&gt; for exact dates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/cut-aws-nat-gateway-costs-7-fixes-for-platform-teams-5057570fc82d" rel="noopener noreferrer"&gt;Cut AWS NAT Gateway Costs: 7 Fixes for Platform Teams&lt;/a&gt;: EKS nodes in private subnets send image pulls, logs, and API calls through NAT gateways. Here is how to cut that bill.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/migrating-ai-agents-to-aws-15-bedrock-and-agentcore-checks-482b7c664962" rel="noopener noreferrer"&gt;Migrating AI Agents to AWS: 15 Bedrock and AgentCore Checks&lt;/a&gt;: a readiness score for AI teams moving agents to Amazon Bedrock and AgentCore.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/blog/2026/08/26/kubernetes-v1-37-release/" rel="noopener noreferrer"&gt;Kubernetes v1.37: Garhwal (official release blog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions-standard.html" rel="noopener noreferrer"&gt;Amazon EKS: Kubernetes versions on standard support (1.37 section)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/10/amazon-eks-distro-kubernetes-version-1-37/" rel="noopener noreferrer"&gt;AWS What's New: Amazon EKS and EKS Distro now support Kubernetes 1.37&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Planning an EKS upgrade and want a second pair of eyes? I help teams run zero-downtime Kubernetes upgrades on AWS at &lt;a href="https://devopscloudconsult.com/" rel="noopener noreferrer"&gt;DevOps Cloud Consult&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>aws</category>
      <category>devops</category>
      <category>sre</category>
    </item>
    <item>
      <title>Cut AWS NAT Gateway Costs: 7 Fixes for Platform Teams</title>
      <dc:creator>Evgeny Anikiev</dc:creator>
      <pubDate>Thu, 22 Oct 2026 14:10:21 +0000</pubDate>
      <link>https://dev.to/evgeny_anikiev/cut-aws-nat-gateway-costs-7-fixes-for-platform-teams-4m9k</link>
      <guid>https://dev.to/evgeny_anikiev/cut-aws-nat-gateway-costs-7-fixes-for-platform-teams-4m9k</guid>
      <description>&lt;p&gt;&lt;strong&gt;Find what flows through your NAT gateways, then move it to free or cheaper paths. Prices, break-even math, and a command for each fix.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Evgeny Anikiev, AWS-certified DevOps engineer with 10+ years running build automation, CI/CD, and Kubernetes in production. Prices verified October 22, 2026, against AWS public pricing pages (US East list prices; check your Region).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; A NAT gateway charges $0.045 per hour per AZ plus $0.045 for every GB it processes, including traffic to S3, ECR, and other AWS services. Most of that traffic doesn't need a NAT at all. Measure what flows through it first, then move AWS-bound traffic to VPC endpoints and keep the rest in the same AZ.&lt;/p&gt;

&lt;p&gt;The seven fixes, roughly in order of savings:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add free S3 and DynamoDB gateway endpoints.&lt;/li&gt;
&lt;li&gt;Add interface endpoints for high-volume AWS APIs (ECR, CloudWatch Logs, STS).&lt;/li&gt;
&lt;li&gt;Stop sending traffic across AZs to reach a NAT gateway.&lt;/li&gt;
&lt;li&gt;Keep Kubernetes service traffic in-zone.&lt;/li&gt;
&lt;li&gt;Send IPv6 egress through an egress-only internet gateway.&lt;/li&gt;
&lt;li&gt;Release idle public IPv4 addresses.&lt;/li&gt;
&lt;li&gt;Show each team its own NAT and data transfer bill.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What is an AWS NAT gateway?
&lt;/h2&gt;

&lt;p&gt;An AWS NAT gateway is a managed service that lets resources in private subnets open connections to the internet and to public AWS service endpoints, while blocking connections coming in from outside. AWS bills it by the hour and by every GB it processes, which is why it shows up on so many networking bills.&lt;/p&gt;

&lt;h2&gt;
  
  
  How much does an AWS NAT gateway cost?
&lt;/h2&gt;

&lt;p&gt;An AWS NAT gateway costs $0.045 per NAT gateway-hour and $0.045 per GB of data processed, at the US East list price AWS uses in its own pricing example. Partial hours bill as full hours, and the per-GB charge applies "regardless of the traffic's source or destination." Internet egress is billed on top.&lt;/p&gt;

&lt;p&gt;The rates that matter for this playbook (US East, list price):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NAT gateway (zonal):&lt;/strong&gt; $0.045 per hour, about $32.85 per month per gateway.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NAT gateway (regional mode):&lt;/strong&gt; $0.045 per hour &lt;em&gt;per AZ it runs in&lt;/em&gt;. Three AZs means three NAT gateway-hours every hour.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NAT data processing:&lt;/strong&gt; $0.045 per GB, both directions, any destination.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internet data transfer out:&lt;/strong&gt; $0.09 per GB in the first tier, after 100 GB free per month across your account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gateway VPC endpoint (S3, DynamoDB):&lt;/strong&gt; no hourly or data processing charge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interface VPC endpoint (PrivateLink):&lt;/strong&gt; $0.01 per hour per AZ, plus $0.01 per GB processed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public IPv4 address:&lt;/strong&gt; $0.005 per hour, in use or idle (about $3.65 per month).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-AZ traffic inside a Region:&lt;/strong&gt; $0.01 per GB, charged on each side of the transfer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The processing fee is where the money goes. A node pulling a 1 GB container image from ECR through a NAT gateway pays $0.045 for that pull. Multiply that by hundreds of nodes scaling up and down every day. That traffic never needed to leave AWS.&lt;/p&gt;




&lt;h2&gt;
  
  
  How do I find what is using my NAT gateway?
&lt;/h2&gt;

&lt;p&gt;Start with two numbers: how much each NAT gateway processes, and where those bytes go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cost Explorer.&lt;/strong&gt; Filter Service = EC2-Other and group by Usage Type. Look for &lt;code&gt;NatGateway-Bytes&lt;/code&gt;, &lt;code&gt;NatGateway-Hours&lt;/code&gt;, and &lt;code&gt;DataTransfer-Regional-Bytes&lt;/code&gt; (cross-AZ).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cost and Usage Report (CUR) in Athena.&lt;/strong&gt; Rank NAT gateways by cost:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;line_item_resource_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;line_item_usage_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_item_unblended_cost&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;line_item_usage_type&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'%NatGateway%'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;line_item_usage_start_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;date_add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'day'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;current_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;VPC Flow Logs on the NAT gateway ENI.&lt;/strong&gt; This tells you &lt;em&gt;where&lt;/em&gt; the bytes go. Enable flow logs on the NAT's network interface, query them in Athena, and rank destinations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;dstaddr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;e9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;gb&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vpc_flow_logs&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;interface_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'eni-0123456789abcdef0'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;day&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2026/10/01'&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;dstaddr&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;gb&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Match the top destination IPs against AWS's published ranges to see which ones are AWS services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://ip-ranges.amazonaws.com/ip-ranges.json &lt;span class="se"&gt;\&lt;/span&gt;
  | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.prefixes[] | select(.region=="us-east-1") | "\(.ip_prefix) \(.service)"'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; aws-ranges.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On container platforms, expect S3 (container image layers, artifacts, logs), ECR, CloudWatch Logs, and STS near the top. All of those can bypass the NAT.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to reduce NAT gateway costs: seven fixes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Add S3 and DynamoDB gateway endpoints (free)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; A gateway endpoint adds a route so traffic to S3 or DynamoDB stays on the AWS network and skips the NAT. AWS charges nothing for it, hourly or per GB.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it matters for containers:&lt;/strong&gt; ECR stores image layers in S3. Without an S3 gateway endpoint, every layer download pays the NAT processing fee.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 create-vpc-endpoint &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--vpc-id&lt;/span&gt; vpc-0123456789abcdef0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--service-name&lt;/span&gt; com.amazonaws.us-east-1.s3 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--vpc-endpoint-type&lt;/span&gt; Gateway &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--route-table-ids&lt;/span&gt; rtb-0aaa rtb-0bbb rtb-0ccc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Attach it to every private route table, then repeat with &lt;code&gt;com.amazonaws.us-east-1.dynamodb&lt;/code&gt; if you use DynamoDB. It costs nothing and needs no application changes, so ship it first.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Add interface endpoints for high-volume AWS APIs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; An interface endpoint (PrivateLink) puts a private IP for an AWS service inside your subnets. Traffic costs $0.01 per GB at the endpoint instead of $0.045 per GB at the NAT.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Break-even:&lt;/strong&gt; Each endpoint costs about $7.30 per AZ per month. You save $0.035 per GB moved off the NAT, so an endpoint pays for itself at roughly &lt;strong&gt;210 GB per month per AZ&lt;/strong&gt;. For a three-AZ VPC, that is about 630 GB per month per service.&lt;/p&gt;

&lt;p&gt;Good candidates for container platforms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ecr.api&lt;/code&gt; and &lt;code&gt;ecr.dkr&lt;/code&gt; (image manifests and auth; layers go through S3)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;logs&lt;/code&gt; (CloudWatch Logs, often the noisiest)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sts&lt;/code&gt; (IRSA and EKS Pod Identity token calls)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sqs&lt;/code&gt;, &lt;code&gt;kinesis-streams&lt;/code&gt;, &lt;code&gt;secretsmanager&lt;/code&gt;, depending on your workload&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use your flow log ranking from the queries above to decide. Don't create endpoints for services that move a few GB a month; they will cost more than they save.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Stop sending traffic across AZs to reach a NAT gateway
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; If private subnets in AZ b and AZ c route to a single NAT gateway in AZ a, every byte pays cross-AZ transfer on top of NAT processing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The math:&lt;/strong&gt; Two extra zonal NAT gateways cost about $65.70 per month. Cross-AZ traffic costs $0.02 per GB counting both sides. Above roughly &lt;strong&gt;3.3 TB per month&lt;/strong&gt; of cross-AZ NAT traffic, one NAT per AZ is cheaper, and it removes a single point of failure too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check your route tables:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 describe-route-tables &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;vpc-id,Values&lt;span class="o"&gt;=&lt;/span&gt;vpc-0123456789abcdef0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'RouteTables[].{rt:RouteTableId,subnets:Associations[].SubnetId,nat:Routes[?NatGatewayId].NatGatewayId}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each private subnet's route table should point at the NAT gateway in the same AZ.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Or use a regional NAT gateway.&lt;/strong&gt; Since November 2025, a NAT gateway can run in regional availability mode: one gateway that expands into each AZ where you have workloads, with no public subnet per AZ and no per-AZ route table edits. It bills per AZ-hour, so it costs the same as one zonal NAT per AZ. AWS's launch post lists two caveats. Expansion into a new AZ takes 15 to 20 minutes on average, and up to 60. Until it finishes, traffic from that AZ goes to another AZ's NAT and pays cross-AZ charges.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Keep Kubernetes service traffic in-zone
&lt;/h3&gt;

&lt;p&gt;Cross-AZ charges don't only come from NAT routing. Service-to-service traffic in EKS crosses AZs all the time because kube-proxy spreads connections across all endpoints by default.&lt;/p&gt;

&lt;p&gt;On Kubernetes 1.33 and later, ask for zone-local routing per Service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;trafficDistribution&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PreferClose&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;PreferClose&lt;/code&gt; sends traffic to endpoints in the client's zone when they exist and falls back to others when they don't. Pair it with topology spread constraints so each zone has replicas to receive the traffic. This traffic never touches the NAT, so it won't show up in your NAT numbers. Size it with the &lt;code&gt;DataTransfer-Regional-Bytes&lt;/code&gt; usage type in Cost Explorer. If you're also planning an upgrade, see my &lt;a href="https://medium.com/@anikievev/eks-1-37-upgrade-checklist-what-breaks-and-how-to-test-it-1a08b9f2fe05" rel="noopener noreferrer"&gt;EKS 1.37 upgrade checklist&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Send IPv6 egress through an egress-only internet gateway
&lt;/h3&gt;

&lt;p&gt;An egress-only internet gateway lets IPv6 workloads reach the internet without a NAT gateway, so there is no NAT hourly or processing charge on that traffic. Standard data transfer out still applies. If your EKS cluster runs in IPv6 mode, or your dependencies (package registries, SaaS APIs) support IPv6, route &lt;code&gt;::/0&lt;/code&gt; to an egress-only internet gateway and keep the NAT for IPv4-only destinations.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Release idle public IPv4 addresses
&lt;/h3&gt;

&lt;p&gt;Every public IPv4 address costs $0.005 per hour whether it is in use or not. Find Elastic IPs that aren't attached to anything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 describe-addresses &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Addresses[?AssociationId==null].[PublicIp,AllocationId,Tags]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;VPC IPAM's Public IP Insights view shows every public IPv4 in the account, including ones attached to load balancers and instances you may have forgotten.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Show each team its own network bill
&lt;/h3&gt;

&lt;p&gt;Platform teams own the VPC, so NAT and data transfer costs usually land in one shared bucket that nobody feels responsible for. Split it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tag&lt;/strong&gt; NAT gateways and endpoints with the owning team or environment and activate those tags as cost allocation tags.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Group flow logs by source subnet&lt;/strong&gt; (or by pod CIDR in EKS) to attribute NAT bytes to the team that generated them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publish a monthly showback&lt;/strong&gt;: GB through NAT per team, top destinations, and which fix from this list would remove it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A monthly report line such as "your service pulled 4 TB of images through the NAT; an S3 gateway endpoint makes that free" gives a team a specific action to take.&lt;/p&gt;




&lt;h2&gt;
  
  
  Worked example: an EKS cluster across three AZs
&lt;/h2&gt;

&lt;p&gt;This is an illustrative model using the list prices above, not a client bill. Assume three zonal NAT gateways process 20 TB (20,480 GB) per month:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;15 TB to S3 (image layers, artifacts)&lt;/li&gt;
&lt;li&gt;2 TB to CloudWatch Logs&lt;/li&gt;
&lt;li&gt;3 TB to the internet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NAT hours: 3 × $0.045 × 730 = $98.55&lt;/li&gt;
&lt;li&gt;NAT processing: 20,480 GB × $0.045 = $921.60&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total NAT cost: about $1,020 per month&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After fixes 1 and 2:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S3 moves to a gateway endpoint: $0&lt;/li&gt;
&lt;li&gt;CloudWatch Logs moves to an interface endpoint: 2,048 GB × $0.01 + 3 AZs × $7.30 = $42.38&lt;/li&gt;
&lt;li&gt;NAT keeps only internet traffic: 3,072 GB × $0.045 + $98.55 = $236.79&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: about $279 per month, a 73% cut&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Internet data transfer out (about $276 at $0.09 per GB) is the same in both cases; endpoints don't change egress pricing. Your traffic mix will differ, so run the flow log queries above to get your own split before estimating savings.&lt;/p&gt;




&lt;h2&gt;
  
  
  NAT gateway cost checklist (copy-paste)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Cost Explorer: &lt;code&gt;NatGateway-Bytes&lt;/code&gt; and &lt;code&gt;DataTransfer-Regional-Bytes&lt;/code&gt; baselined&lt;/li&gt;
&lt;li&gt;[ ] Flow logs enabled on every NAT ENI; top 25 destinations identified&lt;/li&gt;
&lt;li&gt;[ ] S3 gateway endpoint attached to every private route table&lt;/li&gt;
&lt;li&gt;[ ] DynamoDB gateway endpoint attached (if used)&lt;/li&gt;
&lt;li&gt;[ ] Interface endpoints for AWS services above ~210 GB per AZ per month&lt;/li&gt;
&lt;li&gt;[ ] Each private subnet routes to a NAT in its own AZ (or regional NAT in automatic mode)&lt;/li&gt;
&lt;li&gt;[ ] Kubernetes Services with heavy east-west traffic use &lt;code&gt;trafficDistribution: PreferClose&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] IPv6 egress goes through an egress-only internet gateway&lt;/li&gt;
&lt;li&gt;[ ] No unattached Elastic IPs&lt;/li&gt;
&lt;li&gt;[ ] NAT gateways and endpoints tagged; monthly showback per team&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why is my AWS NAT gateway bill so high?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Usually because AWS-bound traffic (S3, ECR image layers, CloudWatch Logs) goes through the NAT and pays $0.045 per GB in processing. Container platforms with frequent node scaling pull large images many times a day. Enable flow logs on the NAT ENI to confirm where the bytes go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does a NAT gateway charge for traffic to S3?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, if there is no S3 gateway endpoint. The NAT processing fee applies to all traffic it handles, regardless of destination. An S3 gateway endpoint is free and removes that traffic from the NAT completely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is a regional NAT gateway cheaper than zonal NAT gateways?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not on price. Regional mode bills $0.045 per hour for each AZ it runs in, the same as one zonal NAT per AZ, and the same per-GB fee. It saves operational work (no public subnet per AZ, no route table edits) and helps avoid cross-AZ routing once it has expanded into every AZ you use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I replace NAT gateways with NAT instances?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For small or non-production environments, a NAT instance on a small Graviton instance (for example with the open-source fck-nat AMI) avoids the per-GB processing fee. You take on patching, scaling, and failover yourself. For production, fix the traffic first with endpoints; the remaining NAT bill is often small enough that the managed gateway is worth it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VPC endpoint vs NAT gateway: which is cheaper for AWS service traffic?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A gateway endpoint (S3, DynamoDB) is always cheaper because it is free. An interface endpoint costs $0.01 per GB plus about $7.30 per AZ per month, against $0.045 per GB through a NAT. It pays for itself above roughly 210 GB per month per AZ for that service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does cross-AZ data transfer cost on AWS?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traffic between Availability Zones in the same Region is billed at $0.01 per GB on each side, so $0.02 per GB in total. It appears as &lt;code&gt;DataTransfer-Regional-Bytes&lt;/code&gt; in Cost Explorer. Same-AZ NAT routing and zone-aware Kubernetes Services reduce it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does a NAT gateway cost per month?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;About $32.85 per month per zonal gateway in hourly charges at US East list price, before data. Add $0.045 for every GB processed. A three-AZ setup starts at about $98.55 per month before any traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/migrating-ai-agents-to-aws-15-bedrock-and-agentcore-checks-482b7c664962" rel="noopener noreferrer"&gt;Migrating AI Agents to AWS: 15 Bedrock and AgentCore Checks&lt;/a&gt;: a readiness score for AI teams moving agents to Amazon Bedrock and AgentCore.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/eks-1-37-upgrade-checklist-what-breaks-and-how-to-test-it-1a08b9f2fe05" rel="noopener noreferrer"&gt;EKS 1.37 Upgrade Checklist: What Breaks and How to Test It&lt;/a&gt;: seven changes that break EKS clusters going from 1.36 to 1.37, with a test command for each.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/vpc/pricing/" rel="noopener noreferrer"&gt;Amazon VPC pricing (NAT gateway, regional NAT, gateway endpoints, public IPv4)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/privatelink/pricing/" rel="noopener noreferrer"&gt;AWS PrivateLink pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/networking-and-content-delivery/introducing-amazon-vpc-regional-nat-gateway/" rel="noopener noreferrer"&gt;Introducing Amazon VPC Regional NAT Gateway (AWS Networking blog, Nov 20, 2025)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/ec2/pricing/on-demand/" rel="noopener noreferrer"&gt;Amazon EC2 On-Demand pricing: data transfer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/containers/understanding-data-transfer-costs-for-aws-container-services/" rel="noopener noreferrer"&gt;Understanding data transfer costs for AWS container services (AWS Containers blog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/aws-ip-ranges.html" rel="noopener noreferrer"&gt;AWS IP address ranges&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Want a second pair of eyes on your AWS network bill? I run NAT and data transfer cost reviews for platform teams at &lt;a href="https://devopscloudconsult.com/" rel="noopener noreferrer"&gt;DevOps Cloud Consult&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>finops</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Migrating AI Agents to AWS: 15 Bedrock and AgentCore Checks</title>
      <dc:creator>Evgeny Anikiev</dc:creator>
      <pubDate>Thu, 22 Oct 2026 14:04:14 +0000</pubDate>
      <link>https://dev.to/evgeny_anikiev/migrating-ai-agents-to-aws-15-bedrock-and-agentcore-checks-44ol</link>
      <guid>https://dev.to/evgeny_anikiev/migrating-ai-agents-to-aws-15-bedrock-and-agentcore-checks-44ol</guid>
      <description>&lt;p&gt;&lt;strong&gt;A readiness assessment for AI teams moving agents from a prototype or another provider to Amazon Bedrock and AgentCore. Score yourself out of 30, with the evidence, AWS service, and command for each check.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Evgeny Anikiev, AWS-certified DevOps engineer with 10+ years running build automation, CI/CD, and Kubernetes in production. AWS service details verified October 22, 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Score 15 checks from 0 to 2. They cover cost per task, evaluations, model access, quotas, AgentCore Runtime, tools, identity, data, observability, and rollback. A total of 24 or more means you can move production traffic. From 15 to 23, fix the zeros and run a shadow or canary pilot. Below 15, keep the agent where it is and build the foundations first.&lt;/p&gt;

&lt;p&gt;Three changes from the past year that older checklists miss:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Amazon Bedrock retired its Model Access page in October 2025. Serverless foundation models are now enabled by default in commercial Regions, so restricting models is your job, done with IAM and service control policies.&lt;/li&gt;
&lt;li&gt;AgentCore Policy became generally available on March 3, 2026. It checks every tool call that passes through AgentCore Gateway against Cedar rules.&lt;/li&gt;
&lt;li&gt;AgentCore Evaluations became generally available on March 31, 2026, with 13 built-in evaluators and online scoring of live traces.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What is an AI migration readiness assessment?
&lt;/h2&gt;

&lt;p&gt;An AI migration readiness assessment is a review, done before production traffic moves, of whether an AI team can run its agents on a new platform safely and within budget. For AWS, that means checking cost per task, evaluation baselines, model governance, Bedrock quotas, AgentCore hosting, tool access, identity, data handling, monitoring, and rollback on Amazon Bedrock and Amazon Bedrock AgentCore.&lt;/p&gt;

&lt;p&gt;It follows the six perspectives of the AWS Cloud Adoption Framework (Business, People, Governance, Platform, Security, Operations), applied to agents instead of servers. Typical starting points are an agent calling the OpenAI or Anthropic API directly, a LangGraph or CrewAI service in a container, or a notebook prototype that leadership now wants in front of customers.&lt;/p&gt;




&lt;h2&gt;
  
  
  How do you score it?
&lt;/h2&gt;

&lt;p&gt;Give each check a score:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;0:&lt;/strong&gt; missing, or exists only in someone's head.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1:&lt;/strong&gt; exists, but is incomplete, untested, or out of date.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2:&lt;/strong&gt; written down, owned by a named person, and tested.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add the scores. The maximum is 30.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;24 to 30, ready:&lt;/strong&gt; move production traffic in stages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;15 to 23, pilot:&lt;/strong&gt; fix every 0, then run the agent in shadow mode or on a small share of traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0 to 14, not ready:&lt;/strong&gt; keep the current setup and build the foundations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One rule overrides the total: a 0 on check 2 (evaluation baseline), check 11 (identity and tool policy), or check 15 (rollback) blocks production at any score. Without a baseline you can't tell whether the move made answers worse. Without tool policy an agent can call anything its credentials allow. Without rollback a bad model or prompt change stays live until someone fixes it by hand.&lt;/p&gt;

&lt;p&gt;A copy-paste scoring sheet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csvs"&gt;&lt;code&gt;&lt;span class="k"&gt;check&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;perspective&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;owner&lt;/span&gt;
&lt;span class="mf"&gt;01&lt;/span&gt; &lt;span class="k"&gt;cost&lt;/span&gt; &lt;span class="k"&gt;per&lt;/span&gt; &lt;span class="k"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;business&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;02&lt;/span&gt; &lt;span class="k"&gt;evaluation&lt;/span&gt; &lt;span class="k"&gt;baseline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;business&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;03&lt;/span&gt; &lt;span class="k"&gt;owners&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;people&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;04&lt;/span&gt; &lt;span class="k"&gt;framework&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="k"&gt;AgentCore&lt;/span&gt; &lt;span class="k"&gt;skills&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;people&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;05&lt;/span&gt; &lt;span class="k"&gt;model&lt;/span&gt; &lt;span class="k"&gt;access&lt;/span&gt; &lt;span class="k"&gt;controls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;governance&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;06&lt;/span&gt; &lt;span class="k"&gt;cost&lt;/span&gt; &lt;span class="k"&gt;attribution&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;governance&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;07&lt;/span&gt; &lt;span class="k"&gt;quotas&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="k"&gt;inference&lt;/span&gt; &lt;span class="k"&gt;routing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;08&lt;/span&gt; &lt;span class="k"&gt;runtime&lt;/span&gt; &lt;span class="k"&gt;hosting&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;09&lt;/span&gt; &lt;span class="k"&gt;tools&lt;/span&gt; &lt;span class="k"&gt;behind&lt;/span&gt; &lt;span class="k"&gt;Gateway&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;10&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="k"&gt;RAG&lt;/span&gt; &lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;11&lt;/span&gt; &lt;span class="k"&gt;identity&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="k"&gt;tool&lt;/span&gt; &lt;span class="k"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;security&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;12&lt;/span&gt; &lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="k"&gt;protection&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="k"&gt;network&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;security&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;13&lt;/span&gt; &lt;span class="k"&gt;observability&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="k"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;operations&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;14&lt;/span&gt; &lt;span class="k"&gt;online&lt;/span&gt; &lt;span class="k"&gt;evaluations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;operations&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;span class="mf"&gt;15&lt;/span&gt; &lt;span class="k"&gt;rollout&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="k"&gt;rollback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;operations&lt;/span&gt;&lt;span class="p"&gt;,,,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Business
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Do you know the cost per task?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Agents bill per token, and one user request often makes several model calls. Measure input and output tokens per task on your current setup, then price them on Bedrock. Score 2 if finance has seen a cost per task and a monthly estimate at expected volume.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cost_per_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;in_tokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out_tokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;in_price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out_price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cached&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cache_discount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Prices are USD per million tokens. cached = input tokens per call served from the prompt cache.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;uncached&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;in_tokens&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;cached&lt;/span&gt;
    &lt;span class="n"&gt;per_call&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uncached&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;in_price&lt;/span&gt;
                &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cached&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;in_price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;cache_discount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;out_tokens&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;out_price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1_000_000&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;per_call&lt;/span&gt;

&lt;span class="c1"&gt;# Example prices, not a quote: $3 input and $15 output per million tokens.
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cost_per_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;               &lt;span class="c1"&gt;# 0.234
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cost_per_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cached&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# 0.137
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The numbers that move this figure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prompt caching:&lt;/strong&gt; AWS says it can cut costs by up to 90% on supported models. Cache-read discounts differ by model, and some models charge extra for cache writes, so test with your real prompts. It works only on on-demand inference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch inference:&lt;/strong&gt; 50% lower than on-demand for select models, for work that can wait.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service tiers:&lt;/strong&gt; Flex costs 50% less than Standard for non-urgent requests. Priority costs 75% more for the fastest responses.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Do you have an evaluation baseline from the current setup?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Build a golden set of real requests with expected answers or grading rules, and score your current agent on it before you change anything. Run the same set on Bedrock after the move. Score 2 if the set has at least a few hundred cases, covers your main task types, and has a pass threshold the product owner agreed to. A 0 here blocks production.&lt;/p&gt;

&lt;h2&gt;
  
  
  People
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;3. Are owners and on-call named?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Someone owns the prompts, someone owns the tools and their APIs, and someone gets paged when the agent fails at 2 a.m. Score 2 if all three are named and the on-call runbook covers model errors, throttling, and tool failures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Can the team build and run on AgentCore?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AgentCore Runtime is framework-agnostic. AWS documents agents built with Strands Agents, LangGraph, and CrewAI running on it, so most teams keep their code. Score 2 if at least two engineers have deployed a test agent to AgentCore Runtime and called it with real credentials.&lt;/p&gt;

&lt;h2&gt;
  
  
  Governance
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;5. Who controls which models can be called?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since October 2025, serverless Bedrock models are enabled by default. Anthropic models still need a one-time use-case form, which covers member accounts when submitted from the management account. Restrict models with a service control policy. Score 2 if an allow-list exists and is enforced at the organization level.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DenyUnapprovedBedrockModels"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Deny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"bedrock:InvokeModel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"bedrock:InvokeModelWithResponseStream"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"NotResource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:bedrock:*::foundation-model/anthropic.*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:bedrock:*::foundation-model/amazon.nova-*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:bedrock:*:*:inference-profile/us.anthropic.*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:bedrock:*:*:inference-profile/us.amazon.nova-*"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the model families with your approved list. The Converse API uses the same &lt;code&gt;bedrock:InvokeModel&lt;/code&gt; permission, so this policy covers it too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Can you split the Bedrock bill by team and agent?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create an application inference profile per agent or team, tag it, and activate the tags as cost allocation tags. Calls made through the profile then show up per tag in Cost Explorer. Score 2 if every production agent calls models through a tagged profile.&lt;/p&gt;

&lt;h2&gt;
  
  
  Platform
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;7. Are quotas and inference routing sized?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bedrock quotas are tokens per minute and requests per minute, set per model and per Region. Cross-Region inference spreads load across Regions in one geography (geo) or worldwide (global), and not every model supports global. Score 2 if you have compared peak tokens per minute against your quotas in Service Quotas, requested increases in advance, and chosen geo or global routing to match your data residency rules. AWS gives priority on increases to accounts that already use their current quota, so build up real traffic before asking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Is the hosting model chosen?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AgentCore Runtime runs each session in its own microVM with separate compute, memory, and filesystem, and wipes it when the session ends. A session ends after 15 minutes of inactivity by default and lives up to 8 hours. For longer jobs, AgentCore Runtime instances run up to 14 days. Score 2 if your longest task fits these limits and you have load-tested cold starts at expected concurrency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Are tools exposed through AgentCore Gateway?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Gateway turns existing APIs and Lambda functions into MCP tools that agents can discover and call. It is also where AgentCore Policy checks each call. Score 2 if every tool the agent can call goes through Gateway, and none are hard-coded HTTP calls inside the agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. Are memory and RAG data planned?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Decide what goes into AgentCore Memory (conversation history and long-term facts per user) and what goes into a Bedrock Knowledge Base (documents for retrieval). For each, write down the data source, refresh schedule, retention period, and who may read it. Score 2 if the retrieval quality on your golden set matches or beats the current setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;11. Are identity and tool policy in place?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use AgentCore Identity for inbound authentication (who may call the agent) and for outbound credentials to tools, so no API keys live in agent code or environment variables. Add AgentCore Policy rules on the Gateway, for example limiting a refund tool to amounts below a threshold. Score 0 if the agent holds long-lived keys or can call tools without a policy check. A 0 here blocks production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12. Are data protection and network paths decided?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AWS states that Bedrock does not use your prompts and completions to train AWS models or share them with model providers. Your security team will still ask about three more things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;private connectivity through AWS PrivateLink endpoints for Bedrock and AgentCore&lt;/li&gt;
&lt;li&gt;Amazon Bedrock Guardrails for content filters and PII redaction&lt;/li&gt;
&lt;li&gt;whether cross-Region inference fits your data residency rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Score 2 if security has signed off on all three in writing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operations
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;13. Can you see what the agent did?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AgentCore Observability records traces of each step: model calls, tool calls, and latency. Bedrock model invocation logging is disabled by default. Turn it on for the audit trail, and treat the logs as sensitive, because they contain full prompts and responses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws bedrock put-model-invocation-logging-configuration &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--logging-config&lt;/span&gt; &lt;span class="s1"&gt;'{
    "cloudWatchConfig": {
      "logGroupName": "/bedrock/model-invocations",
      "roleArn": "arn:aws:iam::111122223333:role/BedrockInvocationLogging"
    },
    "textDataDeliveryEnabled": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Score 2 if traces, invocation logs, and alarms on errors, throttling, and latency exist in the production account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;14. Are evaluations running on live traffic?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AgentCore Evaluations samples live traces and scores them with built-in evaluators for response quality, safety, task completion, and tool use, or with your own. Score 2 if online evaluation runs on production traffic with an alarm when scores drop below the threshold from check 2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;15. Can you roll back a model, prompt, or agent change?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pin model versions instead of relying on whatever is newest. Deploy agent changes as new AgentCore Runtime versions behind an endpoint, so you can move traffic back. Track Bedrock model end-of-life dates. Score 2 only if you rehearsed a rollback in a non-production account. A 0 here blocks production.&lt;/p&gt;




&lt;h2&gt;
  
  
  Worked example: a support agent leaving a direct API setup
&lt;/h2&gt;

&lt;p&gt;This example is hypothetical, built to show the scoring. A team runs a LangGraph customer support agent in a container, calling a model provider's API directly with a key in an environment variable. It handles about 10,000 tasks a month. Its first scoring pass:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Business (checks 1–2): 1, 0.&lt;/strong&gt; Token counts exist, but there is no golden set.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;People (3–4): 1, 0.&lt;/strong&gt; One engineer owns everything, and no one has used AgentCore.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Governance (5–6): 0, 0.&lt;/strong&gt; No model allow-list, no cost tags.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform (7–10): 1, 1, 0, 1.&lt;/strong&gt; Quotas not checked against peak, tools called directly from code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security (11–12): 0, 1.&lt;/strong&gt; API keys in environment variables, no PrivateLink yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operations (13–15): 1, 0, 0.&lt;/strong&gt; Application logs only, no evaluations, no rollback path.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total: 7 out of 30, with blockers on checks 2, 11, and 15. A sensible next four to six weeks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build a golden set from past tickets and score the current agent.&lt;/li&gt;
&lt;li&gt;Deploy the same LangGraph code to AgentCore Runtime in a non-production account.&lt;/li&gt;
&lt;li&gt;Move the agent's tools behind Gateway with Identity and a first Policy rule.&lt;/li&gt;
&lt;li&gt;Add the model allow-list and a tagged application inference profile.&lt;/li&gt;
&lt;li&gt;Run the golden set on both setups, then score all 15 checks again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With the example prices from check 1, caching 6,000 of 8,000 input tokens per call would take the cost per task from about $0.23 to about $0.14, or from about $2,340 to about $1,370 a month at 10,000 tasks. Confirm with your model's real cache pricing.&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Do I need AgentCore to use Amazon Bedrock?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. You can call Bedrock models from any application with the Converse or InvokeModel APIs. AgentCore adds hosting, memory, tool gateway, identity, policy, observability, and evaluations for agents, and works with models from Bedrock or other providers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I run LangGraph or CrewAI agents on AgentCore?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. AgentCore Runtime is framework-agnostic, and AWS documents agents built with Strands Agents, LangGraph, and CrewAI running on it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Amazon Bedrock train on my prompts?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AWS states that Bedrock does not use your prompts and completions to train AWS models and does not share them with third-party model providers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I still need to request model access in Bedrock?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not for most models. Since October 2025, serverless models are enabled by default in commercial Regions. Anthropic models need a one-time use-case form. Some AWS Marketplace models need a subscription, which Bedrock tries to create on first use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long can an AgentCore Runtime session run?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Up to 8 hours per session on microVMs, with a default idle timeout of 15 minutes. AgentCore Runtime instances support work up to 14 days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I get higher Bedrock quotas?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Request increases in Service Quotas per model and Region, and use cross-Region inference profiles to spread load. AWS gives priority to accounts that already use their existing quota.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the difference between AgentCore Policy and Bedrock Guardrails?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Policy controls which tool calls an agent may make, with Cedar rules checked at AgentCore Gateway. Guardrails filter model inputs and outputs, for example blocking topics or redacting PII.&lt;/p&gt;




&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/cut-aws-nat-gateway-costs-7-fixes-for-platform-teams-5057570fc82d" rel="noopener noreferrer"&gt;Cut AWS NAT Gateway Costs: 7 Fixes for Platform Teams&lt;/a&gt;: agents that call external APIs from private subnets pay NAT charges on every request.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@anikievev/eks-1-37-upgrade-checklist-what-breaks-and-how-to-test-it-1a08b9f2fe05" rel="noopener noreferrer"&gt;EKS 1.37 Upgrade Checklist: What Breaks and How to Test It&lt;/a&gt;: for teams that host tools or models on Kubernetes.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/what-is-bedrock-agentcore.html" rel="noopener noreferrer"&gt;Amazon Bedrock AgentCore overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-sessions.html" rel="noopener noreferrer"&gt;AgentCore Runtime: isolated sessions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/03/policy-amazon-bedrock-agentcore-generally-available/" rel="noopener noreferrer"&gt;Policy in Amazon Bedrock AgentCore is generally available (March 2026)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/03/agentcore-evaluations-generally-available/" rel="noopener noreferrer"&gt;Amazon Bedrock AgentCore Evaluations is generally available (March 2026)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2025/10/amazon-bedrock-automatic-enablement-serverless-foundation-models" rel="noopener noreferrer"&gt;Amazon Bedrock automatic enablement of serverless foundation models (October 2025)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html" rel="noopener noreferrer"&gt;Access Amazon Bedrock foundation models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/service-tiers-inference.html" rel="noopener noreferrer"&gt;Service tiers for Amazon Bedrock inference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/quotas-runtime.html" rel="noopener noreferrer"&gt;Quotas for the bedrock-runtime endpoint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html" rel="noopener noreferrer"&gt;Prompt caching in Amazon Bedrock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/model-invocation-logging.html" rel="noopener noreferrer"&gt;Model invocation logging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/bedrock/pricing/" rel="noopener noreferrer"&gt;Amazon Bedrock pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/professional-services/CAF/perspectives" rel="noopener noreferrer"&gt;AWS Cloud Adoption Framework perspectives&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Moving an agent to Bedrock and AgentCore? I run readiness assessments and build the AWS foundations for AI teams at &lt;a href="https://devopscloudconsult.com/" rel="noopener noreferrer"&gt;DevOps Cloud Consult&lt;/a&gt;: landing zone, model access controls, observability, and cost tracking. If you scored under 24, that is the work I can help with.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>agents</category>
      <category>mlops</category>
    </item>
  </channel>
</rss>
