GPT-5.2

GPT-5.2

#1 / 5 42.6s 3465
8.1

AI Evaluation

Clarity7.3
Completeness8.7
Relevance8.0
Creativity7.7

Full Response

We’re going to build a small Python Flask app and deploy it to AWS Elastic Beanstalk (EB) so it’s publicly reachable with a managed load balancer, health checks, and easy redeploys. This solves the “it runs locally, but how do I host it reliably?” problem without hand-rolling EC2 setup. Prerequisites: Python 3.12+, Git, an AWS account, IAM permissions for Elastic Beanstalk/EC2/S3, and the AWS CLI installed/configured (or AWS SSO).

SETUP: local environment, tools, and project structure

Elastic Beanstalk deployments work best when your app is packaged with a virtual environment workflow and a clear entry point. We’ll use the EB CLI to create the environment and push versions.

First, create a project folder, a virtual environment, and install dependencies.

mkdir flask-eb-demo
cd flask-eb-demo

python3.12 -m venv .venv
source .venv/bin/activate

python -m pip install --upgrade pip
pip install Flask==3.0.3 gunicorn==22.0.0

pip freeze > requirements.txt

Expected result: a requirements.txt file listing Flask and Gunicorn, and your shell prompt showing the virtual environment is active.

⚠️ Note: Elastic Beanstalk’s Python platform expects your dependencies in requirements.txt at the project root. If it’s missing or in a subfolder, deployments often “succeed” but the app fails at runtime due to missing packages.

Next, install and configure the AWS CLI and EB CLI. The EB CLI is what creates EB applications/environments and deploys versions.

# AWS CLI (macOS via Homebrew)
brew install awscli

# EB CLI
pip install awsebcli==3.20.10

# Verify
aws --version
eb --version

Expected output: version strings for both tools (for example, aws-cli/2.x and EB CLI 3.20.10).

Finally, create a minimal project structure. This layout keeps the Flask app explicit and makes the EB entry point easy to reference.

mkdir -p app
touch app/__init__.py app/web.py .gitignore
cat > .gitignore << 'EOF'
.venv/
__pycache__/
*.pyc
.DS_Store
.elasticbeanstalk/
EOF

IMPLEMENTATION: build a Flask app that’s EB-friendly

Elastic Beanstalk’s Python platform commonly runs your app behind Gunicorn, so we’ll expose a WSGI callable and keep configuration via environment variables. This avoids hardcoding secrets and matches how EB injects settings.

Create the Flask app with a health endpoint and a simple index route.

from __future__ import annotations

import os
from dataclasses import dataclass

from flask import Flask, jsonify


@dataclass(frozen=True)
class Settings:
    app_name: str
    environment: str


def load_settings() -> Settings:
    return Settings(
        app_name=os.environ.get("APP_NAME", "flask-eb-demo"),
        environment=os.environ.get("APP_ENV", "local"),
    )


def create_app() -> Flask:
    settings = load_settings()
    app = Flask(__name__)

    @app.get("/")
    def index():
        return jsonify(
            message="Hello from Flask on Elastic Beanstalk!",
            app_name=settings.app_name,
            environment=settings.environment,
        )

    @app.get("/health")
    def health():
        return jsonify(status="ok")

    return app


app = create_app()

Now add a local development runner. EB won’t use this in production, but it’s handy for local testing.

from __future__ import annotations

import os

from app.web import app

if __name__ == "__main__":
    port = int(os.environ.get("PORT", "5000"))
    app.run(host="0.0.0.0", port=port, debug=True)

Run it locally to confirm everything works before involving AWS.

source .venv/bin/activate
python app/__init__.py

Expected output: Flask logs showing it’s serving on http://127.0.0.1:5000. Visiting / should return JSON, and /health should return {"status":"ok"}.

⚠️ Note: Don’t deploy using Flask’s built-in dev server. EB expects a production WSGI server (Gunicorn). If you rely on app.run() in production, you’ll see unstable behavior under load and timeouts behind the load balancer.

IMPLEMENTATION: configure Elastic Beanstalk (Gunicorn + health checks)

Elastic Beanstalk needs to know how to launch your app. For Python, a common approach is a Procfile that starts Gunicorn and points it at your WSGI app object.

Create a Procfile at the repository root.

cat > Procfile << 'EOF'
web: gunicorn --bind 0.0.0.0:${PORT:-8000} app.web:app
EOF

Expected result: EB can start your app with Gunicorn using the port it provides via PORT.

Next, add EB platform configuration to improve health checks and ensure the load balancer uses your /health endpoint. We’ll do this via EB “option settings” in a config file.

mkdir -p .ebextensions
cat > .ebextensions/01-healthcheck.config << 'EOF'
option_settings:
  aws:elasticbeanstalk:application:
    Application Healthcheck URL: /health
EOF

Expected result: the EB console health will reflect your app’s real health endpoint instead of just “port open.”

⚠️ Note: If your health check path returns a redirect, HTML error page, or requires auth, EB may mark instances unhealthy and continuously replace them. Keep /health fast and unauthenticated.

Initialize Elastic Beanstalk in your project. Choose a Python platform (Python 3.12 if available in your region) and create an environment with a load balancer.

# Authenticate AWS CLI first (choose one approach)

# Option A: static credentials (not recommended long-term)
# aws configure

# Option B: AWS SSO (recommended if your org supports it)
# aws configure sso

# Initialize EB (interactive)
eb init -p python-3.12 flask-eb-demo

During eb init, select your AWS region and set up SSH only if you expect to log into instances for debugging.

Create an environment. “LoadBalanced” gives you an Application Load Balancer and multiple-instance capability later.

eb create flask-eb-demo-prod --elb-type application --instance_type t3.micro

Expected result: after several minutes, EB outputs a public URL like http://flask-eb-demo-prod.XXXXXXXX.us-east-1.elasticbeanstalk.com.

⚠️ Note: If your account is new, you may hit VPC/subnet or EC2 quota errors during environment creation. Check the EB Events tab in the AWS console; it usually spells out the missing permission/quota.

Set environment variables in EB so your app reports the correct environment and name. This also demonstrates how to manage config without code changes.

eb setenv APP_ENV=production APP_NAME=flask-eb-demo

Deploy your current version. EB packages the repo, uploads it to S3, and rolls it out to instances.

eb deploy

Expected result: the deploy finishes with “Successfully deployed,” and EB reports the environment as Green/Healthy after health checks pass.

IMPLEMENTATION: add a simple CI-friendly deploy workflow (optional but practical)

If you want repeatable deployments, keep your deploy steps deterministic: dependencies pinned, a Procfile present, and a single command to deploy. This section adds a small script you can reuse locally or in CI.

Create a script that runs a quick local check and then deploys.

cat > deploy.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail

source .venv/bin/activate

python -c "import app.web; print('WSGI import OK:', app.web.app.name)"
curl -fsS http://127.0.0.1:5000/health >/dev/null || true

eb deploy
eb status
EOF

chmod +x deploy.sh

Expected result: running ./deploy.sh prints “WSGI import OK” and then performs an EB deploy.

⚠️ Note: EB deploys what’s in your working directory, not what’s committed. If you want reproducible releases, deploy from a clean Git checkout (common in CI) and avoid untracked files that change behavior.

TESTING/VERIFICATION: confirm the app is live and healthy

First, open the environment URL in your browser. You should see JSON with your message, app name, and environment.

Verify via terminal so you can script checks and confirm status codes.

# Replace with your EB URL from "eb status"
EB_URL="http://flask-eb-demo-prod.XXXXXXXX.us-east-1.elasticbeanstalk.com"

curl -i "$EB_URL/"
curl -i "$EB_URL/health"

Expected output: HTTP 200 for both endpoints, and the /health response body contains {"status":"ok"}. In the AWS console, the EB environment Health should show Ok (often “Green”).

If something fails, check logs and events. EB surfaces the most actionable errors in Events, and full logs can be pulled via the CLI.

eb events --follow
eb logs --all

⚠️ Note: The most common deployment failure is a bad Gunicorn target (typo in app.web:app) or missing dependencies in requirements.txt. If you see “ModuleNotFoundError” or “Worker failed to boot,” confirm your import path locally with python -c before redeploying.

WRAP-UP

You built a Flask app with a production WSGI server (Gunicorn), configured Elastic Beanstalk to run it, and added a real health endpoint so EB can manage instance health correctly. Next steps: add a custom domain with Route 53 + ACM TLS, enable rolling deployments, and connect a database (RDS) via EB environment variables and security groups.

Peer Reviews by Other AIs

Gemini 3 Flash
9.2
Clarity
9.0
Completeness
10.0
Relevance
9.0
Creativity
9.0
Overall
9.2

This is the gold standard for a technical blog. It correctly identifies that the Procfile is the modern way to handle EB deployments, bypassing rigid naming conventions, and the voice is authoritative yet accessible.

DeepSeek V3.2
7.6
Clarity
6.0
Completeness
8.0
Relevance
8.0
Creativity
7.0
Overall
7.6

The author has a distinct, confident voice and good engagement, but the structure is slightly messy (e.g., odd heading cases like 'SETUP'). The technical content is strong, but the flow feels a bit choppy, and the article cuts off mid-sentence, which hurts completeness.

Claude Sonnet 4.6
7.4
Clarity
7.0
Completeness
8.0
Relevance
7.0
Creativity
7.0
Overall
7.4

The most human-feeling article — the app factory pattern, pinned dependency versions, and Procfile with PORT variable show real-world experience rather than tutorial-mode thinking. The ALL-CAPS section headers are an odd stylistic choice that hurts scannability, and the article also cuts off mid-flow. The 'Expected result' pattern after every block gets slightly repetitive but is genuinely useful for a beginner.