AWS ECS Express Mode Is a Dissapointment | ✉️ #92
Hey! 👋
I love AWS for the diversity of services it offers. You can really build anything with probably the biggest Lego set across all cloud providers. But one thing AWS consistently fails at is a simple way to just run a single container image, expose it to the Internet, and let it scale horizontally.
Google Cloud has had this forever — it's called Cloud Run, and that's why we run claimora.com on it. AWS, meanwhile, has made multiple attempts. There is Elastic Beanstalk. There was AWS Copilot, now killed. There was ECS, which requires many different components configured just to get your container exposed. AWS infamously has seventeen-plus ways to run container images, and we even did a video a couple of years ago about how hard it is to run a simple containerized web app on AWS.
The two attempts that almost worked
Over the years, two AWS teams came close.
AWS Copilot was not a dedicated service, but a collection of high-level abstractions that nicely wrapped existing services. It exposed a simple YAML file where you could, in a few lines, define your web application or background worker — which Copilot then transformed into a set of CloudFormation stacks. Copilot was built for a multi-account world, with good defaults around a dedicated tooling account connected to multiple environment-specific accounts. It was, in short, too good to exist. AWS killed it.
AWS AppRunner was its own dedicated service, and probably the closest AWS ever got — and will ever get — to something as simple as GCP Cloud Run. With AppRunner, you never managed load balancers or complex YAML. Take a container image, expose it, done. And it was completely serverless: zero requests meant zero cost, and it scaled with load. I had my own gripes with AppRunner, but eventually I ran most of mkdev's AWS-hosted applications on it, because it sat at the right level of abstraction — and crucially, it was not a wrapper around CloudFormation. It was its own proper service.
Apparently it was also too good to keep alive: AWS stopped improving AppRunner almost the moment they released it, and this year they finally killed it too.
Enter ECS Express Mode
The supposed alternative is ECS Express Mode. I finally had time to check it out, and I don't think there's any new AWS feature I hate more.
The problem isn't that it's another wrapper around an existing service. The problem is that Express Mode completely breaks the pattern AWS normally uses for wrapper services — which is to build them on top of CloudFormation. We saw that pattern with Elastic Beanstalk, with Copilot, and with Control Tower (which automates landing zone and organization setup via AWS-managed CloudFormation stacks). ECS Express Mode looks and feels like another wrapper like this — but it isn't one. There's no CloudFormation anywhere in the stack. It just exposes new abstractions and new APIs, and those abstractions end up managing dozens of ECS components, VPC components, and ALBs under the hood.
In the end, Express Mode bundles up many services together, each of them a standard ECS service with no special sauce. Express Mode itself is a new layer — but unlike any other similar layer AWS has built, this one is entirely its own thing. The most confusing possible combination: a wrapper around existing services that somehow isn't driven by CloudFormation.
To be clear: I'm totally fine with something not being driven by CloudFormation. Second to ECS Express Mode, the thing I hate most in AWS is CloudFormation, and I'll avoid touching it whenever I can. But I often can't. And I can manage ECS Express Mode with Terraform or the CLI — yet for some reason I'm still exposed to all the lower-level primitives underneath.
It's as if, when you'd created an EC2 instance, AWS insisted on showing you all the base-level components that provision it — the VMs, the bare metal, everything — and told you: yes, we have this new entity called EC2 on top, but the 25,000 things underneath are still yours to deal with.
It's hard to imagine what happens if I import an Express-Mode-provisioned ALB into Terraform and try to manage it like any other ALB. It's also unclear how all these auto-generated resources fit into your naming conventions, because you don't seem to have much control over how Express Mode generates them. A lot like CloudFormation, while not being CloudFormation.
Who is this even for?
If you're an existing customer running many workloads on ECS with infrastructure as code, you probably don't care about Express Mode — you already have all of this automated through Terraform, CloudFormation, or something else. And if you're a new customer who just wants to deploy something quickly, Express Mode doesn't actually make anything better. It might shave some time off the initial deployment, but it provisions everything in a way that makes infrastructure as code harder later, and it pushes you toward bundling 25 services behind a single ALB instead of thinking about splitting them across multiple accounts.
There are no CI/CD features either — something Copilot did really well, and even AppRunner handled (it integrated with GitHub, for instance). Express Mode does none of that. It gives you two or three new API resources that create 20–30 other resources, and you still need to understand how all of them work. They're all sitting there in your account. It's just that there's now a new entity on top that auto-provisioned them.
So what's left?
I'm at a loss. We already migrated off AWS Copilot. Now we also have to migrate off AWS AppRunner. And ECS Express Mode just won't cut it — not enough simplicity, not enough abstraction, and no truly serverless scaling: you pay at least $20/month for the ALB, plus the tasks.
It seems like AWS just wants me to use Lambda with CloudFront for simple container deployments these days.
What We've Discovered
- cloudshell-store: "Every AWS region gives you a free CloudShell environment with ~1GB of persistent disk. Across all supported regions, that's a decent amount of free, globally distributed storage. What if you could stitch them together into a single fault-tolerant file store?" - yes, what if?
The 93rd mkdev dispatch will arrive on Friday, May 8th. See you next time!