DEV Community

Ustun Ozgur
Ustun Ozgur

Posted on

A Practical Guide to Moving from AWS App Runner to ECS Express Mode

Most teams hear "App Runner is closing to new customers" and think: swap the
runtime resource, point DNS at the new service, done.

In practice, the migration is bigger than that.

AWS now recommends Amazon ECS Express Mode as the migration path. App Runner
closes to new customers on April 30, 2026. Existing services keep running, but
no new features are planned. If you are still on App Runner, the clock is
ticking.

The reason the migration feels deceptively small is that App Runner often sits
in the middle of several things operators rely on: custom domains, TLS
certificates, WAF rules, CI/CD assumptions, health checks, deployment and
rollback habits. Change the runtime and you may discover that half of those were
tightly coupled to it.

This is the playbook I would hand someone starting this migration today.

Start with the Right Mental Model

Do not treat this as a resource rename.

Treat it as a platform migration with at least four moving parts:

  1. runtime
  2. public edge
  3. deployment workflow
  4. operational recovery paths

The runtime is only one layer. Teams lose time when they update the service
first and only later discover that deploys, health checks, certificates, DNS,
or WAF behavior were tightly coupled to App Runner.

What Usually Carries Over Cleanly

The easiest migrations already have these characteristics:

  • the application already runs from a container image
  • images are already published to ECR or another registry
  • environment variables and secrets are already separated
  • the application exposes a stable health endpoint
  • the team already has separate app-only and infra-only operational flows

If you already build an image and ship that image, you are in good shape. That
means the migration is mostly about runtime and edge behavior, not packaging.

One note: if your App Runner service currently deploys from source code rather
than a container image, you will need to add a build step that produces an image
and pushes it to a registry like ECR. Plan for that work separately.

What Changes in ECS Express Mode

ECS Express Mode keeps the simple "give AWS an image and let it run" model, but
it does so by creating ECS and load-balancer infrastructure in your account. You
gain visibility into underlying resources, but you also inherit integration
points around them.

This is where many migrations get harder than expected. Your new runtime may be
simple to create, but your operational tooling now has to coexist with
load-balancer, listener, target-group, certificate, and routing behavior.

Observability changes: X-Ray is no longer built-in

App Runner had native X-Ray integration. You toggled a setting in the
observability configuration, and App Runner handled the rest. The ADOT
collector ran behind the scenes without you managing a sidecar or daemon.

ECS does not work that way. To get X-Ray tracing on ECS (including Express
Mode), you need to run the X-Ray daemon as a sidecar container in your task
definition, instrument your application with the ADOT or X-Ray SDK, and
configure the appropriate IAM permissions on your task role. It is not
difficult, but it is not free either. Plan for an extra container in your task
definition, the associated CPU and memory overhead, and the time to verify that
traces are actually flowing.

If your team relied on App Runner's built-in tracing for debugging production
issues, do not leave this until after the migration. Set it up during the
parallel validation phase so you have the same visibility on the new service
before you shift traffic.

Cost changes: the ALB you did not used to pay for

App Runner included load balancing in its pricing. You did not see a separate
ALB line item on your bill.

ECS Express Mode creates an Application Load Balancer in your account. An ALB
costs roughly $16-25/month just to exist, even with zero traffic. For teams
running multiple environments (dev, staging, production), that adds $50-75/month
in load balancer costs before any compute charges.

Express Mode can share a single ALB across up to 25 services with compatible
networking configurations, which helps. But if your services have different
networking shapes or you need isolation, you may end up with multiple ALBs.

For small, low-traffic services where App Runner's pricing was attractive
precisely because of its simplicity, the additional ALB cost is worth
modeling before you migrate. It may not change your decision, but it should not
be a surprise on your first bill.

The Migration Plan I Recommend

1. Inventory the App Runner service before changing anything

Write down the current behavior, not just the current Terraform or console
shape.

Capture:

  • container image and tag strategy
  • CPU and memory settings
  • environment variables
  • Secrets Manager references
  • health endpoint and expected response
  • custom domains
  • certificate ownership
  • WAF and allowlist behavior
  • observability settings (X-Ray enabled or not, and how traces are consumed)
  • deployment commands people actually use

This becomes your migration acceptance checklist.

2. Preserve the image pipeline

The safest migration keeps the build artifact exactly the same.

If App Runner currently runs image X, the first ECS Express deployment should
also run image X. Do not combine a runtime migration with a packaging change
unless you absolutely have to.

That one decision removes a large class of risk.

3. Bring up ECS Express in parallel

Create the Express service with the same image, the same key environment, and
the same secret references.

Do not move public traffic yet.

Validate the service using its generated endpoint first:

  • container starts
  • app answers health checks
  • database connectivity works
  • Redis or other private dependencies work
  • logs and metrics show up where you expect
  • X-Ray traces are flowing (if you had tracing enabled on App Runner)

This is the point where you learn how Express behaves in your actual account and
network shape.

4. Rebuild the edge deliberately

This is where most hidden complexity lives.

Plan for:

  • ACM certificate creation and validation
  • Route 53 record changes
  • ALB listener and host-routing behavior
  • WAF attachment and policy scope

One of the easiest mistakes is assuming that "runtime healthy" means "public
URL healthy." That is not always true, especially when WAF sits in front of the
service.

Use different signals for different questions:

  • service rollout health
  • target-group health
  • public edge reachability

They are related, but they are not interchangeable.

5. Shift traffic gradually

Use a blue/green mindset, even if the final architecture is simple.

The broad shape is:

  1. keep App Runner serving production traffic
  2. stand up ECS Express in parallel
  3. shift a small percentage of traffic to ECS Express
  4. observe errors, latency, auth, and edge behavior
  5. complete the cutover
  6. keep App Runner around briefly for rollback confidence

Weighted DNS is a good fit for this because it gives you a straightforward
rollback path.

6. Re-verify operator workflows before deleting App Runner

This step gets skipped surprisingly often.

Before retiring App Runner, explicitly verify:

  • app-only deploy
  • infra-only apply
  • full deploy
  • secret rotation path
  • manual recovery path for custom domains
  • CI/CD workflows

If your team had three deploy paths before the migration, you should assume
people still need three deploy paths after it.

The Most Common Pitfalls

Public health checks can lie

If your public URL is protected by WAF or allowlists, a deploy script that
simply curls the public health endpoint may fail even when the backend is
perfectly healthy.

A better deployment gate is usually:

  • service rollout complete
  • target group healthy

Then use the public health endpoint as a separate edge verification signal.

Shared ALBs reduce cost and increase coupling

Express Mode can share Application Load Balancers across services that use the
same networking shape. The cost benefit is real, but so are the tradeoffs: more
host-based routing logic, more shared listener behavior, and more care required
when updating custom-domain rules.

If you have multiple public service surfaces, understand whether they will land
behind one shared ALB or separate ones before you design your routing and WAF
strategy.

Terraform will not always tell you everything during plan

This is especially true with newer resource types and services that create
dependent infrastructure on your behalf.

Be ready for cases where plan succeeds, validate succeeds, and apply reveals an
API-side constraint or provider mismatch. That does not mean Terraform is
failing you. It means you still need a real staging apply as part of the
migration process.

Also worth noting: the Terraform AWS provider has already opened issues to
deprecate App Runner resources in a future major version. If you are managing
App Runner with Terraform, expect provider-level changes in the coming months.

Secret references and secret values are not the same thing

Changing the ECS service definition is one class of update. Changing the value
inside Secrets Manager without changing the reference is a different class of
update.

Make sure your team has a clear answer to both questions:

  • how does the service pick up a changed environment variable definition?
  • how does the service pick up a rotated secret value behind the same ARN?

Those are often different mechanisms.

Do not let the migration silently change deploy contracts

If deploy-app meant "ship application code" before the migration, it should
still mean that afterward.

Migrations become much harder to validate when runtime behavior and operator
behavior change at the same time.

When ECS Express Mode Is a Good Fit

ECS Express Mode is a strong choice when:

  • you want to stay container-first
  • you want AWS-managed defaults
  • you want the underlying resources in your account
  • you do not want to hand-build every ECS and ALB component

It is especially attractive for teams that have outgrown App Runner but still
want a fairly managed experience.

When You May Want Standard ECS Instead

If you need deep control over deployment tuning, target-group behavior, listener
layout, load balancer isolation, or blue/green strategy details, then standard
ECS/Fargate with explicitly managed ALB resources may be a better fit.

That is not a knock against Express Mode. It is a recognition that managed
abstractions are most helpful when their defaults line up with your operational
needs.

It is also worth noting that ECS Express Mode does not currently support
blue/green deployment. If that is a hard requirement for your team, standard
ECS gives you more options.

A Short Acceptance Checklist

Before calling the migration done, verify all of these:

  • ECS Express is running the same image you expected
  • direct service endpoints are healthy
  • custom domains serve the correct service
  • TLS certificates are valid
  • WAF behavior still matches policy
  • X-Ray tracing works (if previously enabled)
  • app-only deploy works
  • infra-only apply works
  • full deploy works
  • secret rotation works
  • ALB cost is understood and budgeted
  • rollback steps are documented and tested

If even one of those is still "probably fine," the migration is not done yet.

Final Advice

The best way to reduce risk is to separate the migration into phases:

  1. create ECS Express
  2. validate it privately
  3. move traffic
  4. verify deploy workflows
  5. remove App Runner

Teams lose the most time when they try to do all five in one move.

If you plan the migration as a runtime swap, you will probably underestimate it.
If you plan it as a platform-and-edge migration, you will make better decisions
earlier.

Further Reading

Top comments (0)