Skip to content

skondla/webapp-fastapi

Repository files navigation

License Python FastAPI Deploy GKE Deploy EKS Deploy AKS

webapp-fastapi — RDS Snapshot Management API

A FastAPI service that exposes an HTTPS REST + HTML interface for managing Amazon RDS database snapshots (create, status, delete) for both single instances and Aurora clusters. The same container ships with reference deployments for AWS (ECS, EKS), Azure (AKS), and Google Cloud (GKE), wired through a GitHub Actions DevSecOps pipeline.


Table of Contents


Architecture

The service is a small async FastAPI app fronted by Uvicorn over TLS. Each HTTP handler delegates to the rdsAdmin module, which wraps the AWS SDK (boto3) and calls Amazon RDS. Snapshots are created by RDS itself and stored in AWS-managed S3 (visible only through the RDS API).

System Architecture

Legacy diagram preserved at images/dbAPIapp.png. The SVG above (images/architecture.svg) is the current source of truth and is updated alongside the code.

Mermaid source (renders on GitHub)
flowchart LR
    subgraph Clients["Clients"]
        U["User / Browser"]
        C["CI / Cron / curl"]
    end

    subgraph Runtime["Container Runtime (EKS / ECS / AKS / GKE / Local)"]
        direction TB
        UV["Uvicorn + TLS<br/>:25443"]
        API["FastAPI app<br/>dbWebAPI.py"]
        TPL["Jinja2 templates<br/>(HTML UI)"]
        LIB["lib/rdsAdmin.py<br/>RDSCreate / RDSDescribe / RDSDelete"]
        UV --> API
        API --> TPL
        API --> LIB
    end

    subgraph AWS["AWS Account"]
        RDS["Amazon RDS<br/>(Instance / Aurora Cluster)"]
        SNAP["RDS Snapshots<br/>(AWS-managed S3)"]
    end

    U -->|HTTPS form post| UV
    C -->|HTTPS / curl| UV
    LIB -->|boto3 / AWS API| RDS
    RDS --> SNAP
Loading

Request flow — POST /backup/create

sequenceDiagram
    autonumber
    participant Client
    participant FastAPI as FastAPI (dbWebAPI)
    participant RDSAdmin as lib.rdsAdmin
    participant RDS as AWS RDS

    Client->>FastAPI: POST /backup/create (endpoint=<db-host>)
    FastAPI->>FastAPI: derive snapshot_name<br/>{instance}-snapshot-{YYYY-MM-DD-HH-MM-SS}
    alt endpoint contains "cluster"
        FastAPI->>RDSAdmin: rds_create_db_cluster_snapshot(...)
        RDSAdmin->>RDS: create_db_cluster_snapshot
    else single instance
        FastAPI->>RDSAdmin: rds_create_db_snapshot(...)
        RDSAdmin->>RDS: create_db_snapshot
    end
    FastAPI->>RDSAdmin: snapshot_status(snapshot_name, endpoint)
    RDSAdmin->>RDS: describe_db[_cluster]_snapshots
    RDS-->>RDSAdmin: Status (creating | available | ...)
    RDSAdmin-->>FastAPI: status
    FastAPI-->>Client: { snapshot_name, status }
Loading

Features

  • Async FastAPI REST endpoints + light Jinja2 HTML UI.
  • HTTPS only — TLS terminated by Uvicorn using a configured cert/key.
  • RDS instance and Aurora cluster snapshot support (routed by endpoint hostname pattern).
  • Stateless — safe to run multiple replicas behind a load balancer.
  • Multi-cloud deploys — reference Kubernetes manifests + IaC for AWS EKS, AWS ECS, Azure AKS, GCP GKE.
  • DevSecOps GitHub Actions — checkout → test → build → Trivy scan → deploy → OWASP ZAP baseline scan.

Repository Layout

webapp-fastapi/
├── app1/                       # FastAPI application (the service)
│   ├── dbWebAPI.py             # FastAPI app, routes, TLS entrypoint
│   ├── dbWebAPI.sh             # Container entrypoint shim
│   ├── lib/rdsAdmin.py         # boto3 wrapper: RDSCreate/Describe/Delete
│   ├── templates/              # Jinja2 HTML templates for the UI
│   ├── config/appConfig.yaml   # host, port, cert, key
│   ├── cert/                   # Local-dev TLS material (do not ship real certs)
│   ├── requirements.txt        # Python deps
│   ├── Dockerfile              # Primary image (python:3.13)
│   ├── Dockerfile.lite         # Slim variant (python:3.11-slim)
│   ├── Dockerfile.alpine       # Alpine variant
│   ├── deployment.yaml         # Sample K8s Deployment
│   ├── service.yaml            # Sample K8s Service
│   └── aws-task-definition.json# ECS task definition
│
├── aws/                        # AWS deployment assets
│   ├── ecr/deploy/             # Push image to ECR
│   ├── ecs/deploy/             # ECS cluster + service (bash + terraform)
│   ├── eks/deploy/             # EKS cluster (eksctl) + app manifests
│   ├── monitoring/grafana/     # Grafana / infracost samples
│   ├── web_infra/example/      # Reference 3-tier VPC infra
│   │   ├── bash/               # AWS CLI bootstrap scripts
│   │   └── terraform/          # main.tf for VPC/ALB/EC2
│   ├── PermissionBoundary.yaml # IAM permission boundary template
│   └── createPermBoundary.sh
│
├── azure/                      # Azure deployment assets
│   ├── acr/deploy/             # ACR setup
│   └── aks/deploy/
│       ├── bash/               # AKS provisioning + nginx ingress
│       └── manifest/           # App + Postgres samples
│
├── gcp/gke/                    # GCP deployment assets
│   ├── deploy/
│   │   ├── terraform/          # GKE module + examples (public/private cluster)
│   │   ├── manifests/          # K8s manifests + Dockerfile for GKE
│   │   ├── monitoring/prometheus/
│   │   └── serviceMesh/        # Istio / Linkerd / Anthos installers
│   └── upgrade/                # Cluster + node pool upgrade scripts
│
├── local/deploy/webapp/        # Local docker/desktop deploy helpers
├── lite/                       # Slim build context (Dockerfile + requirements)
├── from_dockerhub/             # K8s manifests pulling pre-built Docker Hub image
├── manifests/                  # Generic K8s manifests
├── actions/                    # Reference GitHub Actions workflows
├── .github/workflows/          # Active workflows (AKS / EKS / GKE)
├── workflows/                  # Additional workflow examples
├── images/                     # Diagrams and screenshots
├── README.md
└── LICENSE

Quick Start

Run locally

# 1. Install dependencies
cd app1
pip install -r requirements.txt --user

# 2. Generate a self-signed cert (one-time, for local TLS)
cd cert
openssl genrsa -out key.pem 2048
openssl req -new -x509 -key key.pem -out certificate.pem -days 365 \
  -subj "/C=US/ST=GA/L=Atlanta/O=Local/OU=Dev/CN=localhost"
cd ..

# 3. Point appConfig.yaml at your local cert paths, then run:
uvicorn dbWebAPI:app \
  --host 0.0.0.0 --port 25443 \
  --ssl-keyfile cert/key.pem --ssl-certfile cert/certificate.pem --reload

Open https://localhost:25443/ (accept the self-signed cert warning).

Schedule periodic execution (optional)

*/5 * * * * /usr/bin/flock -n /tmp/fullWebapp.lock python /data2/api/db/dbWebAPI.py >> /data2/api/db/log 2>&1

API Reference

The service exposes both HTML pages (for browser use) and JSON endpoints (for curl / CI). All paths are served over HTTPS on the port defined in app1/config/appConfig.yaml.

Method Path Form Body Returns
GET / HTML home
GET /backup HTML tool menu
GET /backup/create HTML form
POST /backup/create endpoint=<db-host> { snapshot_name, status }
GET /backup/status HTML form
POST /backup/status snapshotname=<name>&endpoint=<db> { snapshot_status }
GET /backup/delete HTML form
POST /backup/delete snapshotname=<name>&endpoint=<db> { message }
GET /data JSON sample

Cluster vs. instance routing is determined by checking whether the endpoint value contains the substring cluster (see dbWebAPI.py).

curl examples

# Create a snapshot for an Aurora cluster (RO endpoint)
curl -k https://<host>:25443/backup/create \
  --data "endpoint=ecomm-integ-postgresdb-aurora.cluster-ro-xxxx.us-east-1.rds.amazonaws.com"

# Check status
curl -k https://<host>:25443/backup/status \
  --data "snapshotname=ecomm-integ-postgresdb-aurora-snapshot-2025-06-23-22-21-57" \
  --data "endpoint=ecomm-integ-postgresdb-aurora.cluster-ro-xxxx.us-east-1.rds.amazonaws.com"

# Delete
curl -k https://<host>:25443/backup/delete \
  --data "snapshotname=ecomm-integ-postgresdb-aurora-snapshot-2025-06-23-22-21-57" \
  --data "endpoint=ecomm-integ-postgresdb-aurora.cluster-ro-xxxx.us-east-1.rds.amazonaws.com"

Configuration

app1/config/appConfig.yaml controls runtime bindings:

appConfig:
  hostname: 0.0.0.0
  port: 25443
  certificate: /app/certs/certificate.pem
  key: /app/certs/key.pem

AWS credentials are picked up by boto3 via the standard chain (env vars, shared credentials file, instance/role profile, IRSA, or Workload Identity in GKE). Ensure the runtime identity has the minimum IAM permissions required by rdsAdmin.py:

  • rds:CreateDBSnapshot, rds:CreateDBClusterSnapshot
  • rds:DescribeDBSnapshots, rds:DescribeDBClusterSnapshots
  • rds:DescribeDBInstances, rds:DescribeDBClusters
  • rds:DeleteDBSnapshot, rds:DeleteDBClusterSnapshot
  • rds:AddTagsToResource (used implicitly when tagging snapshots)

Container Image

Three Dockerfiles are provided in app1/:

File Base image Purpose
Dockerfile python:3.13.1 Default — full build
Dockerfile.lite python:3.11-slim Slim image for production
Dockerfile.alpine python:*-alpine Smallest footprint

Build and run:

cd app1
docker build -t skondla/dbwebapi:latest .
docker run --rm -p 25443:25443 \
  -e AWS_ACCESS_KEY_ID=... -e AWS_SECRET_ACCESS_KEY=... -e AWS_REGION=us-east-1 \
  skondla/dbwebapi:latest

Cloud Deployments

Cloud Compute Tooling Path
AWS EKS eksctl + kubectl manifests aws/eks/deploy/
AWS ECS bash + Terraform aws/ecs/deploy/
AWS (image) ECR push helpers aws/ecr/deploy/
Azure AKS bash + nginx-ingress + manifests azure/aks/deploy/
Azure (image) ACR setup azure/acr/deploy/
GCP GKE Terraform module + manifests gcp/gke/deploy/
Local Docker Compose / single-container helpers local/deploy/webapp/

A reference 3-tier VPC (bastion + ALB + private app subnet) is provided under aws/web_infra/example/ for those who want a complete environment, not just the cluster.


CI/CD Pipeline

The GitHub Actions workflows in .github/workflows/ follow a consistent DevSecOps shape:

DevSecOps Pipeline

Mermaid source
flowchart LR
    A[Code Commit] --> B[Checkout]
    B --> C[Test]
    C --> D[Build & Push<br/>ECR / ACR / Artifact Registry]
    D --> E[Trivy Scan<br/>CRITICAL,HIGH]
    E --> F[Deploy<br/>EKS / AKS / GKE]
    F --> G[Smoke test endpoints]
    G --> H[OWASP ZAP baseline]
    G --> I[Slack notify]
Loading

The original asset is preserved at images/DevSecOps_with_GutHub_Actions.png.


Troubleshooting

# Is the process running?
ps -ef | grep dbWebAPI.py

# Is the port bound?
netstat -an | grep 25443
lsof -i :25443

# Tail logs (when launched via the cron flock pattern)
tail -f /data2/api/db/log

# In Kubernetes
kubectl -n <ns> get pods -l app=dbwebapi
kubectl -n <ns> logs deploy/db-backup-tool -f

Reading

Contact

Maintainer: Sudheer (Sam) Kondlaskondla@me.com

License

Released under the terms of the LICENSE file in this repository.

About

Migration of webapp to FastAPI

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors