Reading about Beanstalk Cluster Mode is fine. Putting two real services on one shared cluster and watching the second one deploy in a fraction of the time the first took is better. This walkthrough takes you end to end: an application, two container images, two EKS-tier environments sharing one cluster, a version bump, and a rollback. Budget about 45 minutes, most of which is the one-time cluster creation staring back at you.
The reason to build two services rather than one is that the second deployment is the whole product demo. The first environment provisions an EKS cluster and takes its time about it. The second lands on infrastructure that already exists, and the difference in wall-clock time is the argument for Cluster Mode compressed into a single side-by-side comparison you can run yourself instead of taking a launch blog’s word for it.
Prerequisites
- An AWS account with permissions for Elastic Beanstalk, EKS, ECR, EC2/VPC, IAM, ACM, and CloudWatch. Cluster Mode is not Free Tier eligible, so use an account where a small EKS control-plane charge will not start a conversation.
- AWS CLI v2 configured, plus Docker running locally if you are building images yourself.
- A VPC with at least two subnets in the target Region. The first Cluster Mode deployment into a subnet creates the EKS cluster.
- Two small web services that listen on a port and answer a health check path. Any language works — Cluster Mode also auto-containerizes source for Java, .NET, Python, Node.js, PHP, Ruby, and Go using Cloud Native Buildpacks if you would rather skip Docker entirely.
- Skim the Cluster Mode concepts doc first. It will make the option namespaces make sense.
Build and deploy your Beanstalk Cluster Mode services
- Set your shell variables so nothing later depends on you remembering an account ID.
export AWS_REGION="us-west-2" export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) export REGISTRY="${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com" export APP_NAME="my-microservice" - Create the Elastic Beanstalk application. Both services will live inside it.
aws elasticbeanstalk create-application \ --application-name "my-microservice" \ --description "Multi-services demo" - Create two ECR repositories and authenticate Docker against the registry.
aws ecr create-repository --repository-name frontend --region $AWS_REGION aws ecr create-repository --repository-name api --region $AWS_REGION aws ecr get-login-password --region $AWS_REGION | \ docker login --username AWS --password-stdin $REGISTRY - Build and push both images. Tag them explicitly; “latest” is how you end up debugging the wrong container at midnight.
docker build -t frontend:v1 ./frontend docker tag frontend:v1 $REGISTRY/frontend:v1 docker push $REGISTRY/frontend:v1 docker build -t api:v1 ./api docker tag api:v1 $REGISTRY/api:v1 docker push $REGISTRY/api:v1 - Register an application version for each image. The
--image-configurationparameter is what tells Beanstalk this version is an image rather than a source bundle.for svc in frontend api; do label="${svc}-v1" uri="${REGISTRY}/${svc}:v1" aws elasticbeanstalk create-application-version \ --application-name $APP_NAME \ --version-label "$label" \ --image-configuration Source="{Uri=$uri}" \ --region "us-west-2" done - Write the option-settings file for the frontend. Values below are illustrative — confirm exact option names against the option namespace reference before you bake this into a pipeline.
cat > /tmp/frontend-options.json <<'JSON' [ { "Namespace": "aws:elasticbeanstalk:eks:environment", "OptionName": "Cpu", "Value": "0.5" }, { "Namespace": "aws:elasticbeanstalk:eks:environment", "OptionName": "Memory", "Value": "256Mi" }, { "Namespace": "aws:elasticbeanstalk:eks:environment", "OptionName": "ServicePort", "Value": "8080" }, { "Namespace": "aws:elasticbeanstalk:eks:environment:autoscaling", "OptionName": "MinReplicas", "Value": "2" }, { "Namespace": "aws:elasticbeanstalk:eks:environment:autoscaling", "OptionName": "MaxReplicas", "Value": "10" }, { "Namespace": "aws:elasticbeanstalk:eks:alb", "OptionName": "Scheme", "Value": "internet-facing" }, { "Namespace": "aws:elasticbeanstalk:eks:alb", "OptionName": "HealthCheckPath", "Value": "/healthz" } ] JSON

Create the environments, update, and roll back
- Create the first environment. This is the one that provisions the EKS Auto Mode cluster, so expect roughly ten minutes. Go get coffee; the cluster will still be creating when you get back.
aws elasticbeanstalk create-environment \ --application-name my-microservice \ --environment-name frontend \ --version-label frontend-v1 \ --tier Name=Cluster,Type=EKS \ --option-settings file:///tmp/frontend-options.json - Copy the options file for the API service, change the service port and the health check path to match it, then create the second environment. This one reuses the cluster that already exists in the subnet, which is the entire point of the exercise.
sed -e 's/"8080"/"9090"/' -e 's#/healthz#/api/healthz#' \ /tmp/frontend-options.json > /tmp/api-options.json aws elasticbeanstalk create-environment \ --application-name my-microservice \ --environment-name api \ --version-label api-v1 \ --tier Name=Cluster,Type=EKS \ --option-settings file:///tmp/api-options.json - Watch both environments until they report Ready and Green, then grab the endpoints. HTTPS is on by default with certificates from AWS Certificate Manager, so hit the endpoint over TLS.
aws elasticbeanstalk describe-environments \ --application-name $APP_NAME \ --environment-names frontend api \ --query 'Environments[].[EnvironmentName,Status,Health,CNAME]' \ --output table curl -sS -o /dev/null -w '%{http_code}\n' https://<frontend-cname>/healthz - Ship a v2 of the frontend using a rolling deployment, then roll it back by redeploying the previous version. Cluster Mode also supports all-at-once, immutable, and traffic-splitting with automatic rollback when a deployment fails its checks.
docker build -t frontend:v2 ./frontend docker tag frontend:v2 $REGISTRY/frontend:v2 docker push $REGISTRY/frontend:v2 aws elasticbeanstalk create-application-version \ --application-name $APP_NAME \ --version-label "frontend-v2" \ --image-configuration Source="{Uri=$REGISTRY/frontend:v2}" \ --region "us-west-2" aws elasticbeanstalk update-environment \ --environment-name frontend \ --version-label frontend-v2 # regret it aws elasticbeanstalk update-environment \ --environment-name frontend \ --version-label frontend-v1 - Clean up when you are done, unless you want the EKS control-plane fee to become a recurring feature of your bill.
aws elasticbeanstalk terminate-environment --environment-name api aws elasticbeanstalk terminate-environment --environment-name frontend aws elasticbeanstalk delete-application \ --application-name $APP_NAME --terminate-env-by-force
If something goes sideways
Two failure modes account for most first-run problems. If an environment sits in a pending state well past the ten-minute mark on the very first deployment, check that your subnets have the routing and endpoints a cluster needs to pull images and reach AWS APIs — a private subnet with no NAT and no VPC endpoints will fail quietly and slowly, which is the worst combination. If the environment comes up but reports unhealthy, the culprit is almost always a mismatch between the container’s listening port and the ServicePort value, or a health check path that returns a redirect instead of a 200.
Beyond that, lean on the telemetry. Cluster Mode emits OpenTelemetry data to CloudWatch by default, and the built-in AI troubleshooting will read your logs and suggest fixes, which is a reasonable first stop before you start bisecting your own application. Environment events are still the fastest signal:
aws elasticbeanstalk describe-events \
--application-name $APP_NAME \
--environment-name frontend \
--max-items 20 \
--query 'Events[].[EventDate,Severity,Message]' \
--output text
What you built
Two independent services, each with its own CPU and memory budget, its own replica range, and its own load balancer settings, running on one shared EKS Auto Mode cluster that you never had to configure. You deployed a new version with a rolling strategy and reverted it with a single command. Node provisioning, patching, TLS, and OpenTelemetry-based monitoring into CloudWatch are all handled by Elastic Beanstalk rather than by you.
Worth noticing what you did not build: no node group, no ingress controller install, no cluster autoscaler configuration, no base AMI pipeline, no upgrade runbook. Those are all real pieces of work that exist in every hand-rolled Kubernetes platform, and none of them appeared in this tutorial because AWS is carrying them. That is the actual deliverable here.
From here, wire secrets through AWS Secrets Manager instead of environment variables, tune the autoscaling namespace against real traffic, and add a third service to feel how much cheaper the marginal app gets. The release note covers Region availability and the compliance scope, and there are Agent Skills for AWS containers if you want to drive this from an agent instead of a terminal.
At Enkompass (enkompass.net), this is our home turf. We put new AWS services through real client workloads the week they ship, so you inherit the working pattern instead of the scar tissue. If you’d rather have seasoned cloud people handle it instead of learning the hard way at 2 AM, let’s talk. Reach out through our contact page or call us directly at +1-828-436-5667 — we’ll help you turn this from a someday-project into a done-deal.
