Loading summary
A
Let's imagine this. You have built a slick little web application. It's kind of a monolith, but it's solid, it's a rust backend. And maybe in the front end you're using solidjs. You see what I did there? And it run well enough. And maybe initially you deployed it on premise. Maybe you have a client that gave you a box where you just put all the code and it's running fine. But now, for whatever reason, it's your turn to host it. And of course you want to host it in the cloud on aws. So what do you do? You could roll up your sleeves and dive deep into VPCs, load balancers, ECs, task definition, and all the other delightful complexity that comes with running containers on aws. Or maybe there is a simpler way. What if there was a service that just took your code or your container, whatever that is, packaged it, built it, deployed it, scale it, and just gave you a URL and even an HTTPs connection and at that point you are just done. If you do any change in your repo commit on main, the process will just start again and give you a new version just ready to use. That's actually the promise of a service called AWS App Runner. And in this episode we are putting that promise to test. So we'll share the real story of a project that we recently migrated, why we choose App Runner for it, and everything we discovered along the way. The good, the bad and the downright confusing. And there is a lot of confusing. Spoiler Alert. So if you ever wish for an Heroku like experience on aws, or if you are just trying to figure out when to use App Runner for instance, compared to something like Fargate, hopefully this episode will answer all your questions. My name is Luciano and today I'm joined by Connor for another episode of AWS Bytes podcast. AWS Bytes is sponsored by fortorem. So thanks for Theorem for making this possible. We'll tell you more about fourtheorem later. Conor, do we start by trying to describe what the heck is App Runner?
B
Yeah, what is App Runner? So it's relatively new, a mid-2021 service, and it is yet another way to run containers on AWS. So you're probably familiar with Corey Quinn's rantings about the 17 ways to run containers on AWS. I'm not actually sure if this is the 18th way or the 17th way, but there are a lot of ways. So the tagline for the service is deploy Web apps and APIs at scale and it's definitely more Orientated towards like web servers. So you know, applications that are fronted by some sort of load balancer that accept HTTP traffic. So who is it for? I guess if you're a developer, they're trying to simplify that process. I have an app, I have a docker file. I want to run this container in the cloud, please. And App Runner says that it removes a lot of complexity and moving parts. And then for your DevOps teams or your ops teams or your cloud wranglers, they also promise to REM a lot of the operational pain deployment, build container registries, VPC network topology. You know, apparently we can throw a container over the wall and make it AWS's problem. That's the dream. So focus on building your app. You know, App Runner will has a build process. It'll build your container, it'll push it to an ECR repo, it'll provision whatever infrastructure is needed, deploy the container, make it available on a magic HTTPs URL, and then it has support for auto scaling and all the things you'd expect for a solution like this. So that's App Runner. What was the exact use case? Luciano, what was your test bed for the project? I guess, yeah.
A
So it was a monolithic container with a web application with both backend and, and front end packaged together into one container. Not really relevant, but probably fun for people to know. The backend is written in Rust using the Axum framework. So in that sense it's a bit of a monolithic framework. You put all your business logic, all your HTTP routes into one binary effectively and then there is a front end which is an spa written in solidjs. So all the assets are pre built and then they are served by the same Axum server on a public path, basically. So the story for this particular project is that this was an application that was built a few years ago for a very small project. It's also probably not relevant, but probably still fun to know that it's effectively. It's like a quit style mini game. So it's not really a very complicated or something that is like business critical type of application. So that was actually a good test bed for trying new things without being too much worried about if we break something, this is going to be like a massive damage for a customer. So the idea is that originally we were only asked to build the application, something we did very quickly and now for whatever reason that application was actually hosted on premise. So our deliverable was like this is the container, go figure it out yourself. Now we are asked to. Okay, can you actually host it and manage it yourself in the cloud. And of course, because we live and breathe aws, we try to think, okay, how do we move this container to aws and can we use this excuse as a way to experiment with new services? To be honest, App Runner has been on our mind for a while. We never really had a good excuse to try it out. So we felt like, okay, this was actually the right opportunity to give it a spin because it seemed like a really relevant use case, especially because we didn't want to spend a huge amount of time in doing this migration. But maybe the question that at this point people have is we talked about App Runner and more or less what is the idea? Probably people are much more familiar with something like Fargate when it comes to container. So what is really the difference between the two?
B
Yeah, so I guess Fargate for me is kind of my meat and potato service. It is my go to service for yeeting a container into aws. Usually, you know, it's whether you have a Greenfields app or you're trying to launder technical debt into aws, it seems to be, you know, always the best choice or the least worst choice for getting your container up and running. So like it's hugely flexible and the operational burden tends to be tiny, very small. You know, once you have a Fargate service running AWS does a really good job of taking care of the tasks that are, you know, fulfilling that service. So it is our go to a lot of the time. But you know, there's obviously a lot of terraform and CDK abstractions on top of it and it's very easy to get up and running with Fargate. But I think you forget as a practitioner that's been using it a lot, that there's actually a lot of moving parts involved in Fargate. Right. So you know, you need a VPC, private subnets, root tables, NAT gateway, application, load balancer, security groups, hire groups, ACM certificate verified, assert route 53 records IAM task, execution role, task role, CloudWatch log group, ECS cluster, ECR repo task definition, ECS service and then if you want to deploy it, you probably need GitHub Actions, NoIDC identity provider, a granular role and you need to get your hands dirty and write some GitHub actions. So it's very easy to forget the level of moving parts involved and just getting a pretty straightforward web app up and running in Fargate. Right. So I guess App Runner promises to hide a lot of this complexity or at least automate it for You. So it's much more abstracted. We don't have the concept of ALBs or auto scaling groups or networking on the happy path. And then you don't really have to worry about scaling too much. Right. It has a scale to 0ish concept. It'll shut down containers and it'll relaunch them after some period of, you know, inactivity. It'll put them to sleep for you, I guess. So the pricing model on Fargate is well understood. I guess it's, you know, your kind of VCPU, gigabyte hours and then as mentioned, you have a lot of ancillary costs with a simple Fargate app, whether it's the ALB itself, public IP addresses or a NAT gateway, which you'll probably have if you want to run Fargate in a private subnet. So how does the pricing model compare in App Runner? Luciano, what are we looking at to get up and running?
A
Yeah, I think you described it really well. I think the idea of App Runner is that it is a much more managed service in a way and in that sense, probably similarly to Lambda, for example, that the pricing model is more geared towards you are going to pay for the kind of resources that you are actually, actually using. Azure Application is running and we, we mentioned that the service scales down. It doesn't really scales down to zero. And actually there is an interesting open conversation on GitHub. We'll post the link in the Show Notes. If you're curious where people are asking, well, this is not really competitive with something like Google Cloud App Runner. Sorry, is it called Up Runner, the Google Cloud one?
B
No idea.
A
There is a service to run containers. I don't think it's also. I think it's called Cloud.
B
Oh, it might be called Run, is it?
A
Yeah, something like that. There is a very similar name as well. But effectively there is a similar service in Google Cloud and lots of people are saying, well that one scales to zero. Can you AWS please do the same? Let's leave that aside for a moment. If you're curious, you can check out the link we'll put in the show notes. So going back to the pricing, the idea is that you have two dimensions again very similar to Lambda. So the amount of memory that you are using and the CPU that you are using. So for it's in that sense similar to Lambda, but there are some fundamental differences because we mentioned this concept of containers can be freezed. So you will need to have at least one container. That's the minimum. Of course you can set your Own minimum. We'll talk more about scalability later. But imagine that there is always a container there allocated for you. That container might not be consuming cpu, so in that sense it's kind of frozen and. But it's not totally destroyed. Like for instance, a lambda instance eventually gets destroyed and even all the memory is released. With App Runner it doesn't get released. There is always one container at least sleeping there. So your memory cost in a way can be. There is like a baseline that is fixed. So whatever is the minimum number of containers that you are setting in the auto scaling groups, you are going to be paying for at least that amount of memory. Then of course, if your, let's say cluster, if we can call it like that. If the number of containers, basically it's very elastic. Like if you have lots of traffic, there can be more at some point in time. So of course you will be allocating more memory. And in that sense you pay overall the memory cost, which I think is 0.007 cents of dollar per gigabyte per hour, which if you have one container is about $5 per month. So that's. I think that's kind of the baseline for one application you have in even if it's not getting any traffic, I don't think App Runner is going to get any cheaper than this. Then you have the concept of CPU cost. So the memory is only one dimension. The other dimension is CPU and cpu effectively when your container is frozen, you are not consuming any CPU even if you have any background task. Effectively your container is put to sleep in a way so the memory is still allocated, but it's not executing any cpu. And when you are actually handling web requests, so your CPU is running, that time is actually calculated and you have a cost of.0064 dollars per VCPU per hour. And you can also configure the number of VCPUs that you need per container if you're doing something, for instance, that requires multi threading. So if your app is active all the time and you have one container, the CPU cost is $46 a month. So that I think gives you the idea that even if you have only one container and it's working 24, 7 all the time, I think you will get to a cost of about $50 per month for that. So that kind of gives you, I guess the ballpark of what could be the cost. The good thing is that there is no load balancer cost, which if I remember correctly, something about $30. Correct me if I'm wrong. So you are not paying for that. So that's kind of absorbed in the rest of the cost, which is a good thing. Like actually you don't even see the load balancers in your own account. So AWS is totally managing. That are some extra costs. For instance, if you enable the feature of automatic deployments, the one that Conor you described. So you just connect your repo and let AWS do everything else. I think there is a cost of like $1 per month, but then there is also a build fee. Because of course your build might be very simple and very quick, but maybe you're doing something extremely complex that might take, I don't know, half an hour to build. So that time is built with an extra cost and it's 0.$005 per minute. So keep it in mind, like if you have a very long build, probably you might want to invest in kind of building it yourself. Because there is also another mode where you can build it yourself and then just publish the container and then tell app runner, please release this new version of the container so you are not forced to go with the totally managed approach. You can still handle the build yourself if you want, if you let AWS do it. Just keep in mind that there is an extra cost. Now, if we want to talk a little bit about networking, because I think that's an interesting point. We already mentioned that it's kind of all abstracted for you. Like you don't even know in which network your app runner or your containers are running. Like, you don't really define a VPC and put the containers. There is more magic that AWS does for you.
B
So for people that miss EC2 classic, this is a throwback. Maybe they can get back to that experience of not worrying about a vpc.
A
Pretty much, yeah. Or even, I don't know, sometimes when you just use lambda and you don't put it in a vpc, it's running somewhere magically. You don't have to worry too much about that, which I think is good. Like, I think it removes lots of complexity for many use cases, except that for almost every application at some point you need to connect to a database, right? To do anything useful. So that that creates a problem. Because if you have a database, I don't know, an RDS or an Aurora cluster running in a vpc, then how do you connect your application that is running somewhere that you don't even know to a VPC that you actually are well aware about and you actually control in your own account? So to solve this problem, the team Behind App Runner created a new concept which is effectively, I think they call it VPC endpoint, App Runner, VPC connector, something like that. So effectively there is a new concept and it's even a resource. When you looked into, I don't know, CDK or cloudformation that exists in the App Runner scope and what that allows you to do is effectively to create a connection and I think it's backed by something like private link from whatever networking AWS is provisioning for you to the actual networking where you have your own database and at that point you can decide to do different things. Like effectively you can say all the traffic that my application is generating, like either to connect to a database or maybe go and pull, I don't know, a file from an HTTP or maybe connect to s3 or maybe if you want to send an event through EventBridge. So whatever is internal or external traffic is going to go through that VPC that you control. So at that point you need to be aware of creating all necessary things like routing table, NAT gateways. Yeah, all, everything from a networking perspective to make sure that traffic can be routed correctly to your services. So I think that's the interesting part about networking that generally is very easy to get started with, but then I think eventually you still need to take a little bit of complexity because unless you don't need a database which is like most cases, or maybe you're using a database that is not even on AWS and you can just use the public network for connecting to your database, which I don't know if I would necessarily recommend. But yeah, I think for most serious use cases, I think you still need to understand a little bit of networking and make sure you understand how to connect App Runner to your own vpc.
B
Gotcha. It's great to have the escape hatch, I guess, right, that if you're on some very happy path, it's great to not have to worry about this stuff. But they didn't make it a Mickey Mouse service, I guess by not being able to integrate with the well known, you know, VPC fundamentals, I guess.
A
Okay, that's cool. Pretty much, yeah. Next topic I guess we can explore is maybe deep dive a little bit on the concept of auto scaling. We kind of mentioned it briefly, but I think it's interesting to understand it a little bit more. It's probably based on the existing load balancer auto scaling groups, but again it's something that has been a little bit abstracted for you, like you don't have to provision auto scaling groups is More you have some configuration dials that you can play with to effectively define what are the rules for which I have maybe a container to start with. And if there is more traffic, I want more containers. And then if this traffic goes down eventually I want to reduce the number of containers basically elastically based on traffic. So you actually have. Actually the first thing worth mentioning, as we said, is that you can specify just to configure a single container, so a single instance of your application you can specify virtual CPU and virtual memory. For both you actually have very limited choices. Like for CPU you have 0.250512 and 4. For virtual memory you have 2 gigabytes, 3 gigabytes, 4 gigabytes.
B
Wow. Okay. It is quite limited in the memory footprint then. Okay.
A
And I guess that's probably good enough for most web applications. So again, it's another symptom that this is a service built for web applications in mind and web applications only. Like I don't think you are expected to do, I don't know, data crunching or like massive processing. It's more you are going to be handling HTTP traffic. So probably these characteristics will cover 99% of the use cases. Then in terms of auto scaling, you have three parameters you can play with. One is max concurrency, then you have max size and min size. Now what is max concurrency is basically all the requests that you are receiving through these invisible load balancers, they effectively being monitored and you are effectively saying with this max concurrency, how many requests per second can one single instance of your application handle? So you can set this number. I think the maximum is 200, which I thought was very disappointing. So I believe it's something between like 1 and 200. But basically what it means, let's say if you set it to 200, is that as soon as you have 201 requests per second, AWS is going to spawn up a new instance of the container. Of course you can have limits. So you have this concept of minimum number of containers or min size, which goes from 1, 1 is the minimum max size. I don't know if there is a maximum, I didn't check. But it's effectively. Let's say you put 20 right. You are never going to have more than 20 containers. So if you really have a huge amount of traffic, eventually your containers are going to start to struggle a little bit because you are not going to spin up more instances. And this is just a cost control measure so you can put reasonable boundaries in place so that your containers are not going to scale Indefinitely. I guess that covers more or less what you need to know about instance configuration and auto scaling. What about security?
B
Yeah, it's always good to kick the tires on a new service and see how you or your team might shoot themselves in the foot. I guess so I had a quick play with App Runner myself. I guess one of the interesting things is if you are integrating it with GitHub or your VCS of choice, which is probably the way most teams will go to take advantage of the automation in the GitHub case anyway, it uses the AWS connector for GitHub GitHub app which is used by a variety of services. You can let that have access to your entire GitHub. Org or you can actually limit it to specific repos as well, which is nice. The team that are responsible for your GitHub organization might be happy with that. It does have the kind of load a secret into an environment variable functionality like you'd get with Fargate and ecs which is fantastic. So you can specify Secrets Manager secret and thankfully also SSM Parameter store parameters can be loaded dynamically as well. So there's a couple of services now where they'll try and strong arm you into using Secrets Manager to get that 40 cent per month. So great to see parameter store as a first class citizen there. And it is just a great pattern for loading secrets, you know, at runtime into a containerized app. It has a concept called instance role which is exactly like EC2 instance profile or an ECS task role. So credentials temporary credentials that the container will assume at runtime. So again you can give it granular IAM policies which is fantastic. It has WAF integration which is great. And then from a I guess operational point of view does seem to have really good terraform coverage as well. So you know, let's put some governance and opinionated tooling around the pattern. It's not just a click ops click buttons in the console to get easy containers solution like if. If it fits your use case and you want to lean into App Runner, it does look like there's ways to build it into like an existing robust software development life cycle around infrastructure. You don't have to use the ClickOps escape hatch which is great. One question I wanted to ask you Luciano, is you mentioned background jobs. You know it's very typical if you have a web app you might have some sort of utils instance or you want to have a runner or something that consumes messages from a queue. In this kind of app runner, you know, web app paradigm, how do you run background tasks or kind of ad hoc tasks that are not HTTP requests?
A
I guess yeah, that's a great question, because I think it's very common. For instance, I don't know if you use something like Laravel or Ruby Rails, like all this kind of NVC monolithic web frameworks. I think at least all the ones I've seen, they have a concept of background tasks. So make it easy for you to keep the responses to the users very fast. But then whenever you need to do something that is not necessarily correlated to the response you want to give to the user, like, I don't know, sign up a user to a newsletter, send an email, that kind of stuff, you probably want to schedule a background task, reply to the user, okay, as soon as possible, and then in the background process that particular request. And yeah, as I said, many frameworks have all of that machinery built in, so I think it's common for people to just use this kind of functionality. But I think when you go to App Runner, there is a little bit of a caveat that you need to keep in mind because considering the idea that your instance can be frozen at some point you might end up in a situation if you have an application with very low sparse traffic, then maybe a user comes in, makes a request, something goes in the queue, nothing happens for a while. So effectively everything is frozen and that background task never has a chance to run until maybe in a few days another request comes in, everything is woken up, and then effectively the CPU has time also to deal with the background task. So this is something to be, I think, aware that probably not ideal to use this kind of characteristics from web framework when you're using App Runner, especially if you have very low traffic, like if you have very frequent traffic, probably it's not something you're going to notice, but just be aware that you have very sparse traffic. You might end up in a situation where your background does just get frozen and delayed indefinitely or at least correlated to your web traffic patterns. So I would say that an easier approach is just since you are in AWS, leverage event services like EventBridge and Lambda. This is actually how we solved it. For this specific application we had a concept of background jobs, specifically for newsletter and sending emails. And then there were some monthly reports just to collect some statistics, create some reports and send them by email. So all of that stuff now is literally just there is EventBridge. So whenever the app needs to schedule something, it creates an event and then Lambda captures that event, will process it, totally decoupled from the main application and then whenever the job is done, of course, yeah, there are mechanisms to notify that to the application if the application needs to know about that job being completed. So this is something I think was worth mentioning because it wasn't very obvious at first. It's something that we realized in due course and we didn't expect to to have to do some rework on the application to kind of adjust for this particular use case.
B
Something similar, I guess just to put you on the spot, you mentioned Laravel or Rails. Very common to run database migrations or something on a single host during deployment. There is App Runner YAML which people might be familiar with codebuild YAML and similar files and there's different phases and stuff. Is there some sort of lifecycle hooks or something where you can run code that you want to happen once, I guess as part of an app Runner deploy?
A
That's a very good question as well. Not that I'm aware, like I couldn't see anything like that. We do use migrations for this particular application. I think the advantage there is that this particular migration system will put a lock on the database. So effectively whichever instance starts the migration first will have precedence. And then all the other ones would be like, okay, this is a knob, so it kind of works, no problem. But I remember this was an old laravel application, so I don't know if this is something that they solved now in Laravel itself that this locking mechanism wasn't there. So this approach wouldn't have worked there because effectively you could have two containers starting at the same time and they would both crash because they are conflicting on running the migrations. So I guess something to be aware in the past this is also something we solved with lambda by creating custom resources that would run before a new deployment. And effectively all the migration logic is in the custom resource. Which could be a bit annoying when you're using a monolithic framework because effectively you are suddenly removing all that code, which is generally very nice abstracted in those framework and you have to put it in a lambda and it's not always straightforward to do all of that. So yeah, this might be another point where you might find a little bit of friction just because of the running model. But I think in general when you take frameworks like Laravel or I don't know, Ruby Rails, very hardly, they are built with their level of scalability in mind. It's more like it's going to run in a big VPs and then everyone is up. So this is at least My experience with those kind of frameworks, the serverful approach. Okay, so should we try to do a final analysis? I'm going to try to say what I liked and what I didn't like.
B
Let's do it. What's the good, the bad and the ugly?
A
Exactly. So I think my opinion, and feel free to disagree with me, is that it's really nice that you don't have to worry about managing lots of stuff. You made a very comprehensive list. Networking, load balancers. I'm not going to repeat all of that. But like, you have a path that is almost like the good old times of Heroku, modern times, probably fly IO or railway. I think it's a very similar experience. It's like, I don't want to know anything or almost anything about infrastructure. I want to focus on an app, building an app and then just throw it over the wall. Aws. This is my repo. Go figure it out. I think this is a very appealing proposition for most people, and I think this is a common struggle that a lot of people that are starting with AWS would somehow describe as, yes, I just wanted to deploy this one app and then I spent the next two years learning aws. Right? So I think I felt that myself a few years ago. And I know that a lot of people are feeling this kind of stress of I thought this was simpler and then suddenly I need to take a PhD in AWS to do the most basic thing. I think with services like App Runner, this is going to be less and less the case. So I think this is very welcome in my opinion. Also, if you know Fargate, this is another simplification from Fargate. I think knowing Fargate is absolutely a great skill, but sometimes you just want something simpler. So this can be another option. Another thing that I noticed, and this is probably due to. Actually, I'm not really sure what is the main reason for this, but I had the impression, and I don't have like hard evidence or benchmarks, but I had the impression that doing a deployment is generally much faster than my experience in deploying web applications on Fargate. So again, it might just be due to my bad configuration in Gate, but I had a feeling that, yeah, App Runner is like you can literally deploy a new version in seconds or maybe a minute, rather than having to wait for 10 minutes for all the health checks and everything to stabilize. And also the idea of auto scaling configurations is pretty cool. I don't know if we mentioned this, but we mentioned the parameters, what you can do. You can actually create multiple Configurations, So you could have, I don't know, a Christmas event configuration for when you expect a lot of traffic, and then you can just turn it on and off for specific deployments. So you are not limited to one configuration. You can create sets of different scalability properties, if we want to call it like that, or configurations, and then you can assign them to every deployment. So I think that's a nice thing for those kind of applications that can be very seasonal and maybe you want to be ready for when the season starts. You're just going to flip the switch, change the configuration group, and that's already prepared. You don't have to do the maths again or think about, okay, how many containers do we need? Now you prepare all of this configuration upfront and then you can just use.
B
Yeah, it's interesting too that they went with that requests model, right? Instead of the classic, you know, aggregate CPU usage across a fleet of instances, which is kind of hard to reason about with this, it seems like you can be like, oh, you know, we expect this many requests per second on Black Friday, because that's what we had last year. And it's a bit easier to reason about the level of load, maybe, and your scaling.
A
Yeah, pretty much. And I also think that in general, you could easily benchmark your own, like one instance of a container and see how many requests it can handle with a similar kind of VCPU memory model as well. Maybe you just run it as a container locally with constrained access to the actual resources of the host machine, and you see, okay, it can handle, I don't know, reasonably well, 100 requests per second. That can be your number. I think it's much easier to think about scalability that way, rather than trying to predict how much CPU means. I don't know, now you need another instance or something like that. Especially, I think, because that lots of. For instance, this Rust application uses an Async Async framework, so it's very efficient in dealing with requests. So I was actually a bit disappointed. This is, I think, my first bad note that the maximum is 200, because my benchmark shows that it can easily handle much more than that with one container. But AWS is forcing me to have that as a maximum bound. So if suddenly I have, I don't know, 400 requests per second, it's going to scale it, even though it doesn't really need to scale, because one container could deal with that just fine.
B
So this is the opposite. You should rewrite it in Python instead of Rust.
A
Exactly.
B
Getting more CPU cycles per Container.
A
Exactly. Yeah. One reason not to use Rust. Okay, so the other thing that I was a little bit disappointed, probably a little bit more than just a little bit, was significantly disappointed with this, is that. So I was using CDK for all the infrastructure as code and the support is pretty bad. And this is probably an understatement. So you only have CFN resources. So the level, the basic level of resources, so it maps exactly what you have in Cloudformation, there is no simplification whatsoever. Is like, okay, you need to be extremely explicit, which is a bit annoying. But it's not just that, it's that some features are not even exposed in Cloudformation itself. So of course they are not even in cdk. And this is the case, for instance, if you want to associate a custom domain to your application, all of that stuff is not exposed in cloudformation. So you need to. It exists in the ui, in the web UI and in the cli. So of course, the usual thing there is that you create your own custom resource and you kind of solve the problem yourself. And there is actually a very nice article that shows you how you can do custom resource using cloudformation and Python. It's written by Mark Van Olsten, the CTO of Xibia. So we'll have a link in the show notes if you want to do something like that. I kind of copied that and then did it myself. And it was still, I think, more than 200 lines of code that I would have loved to avoid. So please, AWS fix this, because I think anyone reasonably is going to need to have a custom domain if it's like a public web application. And I would say, hopefully everyone is doing infrastructure as code. So if you are in those two buckets, it's like, yeah, then you have a problem that requires a lot more code than it should. Then the other problem is that if your custom domain is actually an Apex domain. So let's say that you have example.com and you want to expose the application on example.com that means that you need to create an alias record that points to the specific app runner domain. I don't know if it's the right terminology, but the fact that you need to create an alias record, and if you ever used alias records, there is this concept that you have predefined targets. So there are AWS services that can be a target of an alias record. An app runner is one of those. But yet again, this is not exposed in the CDK cloudformation level. So there is a workaround as well and we'll have a link in the show. Notes I'm not going to explain exactly how this alias Route 53 mechanism works. Maybe this is a topic for an entire other episode if people are curious. But effectively if you know certain configuration parameters and will point you to the documentation, you can recreate this functionality yourself. But again, I found myself writing probably other 30 lines of code that I didn't want to write. It was interesting to learn a little bit more about how this alias Mechanism works in Route 53. It's not magic at the end of the day, but it is just painful that you have to go through all of this extra research and code just to be able to use an Apex domain for your application. And in general I think the pain was everywhere in the docs. I think all the docs are not bad, but they are only geared towards people that want to click ops the whole application. I think thataspheres is actually quite well done, but if you are a cloud practitioner again don't do that. Please use infrastructure as code and aws. Please support people more to be able to use infrastructure as code. And yeah, then there are other nitpicks that can be easily improved by aws. For instance, your log groups, they are created automatically, but they are endless and there is one log group for every deployment. So if you are iterating very quickly on your application, I think suddenly you'll have hundreds and hundreds of log groups and you'll end up paying some significant amount of money. So to be fair, this is similar to what happens by default in Lambda, but at least in Lambda with CDK they made it somewhat easier to configure this parameter. So hopefully they can do something similar for App Runner as well. And yeah, I think in general all these problems are not showstoppers. It's just I think the whole experience can be much nicer if AWS improved it. My general worry is that while I was bumping into all these issues I found posts that were like three years old where people already complained about these issues and they are still open. So I'm just a little bit concerned questioning what is the level of investment for AWS on this service? Is it just something that they tried but they are not necessarily fully committed to it? Or maybe, I don't know, eventually they would decide to invest more and improve all these rough edges. So I hope the case is the latter because I think in general I like the service. I just hope it doesn't become another AWS abandonware service where yes, eventually you figure out all the rough edges and you have your copy paste solutions for all of those. But it's just not the nice experience that I wish we could have as cloud practitioners and users of aws.
B
I look forward to the blog post migrating your AWS App runner apps to ECS Fargate that will be published in 2029.
A
Yeah, hopefully that's not the case. Maybe we'll have more of the opposite use cases, I don't know. Yeah. And finally it would be nice if it did scale to zero because Google Cloud Run, that's the name I was not remembering before. Everyone is saying I didn't use it myself so I cannot speak to it, but everyone is saying it's like very similar type of user experience, plus generally much cheaper and simpler because automatically scales to zero. You don't even have to configure it. So it would be nice to have something like that. Now, should we try to summarize why we would prefer App Runner to Fargate or the other way around?
B
It depends, right? Are we allowed to say that on.
A
The podcast as consultants? We are.
B
I think it depends. Yeah, I guess, yeah. If you're looking for that batteries included option, App Runner really does seem like a no brainer. I took it for a quick spin earlier today and you can get from GitHub repo with docker file to running web app in minutes, literally. So it's fantastic for that. I think it'll be great for teams that maybe have a lot of prototypes or they want to deploy feature branches to hosted containers. The fact that you can get that kind of $5 per month price point for mostly stopped apps that you interact with infrequently, I think it's going to be great for that kind of use case. And yeah, maybe it will become the go to for your initial, you know, it'll jump to the top of the list maybe in terms of what tool should I consider for hosting my container? And then you maybe if you start hitting a lot of rough edges, then it's time to look at Fargate. So maybe just slot it into kind of that existing hierarchy maybe that every practitioner has, where maybe you're like trying to minimize the amount of effort or inference. You might be like, can I do it in a step function? No. Okay. Can I do it in lambda? No. Okay. Can I do it in App Runner? Can I do it in Fargate? So I feel like App Runner is just going to slot into that decision tree that we all have. But yeah, for me it's definitely a service that is worth look and it's definitely something I'll be playing around with and looking at terraform coverage and hoping to use it a little more. What about you?
A
Yeah, I'm curious to hear your feedback on the terraform coverage I hope is better than the CDK cloudformation one. So yeah, please let me know about that. Yeah, I think the only thing I'd like to add is that pricing. It's an interesting one because I think it can. It could go either way when you compare it with Fargate because I think the fact that you are not paying for a load balancer for example, could make it much cheaper just because you don't have those 30 bucks fixed per month. But at the same time I think there is a premium on the cost of memory and cpu. So I think if you're really doing an intensive use case like you're running dozens of instances of your containers probably I think there is a point where app run sorry when Fargate becomes cheaper than App Runner. So I don't really have hard data so this is just an assumption for now. So feel free to experiment with cost calculator or your own spreadsheet and figure it out exactly if the pricing will work for you or not depending on whatever are your metrics. So I think that brings us to the end of this episode and sorry, this was a little bit of a longer one but hopefully you found value on it and hopefully you are now curious to use App Runner, give it a spin and maybe you find out that it's easier and better than Fargate for your own use cases. Or maybe not. Definitely let us know. We are really curious as always, we want to know what are you using for your own little tests, but more importantly what are you using in production and why? So please share your stories because this is how we all get better by sharing our stories with each other, lessons learned and so on. Now before we go, a big thanks to our sponsor. So thank you for Theorem for powering yet another episode of AWS Bytes. At fortiorm we believe that servers should be simple, scalable and cost effective and we help teams to just do that. So whether you are diving into containers, stepping into event driven architecture, or scaling a global SaaS platform to AWS, our team is there to help you. So visit forthereum.com to see how we can help you to build faster, better and with more confidence on aws. Thank you very much and we'll see you in the next one.
May 8, 2025 | Hosts: Luciano Mammino & Conor
In this episode, Luciano and Conor explore the real-world differences between AWS App Runner and ECS Fargate for containerized web application hosting. Drawing from a recent migration project and hands-on experimentation, they discuss where App Runner shines, where it falls short, and offer practical insights for AWS developers seeking simplicity or flexibility in container management. The episode is rich with candid assessments, technical deep-dives, and no-nonsense advice for choosing the right service for your workload.
"What if there was a service that just took your code or your container...deployed it, scaled it, and just gave you a URL...and at that point you are just done. That's actually the promise of a service called AWS App Runner. And in this episode we are putting that promise to test."
— Luciano [00:42]
[02:04–04:06] Conor gives an overview: App Runner, launched mid-2021, aims to let developers run web apps and APIs without the operational overhead of Fargate or ECS. Targets "throw your container over the wall" simplicity. Handles build, deploy, HTTPS, scaling, etc., and abstracts VPC, ALBs, etc.
App Runner is primarily for HTTP workloads and promises a simple path from code/Dockerfile to live app.
Notable Quote:
"[App Runner] removes a lot of complexity...Apparently we can throw a container over the wall and make it AWS's problem. That's the dream."
— Conor [02:55]
"It's very easy to forget the level of moving parts involved in Fargate just for a pretty straightforward web app."
— Conor [07:02]
"I think for most serious use cases, you still need to understand a little bit of networking and make sure you understand how to connect App Runner to your own VPC."
— Luciano [16:37]
"I was actually a bit disappointed...the maximum is 200, because my benchmark shows that it can easily handle much more than that with one container. But AWS is forcing me to have that as a maximum."
— Luciano [31:18]
"[W]e didn't expect to...have to do some rework on the application to kind of adjust for this particular use case."
— Luciano [25:23]
[27:45–37:27]
The Good
The Bad/Ugly
Notable Quote:
"My general worry is that...I found posts that were like three years old where people already complained about these issues and they are still open. So I'm just a little bit concerned...what is the level of investment for AWS on this service?"
— Luciano [36:41]
Humor:
"I look forward to the blog post 'Migrating your AWS App Runner apps to ECS Fargate' that will be published in 2029."
— Conor [37:27]
| Segment | Timestamps | Speakers | |-----------------------------------------------|--------------|---------------| | App Context & Problem Setup | 00:00–04:06 | Luciano | | What is App Runner? | 02:04–04:06 | Conor | | App Runner vs Fargate (Complexity) | 06:11–08:52 | Conor | | App Runner Pricing Model | 08:52–14:07 | Luciano | | Networking Intricacies | 14:07–16:40 | Both | | App Runner Auto-scaling & Config | 16:58–20:00 | Both | | Security, GitHub, Secrets, IaC | 20:00–22:48 | Conor | | Background Jobs, Migrations, Lifecycle | 22:48–27:45 | Both | | Good, Bad, and Ugly (Summary) | 27:45–37:27 | Both | | Final Analysis: Which to Choose & When | 38:15–End | Both |
Both hosts encourage listeners to experiment with App Runner, share stories, and contribute to improvement by voicing feedback. While App Runner isn’t perfect — notably around infrastructure as code and advanced use cases — for many developer-centric scenarios, it dramatically lowers the AWS learning curve and “just works” feeling.
Links promised in the show (not listed here):
Sponsor shout-out:
Thanks to FourTheorem for supporting this episode and helping teams build simple, scalable, cost-effective serverless solutions on AWS.
End of summary.