{"id":80715,"date":"2026-07-29T13:04:57","date_gmt":"2026-07-29T07:34:57","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=80715"},"modified":"2026-07-30T15:54:58","modified_gmt":"2026-07-30T10:24:58","slug":"guide-to-fixing-cves-in-amazon-eks-worker-nodes-by-updating-node-group-amis","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/guide-to-fixing-cves-in-amazon-eks-worker-nodes-by-updating-node-group-amis\/","title":{"rendered":"Guide to Fixing CVEs in Amazon EKS Worker Nodes by Updating Node Group AMIs"},"content":{"rendered":"<h1><strong>A Practical Guide to Fixing CVEs in Amazon EKS Worker Nodes by Updating Node Group AMIs<\/strong><\/h1>\n<p>Learn how to identify security vulnerabilities (CVEs) in your EKS worker nodes, update them safely without affecting running applications, and automate the process so your clusters stay secure over time.<\/p>\n<h2><strong>Executive Summary<\/strong><\/h2>\n<p>When you create an Amazon EKS cluster, the worker nodes run on Amazon Machine Images (AMIs). These AMIs contain the operating system, Linux kernel, container runtime, and other software required for Kubernetes to function.<\/p>\n<p>Like any operating system, these components receive security updates over time. As new vulnerabilities (CVEs) are discovered, AWS builds and publishes updated EKS-optimized AMIs that include the necessary security fixes.<\/p>\n<p>One thing that often catches teams by surprise is that AWS doesn&#8217;t automatically replace your existing worker nodes when a new AMI is released. If your node group was created several months ago and hasn&#8217;t been updated since, it&#8217;s probably still running the same AMI it started with.<\/p>\n<p>Your applications may continue running without any issues, but the operating system underneath them could contain vulnerabilities that have already been fixed in newer AMIs. Most teams don&#8217;t notice this until they run a security scan or prepare for a compliance audit.<\/p>\n<p>The good news is that updating worker nodes is a routine maintenance task. The overall process is simple:<\/p>\n<ul>\n<li>Check whether your node groups are using an outdated AMI.<\/li>\n<li>Update the managed node group to use the latest EKS-optimized AMI.<\/li>\n<li>Allow EKS to replace the old worker nodes one at a time.<\/li>\n<li>Verify that all workloads are running normally after the update.<\/li>\n<\/ul>\n<p>In this guide, we will walk through each step and explain how to perform the update safely with little or no impact on your applications.<\/p>\n<h2>Understanding the Problem<\/h2>\n<p>A common misconception is that Amazon EKS automatically keeps every part of your Kubernetes cluster up to date. That&#8217;s only partly true.<br \/>\nAWS manages the Kubernetes control plane for you, which includes components such as:<\/p>\n<ul>\n<li>Kubernetes API Server<\/li>\n<li>etcd<\/li>\n<li>Scheduler<\/li>\n<li>Control Plane availability and upgrades<\/li>\n<\/ul>\n<p>However, the worker nodes are your responsibility. That means you&#8217;re responsible for:<\/p>\n<ul>\n<li>Updating the operating system<\/li>\n<li>Installing security patches<\/li>\n<li>Keeping the Linux kernel up to date<\/li>\n<li>Fixing vulnerabilities found on the EC2 instances running your workloads<\/li>\n<\/ul>\n<p>You can think it like this:<br \/>\n<span style=\"color: #008000;\">EKS Cluster<\/span><br \/>\n<span style=\"color: #008000;\">&#8212;&#8212;&#8212;&#8212;&#8212;-<\/span><br \/>\n<span style=\"color: #008000;\">Control Plane<\/span><br \/>\n<span style=\"color: #008000;\">Managed by AWS : Automatically patched<\/span><br \/>\n<span style=\"color: #008000;\">&#8212;&#8212;&#8212;&#8212;&#8212;-<\/span><br \/>\n<span style=\"color: #008000;\">Worker Nodes<\/span><br \/>\n<span style=\"color: #008000;\">Managed by You : Need manual updates<\/span><br \/>\n<span style=\"color: #008000;\">&#8212;&#8212;&#8212;&#8212;&#8212;-<\/span><\/p>\n<p>If you will not update your worker nodes, they will continue running an old operating system with known vulnerabilities.<\/p>\n<h2><strong>What Is a CVE?<\/strong><\/h2>\n<p><strong>CVE<\/strong> stands for <strong>Common Vulnerabilities and Exposures.<br \/>\n<\/strong>A CVE is simply a publicly documented security flaw.<br \/>\nExample:<\/p>\n<ul>\n<li>Linux kernel vulnerability<\/li>\n<li>OpenSSL vulnerability<\/li>\n<li>glibc vulnerability<\/li>\n<li>containerd vulnerability<\/li>\n<li>systemd vulnerability<\/li>\n<\/ul>\n<p>Assume AWS released an AMI in January.<br \/>\n<span style=\"color: #008000;\">January : AMI Version 1.0<\/span><br \/>\nyour workloads are secured.<\/p>\n<p>Then in March, researchers discover:<br \/>\nEx: <span style=\"color: #008000;\">CVE-2026-12345(Linux Kernel Privilege Escalation)<\/span><\/p>\n<p>AWS fixes it and releases new AMI:<br \/>\n<span style=\"color: #008000;\">April : AMI Version 1.1<\/span><\/p>\n<p>But your cluster is still running on AMI Version 1.0<\/p>\n<p>Your applications will work perfectly but the operating system underneath is vulnerable and this known as <strong>security drift<\/strong>.<\/p>\n<h2><strong>How to Detect Vulnerable Worker Nodes<\/strong><\/h2>\n<p>Before fixing it, you need to first know whether your nodes are outdated or not.<br \/>\nThere are several ways to check that<\/p>\n<h3><strong>Method 1: Amazon Inspector (Recommended)<\/strong><\/h3>\n<p>Amazon Inspector continuously scans EC2 instances for known vulnerabilities.<br \/>\nIt can detect issues like:<\/p>\n<ul>\n<li>Kernel vulnerabilities<\/li>\n<li>OpenSSL CVEs<\/li>\n<li>Package vulnerabilities<\/li>\n<li>High severity issues<\/li>\n<li>Critical vulnerabilities<\/li>\n<\/ul>\n<p>Example findings:<br \/>\nCritical : CVE-2026-12345<\/p>\n<p>Affected Package: kernel<br \/>\nAffected Instance: i-xxxxxxxxxx<\/p>\n<p>This tells you which worker node is vulnerable.<\/p>\n<h2><strong>Method 2: Trivy<\/strong><\/h2>\n<p>If you are using Trivy(Open Source tool) then it can scan both:<\/p>\n<ul>\n<li>EC2 AMIs<\/li>\n<li>Container Images<\/li>\n<\/ul>\n<p>Example:<br \/>\n<span style=\"color: #008000;\">trivy image nginx:latest<\/span><\/p>\n<p>Or<\/p>\n<p><span style=\"color: #008000;\">trivy fs \/<\/span><br \/>\nThis identifies vulnerable operating system packages.<\/p>\n<h2>Method 3: AWS EKS AMI Release Notes<\/h2>\n<p>AWS publishes release notes every time a new EKS AMI is released.<br \/>\nExample release:<br \/>\nAmazon EKS Optimized AMI : 1.29-20260701<br \/>\nIncludes fixes for:<br \/>\nCVE-2026-1111<br \/>\nCVE-2026-2222<br \/>\nCVE-2026-3333<br \/>\nIf your node groups are using older AMI image then those vulnerabilities are still present.<\/p>\n<h2><strong>Check Which AMI Your Worker Nodes Are Using<\/strong><\/h2>\n<p><strong>Run:<\/strong><span style=\"color: #008000;\"> aws eks describe-nodegroup &#8211;cluster-name my-cluster-name &#8211;nodegroup-name my-nodegroup-name\u00a0&#8211;query &#8220;nodegroup.releaseVersion&#8221;<\/span><br \/>\n<strong>Example output you will receive : 1.29.2-20260xx<\/strong><\/p>\n<p>This will tell you the current AMI release your node group is running with.<\/p>\n<h2>Check the Latest Recommended AMI<\/h2>\n<p>AWS stores the latest recommended EKS AMI in the Systems Manager Parameter Store.<br \/>\n<strong>Run:<\/strong> <span style=\"color: #008000;\">aws ssm get-parameter &#8211;name\/aws\/service\/eks\/optimized-ami\/1.29\/amazon-linux-2\/recommended\/image_id &#8211;query &#8220;Parameter.Value&#8221; &#8211;output text<\/span><\/p>\n<p>You will get something like: ami-0abc12345<br \/>\nIf your node group&#8217;s release version is older than the latest recommended release, it is time to update it.<\/p>\n<h2>How EKS Updates Worker Nodes<\/h2>\n<p>When you are updating a Managed Node Group, EKS does not shut down all nodes at once.<br \/>\nInstead it replaces them gradually.<br \/>\n<strong>For example:<br \/>\nOld Nodes<\/strong><\/p>\n<p>Node 1<br \/>\nNode 2<br \/>\nNode 3<br \/>\nNode 4<\/p>\n<p>EKS launches a new node first:<br \/>\nNode 1<br \/>\nNode 2<br \/>\nNode 3<br \/>\nNode 4<\/p>\n<p><strong>New Node<br \/>\n<\/strong>Once the new node becomes healthy:<\/p>\n<ul>\n<li>Pods move to the new node.<\/li>\n<li>One old node is drained.<\/li>\n<li>The old node is terminated.<\/li>\n<\/ul>\n<p>This process repeats until all nodes get replaced.<br \/>\nApplications remain available during the update if they have deployed with enough replicas and sensible disruption budgets.<\/p>\n<h2>Rolling Update vs Force Update<\/h2>\n<p><strong>Rolling Update (Recommended)<br \/>\n<\/strong>Rolling updates replace one node at a time.<br \/>\nThe process contains:<\/p>\n<ol>\n<li>Launch a new node.<\/li>\n<li>Wait until it&#8217;s healthy.<\/li>\n<li>Drain an old node.<\/li>\n<li>Move pods.<\/li>\n<li>Delete the old node.<\/li>\n<li>Repeat.<\/li>\n<\/ol>\n<p>This is the safest approach for production.<\/p>\n<p><strong>Force Update<br \/>\n<\/strong>Sometimes updates become stuck because Kubernetes is not allowed to evict pods.<\/p>\n<p>In such cases, EKS offers a force update.<\/p>\n<p>A force update ignores Pod Disruption Budgets (PDBs) and may interrupt workloads, so it should only be used when there are security risks of delaying the update is greater than the risk of downtime.<\/p>\n<p><strong>Step 1: Check Current AMI Version<\/strong><br \/>\n<span style=\"color: #008000;\">aws eks describe-nodegroup &#8211;cluster-name my-cluster &#8211;nodegroup-name my-nodegroup\u00a0&#8211;query &#8220;nodegroup.{current:releaseVersion,amiType:amiType}&#8221;<\/span><br \/>\n<strong>Example:<br \/>\n<\/strong>Current Release: 1.29.2-20260xx<\/p>\n<p><strong>Step 2: Check Pod Disruption Budgets<\/strong><br \/>\nBefore updating you need to ensure Kubernetes is allowed to move pods.<\/p>\n<p><strong>Run:<\/strong> <span style=\"color: #008000;\">kubectl get pdb &#8211;all-namespaces<\/span><\/p>\n<p>Example:<br \/>\n<span style=\"color: #008000;\">NAME frontend-pdb<\/span><br \/>\n<span style=\"color: #008000;\">MIN AVAILABLE 2<\/span><br \/>\nIf you have only one pod but your PDB requires it to stay available, Kubernetes cannot evict it, and the update will stop.<\/p>\n<p><strong>Step 3: Update the Node Group<\/strong><br \/>\nIf Terraform manages your infrastructure, update the launch template or AMI reference and apply the changes:<br \/>\n<span style=\"color: #008000;\">resource &#8220;aws_eks_node_group&#8221; &#8220;main&#8221; {<\/span><br \/>\n<span style=\"color: #008000;\">\u00a0\u00a0cluster_name = aws_eks_cluster.this.name<\/span><br \/>\n<span style=\"color: #008000;\">\u00a0\u00a0node_group_name = &#8220;primary&#8221;<\/span><br \/>\n<span style=\"color: #008000;\">\u00a0\u00a0launch_template {<\/span><br \/>\n<span style=\"color: #008000;\">\u00a0\u00a0\u00a0\u00a0id = aws_launch_template.node.id<\/span><br \/>\n<span style=\"color: #008000;\">\u00a0\u00a0\u00a0\u00a0version = aws_launch_template.node.latest_version<\/span><br \/>\n<span style=\"color: #008000;\">\u00a0\u00a0}<\/span><br \/>\n<span style=\"color: #008000;\">\u00a0\u00a0update_config {<\/span><br \/>\n<span style=\"color: #008000;\">\u00a0\u00a0\u00a0\u00a0max_unavailable_percentage = 25<\/span><br \/>\n<span style=\"color: #008000;\">\u00a0\u00a0}<\/span><br \/>\n<span style=\"color: #008000;\">}<\/span><\/p>\n<p>Apply the update: <span style=\"color: #008000;\">terraform apply -target=aws_eks_node_group.main<\/span><\/p>\n<p>If you need an urgent update without using Terraform files then you can use the AWS CLI CMD:<br \/>\n<span style=\"color: #008000;\">aws eks update-nodegroup-version &#8211;cluster-name my-cluster\u00a0&#8211;nodegroup-name my-nodegroup<br \/>\n<\/span><\/p>\n<p>EKS then begins replacing nodes with instances launched from the newer AMI.<\/p>\n<p><strong>Step 4: Monitor the Update<\/strong><\/p>\n<p>Check the update status with below CMD:<br \/>\n<span style=\"color: #008000;\">aws eks describe-update &#8211;name my-cluster &#8211;nodegroup-name my-nodegroup\u00a0&#8211;update-id &lt;update-id&gt;<\/span><\/p>\n<p>Watch nodes joining and leaving the cluster: <span style=\"color: #008000;\">kubectl get nodes -o wide &#8211;watch<br \/>\n<\/span>You will see new nodes coming up with the updated AMI while older nodes are cordoned, drained, and removed.<\/p>\n<p><strong>Step 5: Verify Everything Is Healthy<\/strong><\/p>\n<p>Once the update completes you have to confirm that there are no workloads stuck because of scheduling or capacity issues.<br \/>\n<span style=\"color: #008000;\">kubectl get pods &#8211;all-namespaces &#8211;field-selector=status.phase!=Running<\/span><\/p>\n<p>If nothing is returned, it is a good sign that all pods are running normally.<br \/>\nYou can also check Node status, All nodes should report a Ready status.<\/p>\n<h2>What If Something Goes Wrong?<\/h2>\n<p>Sometimes, a newly released AMI can cause an unexpected issue, such as a driver problem or incompatibility with your workloads.<br \/>\nIf that happens, you can roll back by pointing your node group back to the previous launch template version.<br \/>\nView available launch template versions with Below CMD:<br \/>\n<span style=\"color: #008000;\">aws ec2 describe-launch-template-versions\u00a0&#8211;launch-template-id lt-0123456789abcdef0<\/span><\/p>\n<p>Then update Terraform to use the earlier version:<br \/>\n<span style=\"color: #008000;\">launch_template {<\/span><br \/>\n<span style=\"color: #008000;\">\u00a0\u00a0id = aws_launch_template.node.id<\/span><br \/>\n<span style=\"color: #008000;\">\u00a0\u00a0version = &#8220;5&#8221;<\/span><br \/>\n<span style=\"color: #008000;\">}<\/span><\/p>\n<p>Then apply the changes with: <span style=\"color: #008000;\">terraform apply<br \/>\n<\/span>EKS will replace the newer nodes with ones created from the old AMI.<\/p>\n<h2><strong>Automating the Entire Process<\/strong><\/h2>\n<p>Manually checking AMIs across multiple clusters quickly is difficult.<br \/>\nA simple automation can handle most of this work.<\/p>\n<div id=\"attachment_80716\" style=\"width: 353px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-80716\" decoding=\"async\" loading=\"lazy\" class=\" wp-image-80716\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2026\/07\/Blog.png\" alt=\"Automation\" width=\"343\" height=\"480\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2026\/07\/Blog.png 1060w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Blog-214x300.png 214w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Blog-731x1024.png 731w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Blog-768x1075.png 768w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Blog-624x874.png 624w\" sizes=\"(max-width: 343px) 100vw, 343px\" \/><p id=\"caption-attachment-80716\" class=\"wp-caption-text\">Automation<\/p><\/div>\n<p>This ensures your clusters are checked regularly instead of relying on someone to remember.<\/p>\n<h2><strong>Best Practices<\/strong><\/h2>\n<ul>\n<li>Update worker nodes regularly not just after an audit.<\/li>\n<li>Test new AMIs in development or staging before rolling them out in production.<\/li>\n<li>Keep launch template versions explicit so you can easily roll back if required.<\/li>\n<li>Review Pod Disruption Budgets before maintenance windows to avoid stalled updates.<\/li>\n<li>Automate weekly checks for new EKS AMI releases and notify your team when updates are available.<\/li>\n<li>Remember that updating the control plane does not update worker nodes &amp; both need their own maintenance lifecycle.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>A Practical Guide to Fixing CVEs in Amazon EKS Worker Nodes by Updating Node Group AMIs Learn how to identify security vulnerabilities (CVEs) in your EKS worker nodes, update them safely without affecting running applications, and automate the process so your clusters stay secure over time. Executive Summary When you create an Amazon EKS cluster, [&hellip;]<\/p>\n","protected":false},"author":2167,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":0},"categories":[5877],"tags":[1891,5303,8728,3965,8727],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/80715"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/2167"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=80715"}],"version-history":[{"count":2,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/80715\/revisions"}],"predecessor-version":[{"id":80966,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/80715\/revisions\/80966"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=80715"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=80715"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=80715"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}