<?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 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>
