App Runner is an AWS service released on the 18th of May 2021 that allows you to directly run your code or containerized applications. It automatically builds, deploys applications, and distributes traffic with encryption.
App Runner can scale up or down automatically to meet your traffic needs.
Thanks to this new service, we can focus on code only without worrying about scaling or infrastructure.
Its principal use cases are web applications and APIs. App Runner is like Heroku, Digital Ocean app platform, or Google Cloud Run.
To be able to deploy an App Runner instance, we need:
As the name implies, AWS pulls code from GitHub and builds the application on every change in this mode.
Triggers:
⚠ Only Python and Node.js are supported in build mode!️
This mode consists of deploying docker images from private or public AWS ECR registries (only!).
Triggers:
We'll create a simple hello world python application using Flask.
First, let's create a hello.py
file:
from logging import debug
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "<Hello World!>"
Then, creates a requirements.txt
file:
flask==2.0.1
Finally, creates the Dockerfile
file:
FROM python:3.9-alpine
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
ENV FLASK_APP=hello
ENV FLASK_RUN_HOST=0.0.0.0
ENV FLASK_RUN_PORT=8080
EXPOSE 8080
ENTRYPOINT [ "flask", "run" ]
I also got used to creating a .dockerignore
file containing at least:
Dockerfile
copilot/
In this way, on build, the Dockerfile
file and the future copilot directory will not be uploaded to the docker image.
Ok, we're now ready to run something unique 🚀
It's time to run our fantastic HelloWorld application! 🤩
Since AWS Console is user-friendly enough, we'll cover the copilot CLI method.
Copilot uses CloudFormation to provision and manage AWS resources as its backend.
An ECR, or Elastic Container Registry, is an AWS-managed container image registry service. An ECR is a place in which we will store our Docker images.
If you plan to use container mode, you'll need to create an ECR and push your docker image into it.
To create an ECR using the CLI, log in to AWS:
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account_id>.dkr.ecr.<region>.amazonaws.com
Then, create the repository:
aws ecr create-repository \
--repository-name hello/web \
--image-scanning-configuration scanOnPush=true \
--region <region>
Where:
Now, you need to build your application. From your application's directory:
docker build -t hello-python .
Finally, tag and push your image to your ECR:
docker tag hello-python <account_id>.dkr.ecr.<region>.amazonaws.com/hello:latest
docker push <account_id>.dkr.ecr.<region>.amazonaws.com/hello:latest
After this, you can continue by reading the Build mode section 😉
The first thing to do is to create the application and its service endpoint:
copilot init \
--type "Request-Driven Web Service" \
--app hello \
--name web \
--port 8080 \
--dockerfile Dockerfile
--type
is the architecture of the service that we want to run. In this example, we want to run a Request-Driven Web Service, an internet-facing service deployed on AWS App Runner.--app
is the application's name--name
is the service's name--port
is the port exposed in our Dockerfile--dockerfile
is the place where is our application's DockerfileFor container mode, use --image "<account_id>.dkr.ecr..amazonaws.com/hello/web:latest"
instead of --dockerfile Dockerfile
The init step will:
copilot/web/manifest.yml
In the end, copilot should ask you to create a "test" environment. You can skip this step for now.
Now, we need to create a "production" environment. To do so:
copilot env init --profile default --name production --default-config --app hello --prod
--profile
is your credential's profile to use for deploying the application (~/.aws/credentials)--name
is the environment's name--default-config
skip prompting and use default environment configuration--app
is the application's name--prod
indicate that the environment contains production servicesThis environment creation step will:
If everything goes well, you should see something like this:
We can now deploy our application with this last step
copilot svc deploy --app hello --env production --name web
Here we are! 🚀
Finally, try accessing your application by accessing the URL provided by copilot:
Our application is now running, it's lovely! But how can we automate its deployment on code updates?
Well, there is some approach to do this, among them:
Alright, let's use copilot and AWS CodePipeline!
Generate the pipeline's configuration files:
ccopilot pipeline init \
--url https://github.com/<username>/<repository>.git \
--environments "production"
The previous command will generate the following configuration files in your copilot directory:
buildspec.yml
pipeline.yml
Now, create the pipeline in CodePipeline in your AWS account:
copilot pipeline update
Copilot should ask you to do some manual actions:
✔ Successfully added pipeline resources to your application: hello
⠋ Creating a new pipeline: pipeline-hello-apprunner-python-exemple
ACTION REQUIRED! Go to https://console.aws.amazon.com/codesuite/settings/connections to update the status of connection copilot-Julie-apprunner-python-e from PENDING to AVAILABLE.
From the AWS Console, open the CodeSuite connections and click on the freshly created connection.
Then, click on Update pending connection. It will pop out a window asking you to authorize AWS connector to access your Github account:
Click on Install a new app and then select your account and repository. Finally, click Install.
Now, AWS should let you connect:
Get back to your terminal; the pipeline update process must be done:
Try adding a file to your repository, or edit an existing one:
~$ echo "# Hello World" > README.md
~$ git add .
~$ git commit -m "feat(README.md): add readme file"
~$ git push -u origin main
From the CodePipeline section of the AWS Console, you can see the whole process running:
By default, CodePipeline will ask for your approval to go live. Just click on Review and then Approve. You're done, congrats! 🚀
App Runner is a pretty cool product, but I think it is currently not mature enough to be production-ready. The fact that an App Runner instance cannot connect with resources from inside a VPC (RDS, for example) or that we cannot use AWS Secret Manager is quite limiting IMO.
It is not shocking that App Runner is not production-ready since it was released four months before writing this article.
I listed below some good and "bad" points.
In any case, I think App Runner is nonetheless an excellent companion for carrying out PoCs.
I want to share with you a few links which are helpful to follow: