How to deploy a Hello World web app with Elastic Observability on AWS App Runner

library-branding-elastic-observability-white-1680x980.png

Elastic Observability is the premiere tool to provide visibility into web apps running in your environment. AWS App Runner is the serverless platform of choice to run your web apps that need to scale up and down massively to meet demand or minimize costs. Elastic Observability combined with AWS App Runner is the perfect solution for developers to deploy web apps that are auto-scaled with fully observable operations, in a way that’s straightforward to implement and manage. 

This blog post will show you how to deploy a simple Hello World web app to App Runner and then walk you through the steps to instrument the Hello World web app to enable observation of the application’s operations with Elastic Cloud.

Elastic Observability setup

We’ll start with setting up an Elastic Cloud deployment, which is where observability will take place for the web app we’ll be deploying.

From the Elastic Cloud console, select Create deployment.

1 create deployment

Enter a deployment name and click Create deployment. It takes a few minutes for your deployment to be created. While waiting, you are prompted to save the admin credentials for your deployment, which provides you with superuser access to your Elastic® deployment. Keep these credentials safe as they are shown only once.

Elastic Observability requires an APM Server URL and an APM Secret token for an app to send observability data to Elastic Cloud. Once the deployment is created, we’ll copy the Elastic Observability server URL and secret token and store them somewhere safely for adding to our web app code in a later step.

To copy the APM Server URL and the APM Secret Token, go to Elastic Cloud. Then go to the Deployments page, which lists all of the deployments you have created. Select the deployment you want to use, which will open the deployment details page. In the Kibana® row of links, click on Open to open Kibana for your deployment.

2 my deployment

Select Integrations from the top-level menu. Then click the APM tile.

3 apm

On the APM Agents page, copy the secretToken and the serverUrl values and save them for use in a later step.

4 apm agents

Now that we’ve completed the Elastic Cloud setup, the next step is to set up our AWS project for deploying apps to App Runner.

AWS App Runner setup

To start using AWS App Runner, you need an AWS account. If you’re a brand new user, go to aws.amazon.com to sign up for a new account.

5 start building on aws today

Set up AWS CloudShell

We’ll perform the process of creating a Python Hello World App image and pushing it to the AWS ECR using AWS CloudShell.

We’re going to use Docker to build the sample app image. Perform the following five steps to set up Docker within CloudShell.

1. Open AWS CloudShell.

6 welcome to aws cloudshell
7 aws cloudshell

2. Run the following two commands to install Docker in CloudShell:

sudo yum update -y
sudo amazon-linux-extras install docker

3. Start Docker by running the command:

sudo dockerd

4. With Docker running, open a new tab in CloudShell by clicking the Actions dropdown menu and selecting New tab.

8 aws cloudshell with code

5. Run the following command to authenticate Docker within CloudShell. Replace <account_id> with your AWS Account ID in the Docker command below, and then run it in CloudShell.

aws ecr get-login-password --region us-east-2 | sudo docker login --username AWS --password-stdin <account_id>.dkr.ecr.us-east-2.amazonaws.com

Build the Hello World web app image and push it to AWS ECR

We’ll be using AWS ECR, Amazon’s fully managed container registry for storing and deploying application images. To build and push the Hello World app image to AWS ECR, we’ll perform the following six steps in AWS CloudShell:

1. Run the command below in CloudShell to create a repository in AWS ECR.

aws ecr create-repository \
    --repository-name elastic-helloworld/web \
    --image-scanning-configuration scanOnPush=true \
    --region us-east-2

“elastic-helloworld” will be the application's name and “web” will be the service name.

2. In the newly created tab within CloudShell, clone a Python Hello World sample app repo from GitHub by entering the following command.

git clone https://github.com/elastic/observability-examples

3. Change directory to the location of the Hello World web app code by running the following command:

cd observability-examples/aws/app-runner/helloworld

4. Build the Hello World sample app from the application’s directory. Run the following Docker command in CloudShell.

sudo docker build -t elastic-helloworld/web .

5. Tag the application image. Replace <account_id> with your AWS Account ID in the Docker command below, and then run it in CloudShell.

sudo docker tag elastic-helloworld/web:latest <account_id>.dkr.ecr.us-east-2.amazonaws.com/elastic-helloworld/web:latest

6. Push the application image to ECR. Replace <account_id> with your AWS Account ID in the command below, and then run it in CloudShell.

sudo docker push <account_id>.dkr.ecr.us-east-2.amazonaws.com/elastic-helloworld/web:latest

Deploy a Hello World web app to AWS App Runner

We’ll perform the process of deploying a Python Hello World App to App Runner using the AWS App Runner console.

1. Open the App Runner console and click the Create an App Runner service button.

9 aws app runner

2. On the Source and deployment page, set the following deployment details:

  • In the Source section, for Repository type, choose Container registry.
  • For Provider, choose Amazon ECR.
  • For Container image URI, choose Browse to select the Hello World application image that we previously pushed to AWS ECR.
    • In the Select Amazon ECR container image dialog box, for Image repository, select the “elastic-helloworld/web” repository.
    • For Image tag, select “latest” and then choose Continue.
  • In the Deployment settings section, choose Automatic.
  • For ECR access role, choose Create new service role.
  • Click Next.
10 source and deployment

3. On the Configure service page, in the Service settings section, enter the service name “helloworld-app.” Leave all the other settings as they are and click Next.

11 configure service

4. On the Review and create page, click Create & deploy.

12 review and create

After a few minutes, the Hello World app will be deployed to App Runner. 

13 hello world app green text

5. Click the Default domain URL to view the Hello World app running in App Runner.

14 hello world

Instrument the Hello World web app with Elastic Observability

With a web app successfully running in App Runner, we’re now ready to add the minimal code necessary to start monitoring the app. To enable observability for the Hello World app in Elastic Cloud, we’ll perform the following five steps in AWS CloudShell:

1. Edit the Dockerfile file to add the following Elastic Open Telemetry environment variables along with the commands to install and run the Elastic APM agent. Use the “nano” text editor by typing “nano Dockerfile”. Be sure to replace the <ELASTIC_APM_SERVER_URL> text and the <ELASTIC_APM_SECRET_TOKEN> text with the APM Server URL and the APM Secret Token values that you copied and saved in an earlier step. The updated Dockerfile should look something like this:

FROM python:3.9-slim as base

# get packages
COPY requirements.txt .
RUN pip install -r requirements.txt

WORKDIR /app

# install opentelemetry packages
RUN pip install opentelemetry-distro opentelemetry-exporter-otlp
RUN opentelemetry-bootstrap -a install

ENV OTEL_EXPORTER_OTLP_ENDPOINT='<ELASTIC_APM_SERVER_URL>'
ENV OTEL_EXPORTER_OTLP_HEADERS='Authorization=Bearer%20<ELASTIC_APM_SECRET_TOKEN>'
ENV OTEL_LOG_LEVEL=info
ENV OTEL_METRICS_EXPORTER=otlp
ENV OTEL_RESOURCE_ATTRIBUTES=service.version=1.0,deployment.environment=production
ENV OTEL_SERVICE_NAME=helloworld
ENV OTEL_TRACES_EXPORTER=otlp

COPY . .
ENV FLASK_APP=helloworld
ENV FLASK_RUN_HOST=0.0.0.0
ENV FLASK_RUN_PORT=8080
EXPOSE 8080
ENTRYPOINT [ "opentelemetry-instrument", "flask", "run" ]

Note: You can close the nano text editor and save the file by typing “Ctrl + x”. Press the “y” key and then the “Enter” key to save the changes.

2. Edit the helloworld.py file to add observability traces. In CloudShell, type “nano helloworld.py” to edit the file.

  • After the import statements at the top of the file, add the code required to initialize the Elastic Open Telemetry APM agent:
from opentelemetry import trace
tracer = trace.get_tracer("hello-world")
  • Replace the “Hello World!” output code . . .
return "<h1>Hello World!</h1>"
  • … with the Hello Elastic Observability code block.
    	return '''
    	<div style="text-align: center;">
    	<h1 style="color: #005A9E; font-family:'Verdana'">
    	Hello Elastic Observability - AWS App Runner - Python
    	</h1>
    	<img src="https://elastic-helloworld.s3.us-east-2.amazonaws.com/elastic-logo.png">
    	</div>
    	'''
  • Then add a “hi” trace before the Hello Elastic Observability code block along with an additional “@app.after_request” method placed afterward to implement a “bye” trace.
@app.route("/")
def helloworld():
	with tracer.start_as_current_span("hi") as span:
  	  logging.info("hello")
  	  return '''
   	 <div style="text-align: center;">
   	 <h1 style="color: #005A9E; font-family:'Verdana'">
   	 Hello Elastic Observability - AWS App Runner - Python
   	 </h1>
   	 <img src="https://elastic-helloworld.s3.us-east-2.amazonaws.com/elastic-logo.png">
   	 </div>
   	 '''

@app.after_request
def after_request(response):
	with tracer.start_as_current_span("bye"):
  	  logging.info("goodbye")
  	  return response

The completed helloworld.py file should look something like this:

import logging
from flask import Flask

from opentelemetry import trace
tracer = trace.get_tracer("hello-world")

app = Flask(__name__)

@app.route("/")
def helloworld():
    with tracer.start_as_current_span("hi") as span:
   	 logging.info("hello")
   	 return '''
    	<div style="text-align: center;">
    	<h1 style="color: #005A9E; font-family:'Verdana'">
    	Hello Elastic Observability - AWS App Runner - Python
    	</h1>
    	<img src="https://elastic-helloworld.s3.us-east-2.amazonaws.com/elastic-logo.png">
    	</div>
    	'''

@app.after_request
def after_request(response):
    with tracer.start_as_current_span("bye"):
   	 logging.info("goodbye")
   	 return response

Note: You can close the nano text editor and save the file by typing “Ctrl + x”. Press the “y” key and then the “Enter” key to save the changes.

3. Rebuild the updated Hello World sample app using Docker from within the application’s directory. Run the following command in CloudShell.

sudo docker build -t elastic-helloworld/web .

4. Tag the application image using Docker. Replace <account_id> with your AWS Account ID in the Docker command below and then run it in CloudShell.

sudo docker tag elastic-helloworld/web:latest <account_id>.dkr.ecr.us-east-2.amazonaws.com/elastic-helloworld/web:latest

5. Push the updated application image to ECR. Replace <account_id> with your AWS Account ID in the Docker command below and then run it in CloudShell.

sudo docker push <account_id>.dkr.ecr.us-east-2.amazonaws.com/elastic-helloworld/web:latest

Pushing the image to ECR will automatically deploy the new version of the Hello World app.

15 green banner successful deployment

Open the App Runner console. After a few minutes, the Hello World app will be deployed to App Runner. Click the Default domain URL to view the updated Hello World app running in App Runner.

16 elastic

Observe the Hello World web app

Now that we’ve instrumented the web app to send observability data to Elastic Observability, we can now use Elastic Cloud to monitor the web app’s operations.

  1. In Elastic Cloud, select the Observability Services menu item. 

  2. Click the helloworld service.

  3. Click the Transactions tab.

  4. Scroll down and click the “/” transaction.

  5. Scroll down to the Trace Sample section to see the “/,” “hi,” and “bye” trace samples.

17 trace sample

Observability made to scale

You’ve seen the complete process of deploying a web app to AWS App Runner that is instrumented with Elastic Observability. The end result is a web app that will scale up and down with usage, combined with the observability tools to monitor the web app as it serves one user or millions of users. 

Now that you’ve seen how to deploy a serverless web app instrumented with observability, visit Elastic Observability to learn more about how to implement a complete observability solution for your apps. Or visit Getting started with Elastic on AWS for more examples of how you can drive the data insights you need by combining AWS’s cloud computing services with Elastic’s search-powered platform.

The release and timing of any features or functionality described in this post remain at Elastic's sole discretion. Any features or functionality not currently available may not be delivered on time or at all.