Containers

Better Together: Amazon EKS Auto Mode and Istio Ambient Mesh

When your microservices architecture grows from a few services to hundreds, two problems emerge that can consume your team’s time: keeping compute infrastructure running smoothly and securing communication between services. In this post, you will learn how Amazon EKS Auto Mode and Istio Ambient Mesh work together to automate infrastructure management while providing automatic mTLS-based service-to-service security, helping reduce operational overhead and designed to help strengthen your security posture.

Teams often spend time on repetitive operational tasks such as patching nodes, scaling clusters, and configuring networking policies. As the number of services grows, securing service-to-service communication and managing proxy configurations for each service adds even more work. This growing complexity highlights the need for a more automated and integrated approach. This is where Amazon Elastic Kubernetes Service (Amazon EKS) Auto Mode and Istio Ambient Mesh come together. Amazon EKS Auto Mode automates node provisioning, scaling, and patching, so EKS Auto Mode handles the compute layer management. Istio Ambient Mesh provides automatic mutual TLS encryption and traffic policies without requiring application code changes or traditional sidecar proxies. This combination can help reduce manual work while providing automatic encryption and policy enforcement capabilities. We explore their integrated architecture and walk through a hands-on implementation from cluster creation through mTLS encryption, authorization policies, and Layer 7 traffic controls.

Understanding the components

Managing Kubernetes infrastructure traditionally requires significant operational overhead. Teams must handle node provisioning, capacity planning, OS patching, and scaling decisions manually. Amazon EKS Auto Mode addresses these challenges by extending AWS management beyond the Kubernetes control plane to the compute layer itself. It automates the full lifecycle of nodes including provisioning, scaling, patching, and update, so you can focus on deploying applications rather than maintaining infrastructure.

EKS Auto Mode runs workloads on Amazon EC2 managed instances with a hardened, container-optimized operating system and AWS-managed system components. You no longer need to deploy and operate many of the add-ons typically required to run Kubernetes in production.

Amazon EKS Auto Mode components

  • EKS Auto Mode Managed instance – AWS controls node lifecycle, patching, and security configuration. EKS Auto Mode removes direct SSH access and provides Kubernetes-native observability and troubleshooting.
  • Bottlerocket-based OS – Nodes use Bottlerocket, a minimal, immutable, container-optimized Linux distribution which includes only the essential software required to run containers. The immutable root filesystem and SELinux mandatory access control help enforce strict security boundaries.
  • Built-in system components –  AWS manages components like Amazon VPC CNI, kube-proxy, Amazon EBS CSI driver, CoreDNS, and AWS Load Balancer Controller as system processes rather than requiring you to deploy them as cluster add-ons. As a result, you avoid version compatibility issues and reduce the threat surface.
  • Karpenter-powered scaling – EKS Auto Mode uses a custom version of Karpenter. Karpenter on Auto Mode is not the same as OSS Karpenter. It provisions right-sized instances based on pod resource requests and scheduling constraints. It continuously evaluates consolidation opportunities, replacing multiple underutilized nodes with fewer, appropriately sized instances, or migrating workloads to Spot instances when possible.

The result is a Kubernetes environment where you manage workloads, not nodes. While EKS Auto Mode streamlines compute operations, you still need secure and observable service-to-service communication for your microservices. Istio Ambient Mesh helps reduce resource overhead and streamline operations by removing sidecars from the service mesh entirely. Ambient Mesh shifts traffic security and policy enforcement out of individual pods, decoupling networking from application lifecycles.

Istio Ambient Mesh components

  • Istio-cni – A node agent that watches for pods labeled for ambient mode and programs the iptables rules that send their traffic through ztunnel. It runs as a chained CNI plugin, so it coexists with whatever CNI your cluster already uses (in EKS Auto Mode, that’s the AWS VPC CNI).
  • ztunnel (zero-trust tunnel, Layer 3/4) – ztunnel is a per-node proxy (deployed as a Kubernetes DaemonSet) that creates a secure L4 overlay across your workloads. It terminates mTLS connections, enforces L4 authorization policies, and emits TCP telemetry, so application pods get zero-trust networking without code changes or sidecars. It’s written in Rust for performance and memory safety. By design, ztunnel stays at L3/L4. it doesn’t parse HTTP headers or terminate application-layer traffic, which is what keeps it safe to run as a shared per-node component.
  • Waypoint Proxies – Optional Layer 7 proxies deployed per-namespace or per-service account. Waypoints run as standard Kubernetes Deployments (enabling horizontal autoscaling) and provide HTTP-aware features: request routing, retries, timeouts, circuit breaking, and L7 authorization policies. Waypoints process traffic when you configure Layer 7 features such as request routing, retries, or circuit breaking.
  • HBONE (HTTP-Based Overlay Network Environment) Protocol – Ambient mode uses HBONE to tunnel traffic between ztunnel and waypoints. This allows mTLS-encrypted traffic to traverse existing network infrastructure without requiring CNI plugins to understand service mesh semantics.

With this model, you can apply service mesh capabilities incrementally without forcing every workload into a uniform proxy model.

EKS Auto Mode and Istio Ambient Mesh both reduce what you need to manage: one at the compute layer, the other at the service networking layer. Together, they can help reduce operational complexity while maintaining security and flexibility.

Solution architecture

Amazon EKS Auto Mode simplifies the configuration and management required to run workloads on Kubernetes. After you create the cluster, you define resource requirements (CPU, memory) and scheduling constraints (availability zones, instance types) for your workloads. Karpenter then automatically provisions the right-sized EC2 managed instances to meet these requirements, reducing the need for manual capacity planning. With node security managed by AWS, you can focus on your workloads.

Secure traffic Flow

Figure 1. Architecture of Istio ambient mode with Layer 4 features

To add workloads to the Istio Ambient Mesh, add the label istio.io/dataplane-mode=ambient to the target namespace or pod. Adding the label to the namespace adds the pods in that namespace to the ambient mesh, or you can be more selective by adding the label to specific pods. After it’s added to the ambient mesh, traffic into and out of the pod is intercepted at the Layer 4 level by ztunnel. At this point, the Istio “secure overlay” is in place, and workloads can take advantage of automatic mTLS encryption and authentication, L4 authorization policies, and TCP level observability. The ztunnel routes traffic securely to other workloads, other ztunnel proxies, or waypoint proxies.

The diagram in Figure 1 illustrates the following end-to-end workflow for Layer 4 traffic in Istio Ambient Mesh:

  • Pod startup and detection – When a pod starts, Istio-cni detects it and sends the pod network namespace file descriptor to the node-local ztunnel proxy. Ztunnel uses this to create listeners inside the pod’s network namespace.
  • Traffic redirection – Iptables rules within the pod’s namespace redirect inbound and outbound traffic to local ztunnel listeners, making sure pod traffic flows through the ztunnel proxy transparently.
  • HBONE tunnel establishment – Ztunnel establishes HBONE (HTTP-Based Overlay Network Environment) tunnels to securely transport traffic between source and destination workloads. Each unique source-destination pair gets a dedicated connection within the encrypted tunnel. Istio-cni then notifies the ztunnel proxy to set up a TCP stream between the source and destination.
  • Certificate management – Ztunnel manages SPIFFE-based X.509 certificates for each workload running on the node to support mutual TLS (mTLS) authentication, helping make sure that communication within the mesh is authenticated and encrypted.
  • Traffic encapsulation – When a Service 1 Pod sends traffic to a Service 2 Pod, the source ztunnel captures and encapsulates the traffic into the HBONE protocol and securely tunnels it to the destination ztunnel.
  • Policy enforcement and delivery – At the destination, ztunnel decapsulates the HBONE traffic, evaluates Layer 4 Authorization Policies, and presents traffic to the destination service if it passes policy enforcement. This entire process happens transparently, without the source or destination service being aware of it.

Figure 2. Architecture of Istio ambient mode with Layer 7 features (waypoint)

To take advantage of the full feature set of Istio and L7 capabilities, a waypoint proxy is required. After deploying a waypoint proxy, a label like istio.io/use-waypoint=waypoint must be added to the target namespace, service, or Pod. At this point, traffic will now flow through the waypoint proxy.

The initial steps match the L4 flow described above (iptables redirection, HBONE tunnel setup, and SPIFFE certificate management). The difference is in how traffic is routed after ztunnel captures it:

  • When a service 1 Pod sends traffic to a service 2 pod, ztunnel captures and encapsulates the traffic into the HBONE protocol and securely tunnels the traffic to the waypoint proxy
  • Waypoint proxy handles L7 processing, including policy enforcement
  • After waypoint proxy processing, the traffic is sent to the destination through a second secure tunnel to the destination ztunnel proxy
  • At the destination, ztunnel will decapsulate the HBONE traffic from the pod’s network namespace, and present traffic to destination service
  • This happens without the source or destination service aware of the process

Implementation Guide

Prerequisites

Before you begin, make sure the following tools are installed:

You also need an AWS account with permissions to create EKS clusters, VPCs, AWS Identity and Access Management (IAM) roles, and load balancers. Familiarity with Kubernetes concepts and kubectl is helpful. The walkthrough takes approximately 30-45 minutes to complete, and the AWS resources you create will incur costs while running. Be sure to complete the cleanup section when you are done.

Note: This walkthrough deploys Istio 1.28.1. Before deploying Istio in your own environment, review the Istio security advisories for any known vulnerabilities and recommended versions

Create the Amazon EKS Auto Mode Cluster with Istio’s Ambient Mode

  1. Clone the Istio on EKS repository:
git clone https://github.com/aws-samples/sample-istio-ambient-eks-automode.git
  1. Navigate to the Terraform module directory
cd sample-istio-ambient-eks-automode

The repository contains an example for deploying and running Istio on EKS. You use the Terraform module to create your EKS Auto Mode cluster and deploy the required Helm charts for Istio in ambient mode. For more information about installing Istio in ambient mode with Helm, refer to the Istio documentation. Run the following commands to create the EKS Auto Mode cluster, deploy Istio in ambient mode, and configure kubectl access to the cluster.

  1. Initialize and apply the Terraform configuration
cd terraform-blueprint/ambient
terraform init

terraform plan
terraform apply --auto-approve

Note: This step typically takes 15–20 minutes to complete, as it provisions the EKS Auto Mode cluster, VPC, IAM roles, and installs Istio in ambient mode.

  1. Configure kubectl access to the cluster
aws eks --region us-west-2 update-kubeconfig --name ambient
kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
istio-system istio-cni-node-vd4m5 1/1 Running 0 10m
istio-system istiod-759544898-56qzf 1/1 Running 0 11m
istio-system ztunnel-bq42b 1/1 Running 0 10m

Visualization

Next, deploy several add-ons to support the observability of Istio and the workloads running within the mesh.

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.28/samples/addons/prometheus.yaml -f https://raw.githubusercontent.com/istio/istio/release-1.28/samples/addons/kiali.yaml

kubectl wait --for=condition=Ready --timeout=240s pods --all -n istio-system

Kiali is a console for the Istio service mesh. You use it here to validate the ambient mode configuration. To access this dashboard, port-forward the Kiali service to your local machine:

kubectl port-forward svc/kiali 20001:20001 -n istio-system

Use your browser to navigate to http://localhost:20001

Deploy sample EKS application

To demonstrate some of the features of Istio, deploy a retail store sample application. This sample application uses a microservices architecture with components written in various programming languages and uses a variety of data stores. By default, the UI service is set to type=LoadBalancer, but you update this to ClusterIP and let Istio handle traffic into the cluster later. Run the following commands in a second terminal session.

helm install cart oci://public.ecr.aws/aws-containers/retail-store-sample-cart-chart --version 1.3.0
helm install catalog oci://public.ecr.aws/aws-containers/retail-store-sample-catalog-chart --version 1.3.0

cat > checkout-values.yaml <<EOF
redis:
  create: true
app:
  persistence:
    provider: redis
  endpoints:
    orders: 'http://orders:80'
EOF

helm install -f checkout-values.yaml checkout oci://public.ecr.aws/aws-containers/retail-store-sample-checkout-chart --version 1.3.0
helm install orders oci://public.ecr.aws/aws-containers/retail-store-sample-orders-chart --version 1.3.0

cat > ui-values.yaml <<EOF
app:
  endpoints:
    carts: http://cart-carts:80
    catalog: http://catalog:80
    checkout: http://checkout:80
    orders: http://orders:80
EOF

helm install -f ui-values.yaml ui oci://public.ecr.aws/aws-containers/retail-store-sample-ui-chart --version 1.3.0

After this step, use kubectl wait to verify that you have successfully started the pods before you proceed

kubectl wait --for=condition=Ready --timeout=120s pods --all

EKS clusters don’t include Kubernetes Gateway API custom resource definitions (CRDs) by default. The Gateway API is an open-source standard interface for Kubernetes application networking and represents the next generation of managing ingress and service mesh traffic within a cluster. Istio supports the Kubernetes Gateway API, and you need these resources to allow ingress traffic into your cluster and to manage ambient mesh traffic. There is a Gateway resource in the Istio APIs, but this walkthrough doesn’t use that resource, and there are key differences between the two.

kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
  kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/standard-install.yaml

A Gateway helps route traffic to services within the cluster. Each Gateway is associated with a GatewayClass which indicates the gateway controller that handles the traffic for that Gateway. In this example, you need traffic from outside the cluster routed to the UI service running within the cluster. By default, Istio creates a ServiceAccount, Service, and Deployment that corresponds to the Gateway configuration. If you need to adjust the settings of the underlying resources, create a ConfigMap and associate it to the Gateway resource as shown here. Route resources define rules for mapping requests through a Gateway to backend Kubernetes services. The HTTP Route is for the HTTP protocol and routes requests to the UI service.

export USER_IP=$(curl https://checkip.amazonaws.com/)
cat <<EOF | envsubst | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: retail-store-gateway
  namespace: istio-ingress
spec:
  gatewayClassName: istio
  infrastructure:
    parametersRef:
      group: ""
      kind: ConfigMap
      name: retail-store-gateway-options
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: retail-store-gateway-options
  namespace: istio-ingress
data:
  service: |
    metadata:
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
        service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
        service.beta.kubernetes.io/aws-load-balancer-attributes: load_balancing.cross_zone.enabled=true
    spec:
      loadBalancerSourceRanges:
        - ${USER_IP}/32
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: retail-store-httproute
  namespace: default
spec:
  parentRefs:
  - name: retail-store-gateway
    namespace: istio-ingress
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: ui
      port: 80
EOF

Note: This walkthrough configures the Gateway listener for HTTP on port 80 to keep the demonstration focused on the service mesh. For production environments, configure TLS termination on the Gateway listener. See the Istio Gateway TLS configuration and the AWS Load Balancer Controller TLS guidance for setting up HTTPS with ACM certificates.

To wait for the load balancer to finish provisioning you can run this command:

curl --head -X GET --retry 30 --retry-all-errors --retry-delay 15 --connect-timeout 30 --max-time 60 \
  -k $(kubectl get gateway retail-store-gateway -n istio-ingress -ojsonpath='{.status.addresses[0].value}')

To verify that workloads in the default namespace are included in the ambient mesh, label the namespace.

kubectl label namespace default istio.io/dataplane-mode=ambient

Run the following commands to get the URL to access the example retail store application.

export NLB_HOST=$(kubectl get gateway retail-store-gateway -n istio-ingress -ojsonpath='{.status.addresses[0].value}')
echo http://$NLB_HOST

You should see the example retail store homepage.

Demonstrate mTLS between services

Because we labeled the default namespace, all workloads are added to the ambient mesh and service to service communication is authenticated with mutual TLS (mTLS). To validate this, let’s generate some traffic for our example retail store which we will review in Kiali. Using the URL of the example retail store site, explore the site and the gadget repository. Add some items to your cart and complete the checkout process. Do this several times to generate test traffic.

Return to the browser tab with Kiali and open the Traffic Graph. You might need to select additional items under the Display menu. With Security selected under the Display menu, you can see the lock icon marking each segment between microservices.

If you select a segment, like between the ui and carts service, you will see on the right hand side the lock icon that indicates that mTLS is enabled for that traffic. As you can see, the lock icon is displayed for each network segment between microservices, indicating that mTLS is enabled for traffic within the ambient mesh.

Enforce mTLS within the mesh

For service-to-service communication within the ambient mesh, network traffic is authenticated with mTLS. However, mTLS isn’t required. If a service outside the scope of the ambient mesh attempts to connect to a service inside the ambient mesh, mTLS won’t be used. Create a test workload in a separate namespace so this workload isn’t automatically included in the ambient mesh.

kubectl create ns curl
kubectl run curl-pod -n curl --image=curlimages/curl:8.19.0 -- sleep infinity

Test connectivity from this workload to a service running within the ambient mesh.

kubectl exec curl-pod -n curl -- curl -s "http://catalog.default/catalog/tags"

This request succeeds because mTLS isn’t required yet for ambient mesh workloads.

sample-istio-ambient-eks-automode % kubectl exec curl-pod -n curl -- curl -s "http://catalog.default/catalog/tags"
[{"name":"accessories","displayName":"Accessories"},{"name":"clothing","displayName":"Clothing"},{"name":"food","displayName":"Food"},{"name":"vehicles","displayName":"Vehicles"}]

To enforce mTLS connectivity for ambient mesh workloads, create a mesh-wide PeerAuthentication policy that requires mTLS.

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: "default"
  namespace: "istio-system"
spec:
  mtls:
    mode: STRICT
EOF

After creating the mesh wide PeerAuthentication policy, attempt the request again.

kubectl exec curl-pod -n curl -- curl -s "http://catalog.default/catalog/tags"

Now the request fails as expected.

kubectl exec curl-pod -n curl -- curl -s "http://catalog.default/catalog/tags"
command terminated with exit code 56

Layer 4

So far you’ve seen how ztunnel handles identity and encryption at the network layer. Authorization at Layer 4 — controlling which workloads can talk to each other — is also enforced by ztunnel without any additional components. Create another test workload, but this time it resides in the default namespace and becomes part of the ambient mesh.

kubectl run curl-pod --image=curlimages/curl:8.19.0 -- sleep infinity

Test connectivity from this workload to the catalog service within the ambient mesh.

kubectl exec curl-pod -- curl -s "http://catalog/catalog/tags"

The request is successful.

sample-istio-ambient-eks-automode % kubectl exec curl-pod -- curl -s "http://catalog/catalog/tags"
[{"name":"accessories","displayName":"Accessories"},{"name":"clothing","displayName":"Clothing"},{"name":"food","displayName":"Food"},{"name":"vehicles","displayName":"Vehicles"}]

Now add an AuthorizationPolicy that restricts access to the catalog service to only the UI service. This policy is focused on workload-to-workload authorization and can be handled by the Layer 4 proxy (ztunnel).

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: catalog
  namespace: default
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: catalog
      app.kubernetes.io/component: service
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/default/sa/ui
EOF

After creating the AuthorizationPolicy, attempt the request again.

kubectl exec curl-pod -- curl -s "http://catalog/catalog/tags"

Now this request fails as expected.

sample-istio-ambient-eks-automode % kubectl exec curl-pod -- curl -s "http://catalog/catalog/tags"
command terminated with exit code 56

if you access the example retail store through your web browser, you will see the site is still fully functional because access is permitted through the UI service.

Layer 7

Now that you have seen how a Layer 4 focused AuthorizationPolicy works, we will explore some capabilities that require Layer 7. In this example, you apply application-layer restrictions by requiring requests to carry a valid authentication header. For more details on the Istio features available at Layer 4 vs. Layer 7, review the ambient mode documentation. To use Layer 7 authorization policies, you must create a waypoint proxy for the catalog service. Unlike ztunnel, which runs on every node automatically, a waypoint is something you deploy deliberately — only where you need HTTP-aware policy enforcement. You choose the blast radius: a single service, a group of services sharing the same trust boundary, or an entire namespace. Since the retail store’s catalog service is the one you want to protect with an L7 header check, you’ll deploy a waypoint scoped to just that service.

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  labels:
    istio.io/waypoint-for: service
  name: catalog-waypoint
  namespace: default
spec:
  gatewayClassName: istio-waypoint
  listeners:
  - name: mesh
    port: 15008
    protocol: HBONE
EOF

With the waypoint deployed, you now need to enroll your workloads to use it. Add a label to the catalog service to enroll this workload.

kubectl label service catalog istio.io/use-waypoint=catalog-waypoint

At this point, if you attempt to access the catalog service from the UI service, you see that access is denied.

kubectl exec deployment/ui -- curl -s "http://catalog/catalog/tags"

The access denied result will look like this:

sample-istio-ambient-eks-automode % kubectl exec deployment/ui -- curl -s "http://catalog/catalog/tags"
upstream connect error or disconnect/reset before headers. reset reason: connection termination

Adding the waypoint changes the traffic path: requests from the UI now travel through the waypoint before reaching the catalog service’s ztunnel. Because of this extra hop, the receiving ztunnel authenticates the connection as coming from the waypoint’s service account, not the UI’s. Your existing policy only allows the UI identity, so traffic is denied. The fix is to attach the AuthorizationPolicy directly to the waypoint using targetRefs, where the original source identity is still visible and can be evaluated.

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: catalog
  namespace: default
spec:
  targetRefs:
  - kind: Gateway
    group: gateway.networking.k8s.io
    name: catalog-waypoint
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/default/sa/ui
EOF

This restricts traffic to the waypoint so that it only comes from the UI service. If you attempt to access the catalog service from the UI service, you see that connectivity is restored.

kubectl exec deployment/ui -- curl -s "http://catalog/catalog/tags"

The successful request will look like this:

sample-istio-ambient-eks-automode % kubectl exec deployment/ui -- curl -s "http://catalog/catalog/tags"
[{"name":"accessories","displayName":"Accessories"},{"name":"clothing","displayName":"Clothing"},{"name":"food","displayName":"Food"},{"name":"vehicles","displayName":"Vehicles"}]

The previous policies controlled which services can communicate which is a network-level concern. But production workloads often need application-layer checks as well. A common pattern is validating access tokens at the mesh layer using Istio’s RequestAuthentication with a JWT issuer like Amazon Cognito, so requests are authenticated before they ever reach your application code. To demonstrate the L7 policy mechanics without requiring an identity provider, this example uses a static header check. Apply an AuthorizationPolicy that requires requests to the catalog service to include an x-auth-token header with a valid value.

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: catalog
  namespace: default
spec:
  targetRefs:
  - kind: Gateway
    group: gateway.networking.k8s.io
    name: catalog-waypoint
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/default/sa/ui
    when:
    - key: request.headers[x-auth-token]
      values: ["internal-retail-token"]
EOF

Testing access to the catalog service from the UI service without the header:

kubectl exec deployment/ui -- curl -s "http://catalog/catalog/tags"

The request is denied because the header is missing:

sample-istio-ambient-eks-automode % kubectl exec deployment/ui -- curl -s "http://catalog/catalog/tags"
RBAC: access denied

Now include the required header:

kubectl exec deployment/ui -- curl -s -H "x-auth-token: internal-retail-token" "http://catalog/catalog/tags"

The successful result will look like this:

sample-istio-ambient-eks-automode % kubectl exec deployment/ui -- curl -s -H "x-auth-token: internal-retail-token" "http://catalog/catalog/tags"
[{"name":"accessories","displayName":"Accessories"},{"name":"clothing","displayName":"Clothing"},{"name":"food","displayName":"Food"},{"name":"vehicles","displayName":"Vehicles"}]

Cleanup

To remove the resources created in the cluster:

  • Remove the Layer 7 authorization policy and waypoint:
    kubectl delete AuthorizationPolicy catalog
    kubectl label service catalog istio.io/use-waypoint-
    kubectl delete gateway catalog-waypoint
  • Remove the test pods, mTLS policy, and curl namespace:
    kubectl delete pod curl-pod
    kubectl delete PeerAuthentication default -n istio-system
    kubectl delete pod curl-pod -n curl
    kubectl delete ns curl
  • Remove the namespace label and ingress Gateway resources:
    kubectl label namespace default istio.io/dataplane-mode-
    kubectl delete HTTPRoute retail-store-httproute
    kubectl delete Gateway retail-store-gateway -n istio-ingress
    kubectl delete cm retail-store-gateway-options -n istio-ingress
  • Uninstall the application components:
    helm uninstall ui
    helm uninstall orders
    helm uninstall checkout
    helm uninstall catalog
    helm uninstall cart
  • Remove the values files:
    rm checkout-values.yaml
    rm ui-values.yaml
  • Destroy the Terraform-managed infrastructure:
    terraform destroy --auto-approve

Cost estimate

This walkthrough creates a single EKS Auto Mode cluster in us-west-2 running a lightweight sample application. The EKS cluster fee is $0.10/hour for the control plane (Standard Support pricing). EKS Auto Mode charges a compute fee on top of standard EC2 On-Demand instance pricing for instances it manages, which varies by instance type. With the sample retail store application modest resource requirements, expect Karpenter to provision 1–2 small instances. Including the Network Load Balancer (~$0.02/hour), the total estimated cost is approximately $0.25-$0.40 per hour depending on instance types provisioned. Complete the cleanup section to minimize costs. For detailed pricing, see Amazon EKS pricing.

Conclusion

Running microservices at scale means balancing operational complexity with security, performance, and flexibility. Amazon EKS Auto Mode and Istio Ambient Mesh help reduce the management burden at two critical layers: compute infrastructure and service networking.

With Amazon EKS Auto Mode, you no longer manage node lifecycle, patching, or scaling decisions, so you can focus on workloads rather than infrastructure. Istio Ambient Mesh complements this with a sidecarless service mesh architecture that gives you mTLS encryption, traffic management, and observability without the resource overhead of traditional sidecar deployments.

Together, these technologies give you automated compute management and simplified service mesh adoption that can reduce day-to-day tasks. Security is built-in through automatic mTLS authentication and flexible authorization policies. You can adopt capabilities incrementally, applying Layer 4 and Layer 7 features selectively based on workload requirements, while benefiting from reduced resource overhead across both managed compute and the sidecarless architecture.

For both new microservices environments and existing modernization projects, combining Amazon EKS Auto Mode with Istio Ambient Mesh provides production-ready infrastructure with less overhead and a stronger security posture. The implementation guide in this post shows how to get started, from cluster creation to enforcing mTLS and authorization policies.

You’ve built the foundation: a secure, automated Kubernetes environment with mTLS encryption out of the box. To continue your journey with EKS Auto Mode and Istio Ambient Mesh, explore these resources:


About the authors

Dave Shimko is a Solutions Architect with Amazon Web Services (AWS), working with Automotive and Manufacturing customers to accelerate their cloud and AI journeys. He is passionate about helping customers adopt containers, generative AI, and modern developer experiences. Outside of work, Dave lives in Raleigh, North Carolina and enjoys traveling, being outdoors, and spending time with his family.

Nivi Prasad is a Solutions Architect at AWS, working with startup customers in the FinTech space with a focus on containers and application modernization. She is passionate about helping customers adopt EKS and modern deployment strategies. Based in New York City, when she’s not helping startups scale their infrastructure, she enjoys going to concerts, experiencing new food, and exploring the city.

Shamanth Devagari is a Delivery Consultant at AWS, specializing in cloud-native development, distributed systems, and generative AI workloads. His primary expertise lies in guiding customers through the adoption of containerized solutions, generative AI architectures, and resilient distributed systems. Outside of work, Shamanth lives in New Jersey and enjoys traveling and exploring the latest tech trends.