~/post/fastapi-app-with-apprunner
Published on

How to deploy your next FastAPI app on AWS with AppRunner in less than 5 minutes?

7 mins read
Authors
  • Name
    Twitter

In May 2021, AWS announced the General Availability of its service AWS App Runner, described as "the simplest way to build and run a containerized web application in AWS". At that time, the service was extremely limited (no support for VPC connectivity) and only a few runtimes were supported.

02 years later, the service has evolved and now supports many features.

In this article, you will see what AppRunner is and how it can help you to deploy FastAPI web apps in a couple of minutes.

Table of Contents

Why AppRunner?

When it comes to deploying a web application on AWS, you have several ways, depending on the application’s requirements, team capabilities, budget and various constraints.

However, regardless of the deployment method chosen, there are some mandatory configurations that need to be in place to ensure the application is highly available.

This typically falls under the responsibility of the operations team (ops), who must set up:

  • Load balancing
  • Target groups
  • Scaling
  • Security groups
  • Domains
  • Certificates
  • Observability (monitoring, logging, metrics)
  • And more.

Despite this complexity, developers simply want to deploy their application and focus on its development. This observation led AWS to offer a fully managed service to simplify the deployment of applications: AppRunner.

Definition

The official page states “AWS App Runner is a fully managed container application service that lets you build, deploy, and run containerized web applications and API services without prior infrastructure or container experience”.

At this moment, you are probably wondering if AppRunner is a:

  • Platform as a Service (PaaS)?
  • Container as a Service (CaaS)?
  • New Serverless Service?
  • Managed Service
  • or All at once?

Let’s try to understand how the service operates. This will probably help us to respond to the question.

Modes of Operation

Under the hood, AppRunner creates an ECS cluster and uses Fargate to effortlessly run your containers, saving you time and effort.

While some may argue that sacrificing granularity is a compromise, the benefits of simplicity and speed are undeniable. With built-in continuous integration and integration with CloudWatch for logs and monitoring, App Runner eliminates the need for additional third-party services.

Streamline your container management with App Runner and focus on what matters most – your business!

AppRunner Architecture

When it comes to configuring App Runner, you have two options to choose from – manual and automatic.

The manual mode is ideal for those who prefer to have more control over the configuration process. With this mode, you can configure your application's environment variables, networking, and other settings using the AWS Management Console or CLI.

On the other hand, the automatic mode is interesting for those who prefer a more hands-off approach. With this mode, App Runner automatically loads your application configuration from its source code allowing you to focus on other aspects of your project.

In addition to the modes of configuration, App Runner offers two modes of operation – Container Mode and Build Mode.

Container Mode is recommended for running pre-built containers from a container registry, such as Amazon ECR or Docker Hub. With this mode, you can quickly deploy and scale your application without worrying about the underlying infrastructure.

The Build Mode is perfect for building and deploying applications from source code. With this mode, App Runner automatically builds your application from your source code, dependencies, and build instructions, making it easy to deploy and manage your applications.

Whether you prefer to use pre-built containers or build your applications from source code, App Runner offers flexible options to meet your needs.

App Runner in Action

Now that we have a complete overview of the service, let’s practice using build and automatic modes.

In a previous article, I set up a basic python api with FastAPI Framework. I will reuse the code for the rest of this article.

import fastapi, uvicorn
from starlette.requests import Request
import prometheus_client
import os

api = fastapi.FastAPI()

...

if __name__ == "__main__":
    print("Starting webserver...")
    uvicorn.run(
        api,
        host="0.0.0.0",
        port=int(os.getenv("PORT", 8080)),
        debug=os.getenv("DEBUG", False),
        log_level=os.getenv('LOG_LEVEL', "info"),
        proxy_headers=True
    )

The AWS Console provides all you need for the deployment. You should see a page like this:

AppRunner Getting Started

Click on Create an App Runner Service button, you have now this:

AppRunner Creation Page

For the while, AppRunner supports only Github as Source code repository. So, click on the Add new button to add a new repository.

A new window is opened. Set a name for your connection and click on the Install button.

AppRunner Connection

Indeed, AWS will install the Github connect and you will be able to select the repository and the branch you want to deploy. The connection could be reused for all your other services.

Don’t forget to check the repositories the AWS Connector has access to.

AppRunner Integration

At this step, you should have all your fields filled in as follows:

AppRunner Service

On the Next Page, it’s time to configure your build settings.

Add the configuration file apprunner.yaml at the root of your project with the following content:

version: 1.0 # version of the specification
runtime: python3 # runtime to use
build:
  commands:
    build:
      - pip install -r requirements.txt # install dependencies

  env: # define environment variables
    - name: PORT
      value: '8080'

run:
  command: python app.py # command to run fastapi
  network:
    port: 8080 # port AppRunner will expose

On the Next Page, you can enable various options to make stand out your service:

  • Auto Scaling: Define the scaling behaviour for you service by setting the number of requests, concurrency, etc.

  • Health Check: Configure the health checks that the load balancer performs on your App Runner service instances (the path to request, the number of consecutive health check failures, etc.). The health check path of our service is /ping.

  • Security: A custom instance role to call AWS services.

  • Networking: Public, private endpoints, custom VPC, etc.

  • Observability: Tracing with AWS X-Ray.

The last page is the Review and create Page. You will be able check your settings one last time before the deployment. If everything is good, click on the Create and deploy  button, which will trigger the deployment process:

AppRunner Deployment

It will take a couple of minutes for AppRunner to deploy your application. After that, the status turns into Running and a message indicates that your application is running.

AppRunner Running

By default, a random URL is assigned to your service. Feel free to associate your custom DNS record (CNAME).

Congratulations, You nailed it!

Testing the continuous deployment

In automatic mode, every push on your repository will trigger the deployment of your service. Let’s test it!

Open the app.py file and add the following code:

...

@api.get('/hello')
def hello(request: Request):
    REQUESTS.labels(endpoint='/hello').inc()
    return "Hello World!"
...

Commit your changes and push them.

If you go back to your AWS Console, you should see the status of your service status transitioning from running to Operation in progress. This indicates the detection of changes and a redeployment in progress.

AppRunner CICD

A few minutes later, your application should be running again and the new endpoint should now be available:

AppRunner Hello

Awesome! our automatic deployment is fully operational.

If you prefer command line, feel free to check out the AWS CLI Docs page.

Conclusion

To sum up, AWS AppRunner is definitely THE service you should consider to deploy your next FastAPI service quickly and efficiently. It’s developer-centric and easy to set up.

A lot of effort of integration with the AWS Ecosystem has been done these last months and the service is now production-ready for most of use cases. Just enjoy!