{"id":50817117,"url":"https://github.com/erwan-simon/aws-serverless-notebook-platform","last_synced_at":"2026-06-13T10:30:44.755Z","repository":{"id":350642958,"uuid":"1189902529","full_name":"erwan-simon/aws-serverless-notebook-platform","owner":"erwan-simon","description":"A self-hosted, serverless platform offering an intuitive UI to manage, schedule, and execute Jupyter notebooks on AWS.","archived":false,"fork":false,"pushed_at":"2026-04-22T20:04:26.000Z","size":956,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"prod","last_synced_at":"2026-04-22T22:08:47.660Z","etag":null,"topics":["aws","data","docker","notebook","python","serverless","terraform","webapp"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erwan-simon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-23T19:27:14.000Z","updated_at":"2026-04-22T20:04:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/erwan-simon/aws-serverless-notebook-platform","commit_stats":null,"previous_names":["erwan-simon/aws-serverless-notebook-platform"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/erwan-simon/aws-serverless-notebook-platform","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erwan-simon%2Faws-serverless-notebook-platform","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erwan-simon%2Faws-serverless-notebook-platform/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erwan-simon%2Faws-serverless-notebook-platform/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erwan-simon%2Faws-serverless-notebook-platform/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erwan-simon","download_url":"https://codeload.github.com/erwan-simon/aws-serverless-notebook-platform/tar.gz/refs/heads/prod","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erwan-simon%2Faws-serverless-notebook-platform/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34281699,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","data","docker","notebook","python","serverless","terraform","webapp"],"created_at":"2026-06-13T10:30:44.057Z","updated_at":"2026-06-13T10:30:44.742Z","avatar_url":"https://github.com/erwan-simon.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AWS Serverless Notebook Platform\n\n![License](https://img.shields.io/badge/license-CC--BY--NC--4.0-blue)\n![Terraform AWS provider](https://img.shields.io/badge/terraform%20aws-%E2%89%A55.60-blueviolet)\n![Python](https://img.shields.io/badge/python-3.10%2B-blue)\n\nA self-hosted, browser-accessible notebook platform on AWS. Upload a Jupyter notebook, launch\na JupyterLab or VS Code session on ECS Fargate, run notebooks as one-off batch jobs, schedule\nthem on a cron — all behind Cognito and CloudFront, all provisioned by one `terraform apply`.\n\n```mermaid\nflowchart LR\n    UI[\"\u003cb\u003eWeb portal\u003c/b\u003e\u003cbr/\u003e\u003cbr/\u003eStatic SPA on CloudFront,\u003cbr/\u003eCognito sign-in.\u003cbr/\u003e\u003cbr/\u003e\u003ci\u003eupload · browse · run · view\u003c/i\u003e\"]\n    SESSION[\"\u003cb\u003eInteractive sessions\u003c/b\u003e\u003cbr/\u003e\u003cbr/\u003eJupyterLab or VS Code,\u003cbr/\u003eon-demand on ECS Fargate.\u003cbr/\u003e\u003cbr/\u003e\u003ci\u003epersistent /home · auto-shutdown\u003c/i\u003e\"]\n    BATCH[\"\u003cb\u003eBatch \u0026 schedules\u003c/b\u003e\u003cbr/\u003e\u003cbr/\u003eRun notebooks headless\u003cbr/\u003eor on a cron, with logs\u003cbr/\u003eand rendered HTML output.\u003cbr/\u003e\u003cbr/\u003e\u003ci\u003epapermill · EventBridge\u003c/i\u003e\"]\n    CONFIG[\"\u003cb\u003eConfigurations\u003c/b\u003e\u003cbr/\u003e\u003cbr/\u003eImage + IAM role + size.\u003cbr/\u003eBring your own from the UI,\u003cbr/\u003eauto-validated end-to-end.\u003cbr/\u003e\u003cbr/\u003e\u003ci\u003eper-team isolation\u003c/i\u003e\"]\n\n    UI --\u003e SESSION\n    UI --\u003e BATCH\n    CONFIG --\u003e SESSION\n    CONFIG --\u003e BATCH\n```\n\n| ![Notebooks list](docs/screenshots/notebooks_list.png) | ![Notebook viewer](docs/screenshots/notebook.png) |\n|:---:|:---:|\n| ![Interactive session](docs/screenshots/session.png) | ![Configurations](docs/screenshots/configurations.png) |\n\n## What you get\n\n- **Notebooks in the browser, no machine to manage.** Upload `.ipynb` files, organize them in\n  folders, view rendered output, all from a portal served via CloudFront. No EC2, no SageMaker,\n  no local Python setup — sessions are ECS Fargate tasks that exist only while you use them.\n- **Two interactive runtimes, one click.** Pick a configuration, pick CPU/RAM, click Run —\n  you get either a full JupyterLab or a full VS Code in the browser, served over HTTPS at a\n  per-session URL. Idle sessions are killed automatically (default 60 min) to keep costs flat.\n- **Batch + scheduled execution, baked in.** The same notebook you ran interactively can be\n  run headless via Papermill, or scheduled on a cron through EventBridge. Output is rendered\n  back to HTML and served from the portal; execution history per notebook is one click away.\n- **Bring your own image and IAM role.** A *configuration* pairs a Docker image (any ECR repo)\n  with an IAM role and default sizing. Add new ones from the UI; the platform automatically\n  validates them end-to-end (Papermill hello-world, JupyterLab boot, code-server boot) and\n  marks each session type compatible only if its validation passed.\n- **Per-user persistent storage.** EFS access points give every user a private `/home`\n  preserved across sessions, plus a `/shared` mount for team data. No more \"I lost my work\n  when the kernel died.\"\n- **Cognito + WAF + private origin out of the box.** Email-based admin-only sign-up, OAuth2\n  PKCE, a CloudFront-only path to the ALB (origin verification + AWS-managed prefix list),\n  WAF rate-limiting, geo-blocking, IP allowlist, API Gateway throttling.\n- **Tag-based safety net for custom configurations.** Custom IAM roles and ECR repos must\n  carry a security allowlist tag (`{project_name}:{domain_name} = allowed`) — the stack is\n  policy-restricted to refuse everything else, so a mistyped ARN can't grant unintended\n  privileges.\n- **Multi-environment by default.** `dev`, `staging`, `prod`, … are isolated via Terraform\n  workspaces. Resource names embed the workspace; no shared state, no copy-paste.\n\n## How it works\n\nFive concepts cover the platform:\n\n- A **notebook** is an `.ipynb` file you upload through the portal. It lives in S3, is rendered\n  to HTML on demand, and can be run interactively, headlessly, or on a schedule.\n- A **session** is an ECS Fargate task running JupyterLab or code-server, fronted by an ALB\n  listener rule on a per-session path (`/s/{service}/{session_id}/*`) and proxied through\n  CloudFront. Idle sessions are reaped automatically.\n- An **execution** is a one-off ECS task that runs a notebook with Papermill and renders the\n  result. Per-notebook execution history (status + output link) is shown in the UI.\n- A **schedule** is an EventBridge Scheduler rule that fires an execution on a cron expression.\n- A **configuration** is the (Docker image, IAM role, default size) tuple users pick from when\n  launching a session or running a notebook. Configurations are either Terraform-managed\n  (seeded from code, immutable in the UI) or user-added through the UI (validated end-to-end\n  on creation).\n\nCloudFront fronts everything: the SPA, the API Gateway, and the sessions ALB. The ALB security\ngroup only accepts traffic from the AWS-managed CloudFront origin-facing prefix list, so the\nALB is unreachable from the public internet.\n\n## Quickstart\n\nPrerequisites:\n\n- An AWS account with admin (or close to it) credentials configured locally.\n- Terraform `\u003e= 1.0` and Docker (Terraform invokes Docker locally to build images).\n- An existing Terraform state backend (S3 bucket + DynamoDB table).\n- A VPC tagged `Name = {project_name}_network_platform_prod` with public subnets tagged `Tier = Public`.\n\nFull prerequisites in [`docs/deploying.md`](docs/deploying.md).\n\n```bash\n# 1. Clone\ngit clone https://github.com/erwan-simon/aws-serverless-notebook-platform.git\ncd aws-serverless-notebook-platform/iac\n\n# 2. Create your local config from the templates and edit the values\ncp backend.hcl.example      backend.hcl\ncp terraform.tfvars.example terraform.tfvars\n$EDITOR backend.hcl terraform.tfvars\n\n# 3. Deploy\nterraform init -backend-config=backend.hcl\nterraform workspace new prod\nterraform apply\n\n# 4. Get the URL\nterraform output cloudfront_url\n```\n\nOpen the URL in your browser, sign in with the Cognito user you created, upload a notebook\nand run it. Full deployment walk-through (including how to create the first Cognito user) in\n[`docs/deploying.md`](docs/deploying.md). End-user walk-through in [`docs/using.md`](docs/using.md).\n\n## Concepts at a glance\n\n| Concept             | What it is                                                                                              | Where it lives                              |\n|---------------------|---------------------------------------------------------------------------------------------------------|---------------------------------------------|\n| **Notebook**        | `.ipynb` file uploaded through the portal. Stored in S3, rendered on demand.                            | S3 + DynamoDB                               |\n| **Session**         | On-demand JupyterLab or VS Code task on ECS Fargate, served at `/s/{service}/{id}/*`.                   | ECS service + ALB listener rule             |\n| **Execution**       | One-shot Papermill run of a notebook on ECS, with rendered HTML output.                                 | ECS task + DynamoDB                         |\n| **Schedule**        | Cron-triggered execution.                                                                               | EventBridge Scheduler                       |\n| **Configuration**   | Image + IAM role + default size, picked at run time. Managed (immutable) or user-added (validated).     | DynamoDB                                    |\n| **Workspace**       | Terraform workspace = environment (`dev`, `staging`, `prod`, …). Embedded in every resource name.       | Terraform                                   |\n\nResource names follow `{project_name}_{domain_name}_{workspace}_{resource_name}`, e.g.\n`poc_jupyter_sandbox_prod_ecs_cluster`.\n\n## Documentation\n\n| If you want to…                                       | Go to                                       |\n|-------------------------------------------------------|---------------------------------------------|\n| Stand the platform up in a real AWS account           | [`docs/deploying.md`](docs/deploying.md)    |\n| Use the deployed platform (notebooks, sessions, …)    | [`docs/using.md`](docs/using.md)            |\n\n## Repository layout\n\n```\n.\n├── code/\n│   ├── backend/                       # 17 Lambda handlers (Python), grouped by domain\n│   │   ├── configuration/             # add, delete, list, update\n│   │   ├── notebook/                  # upload, list, delete, render, run, update\n│   │   ├── execution/                 # get_status, list, update_status\n│   │   ├── session/                   # run, get, stop\n│   │   └── schedule/                  # schedule, unschedule\n│   ├── frontend/                      # Static SPA (HTML + vanilla JS), Cognito PKCE auth\n│   ├── docker_images/default/         # Default base image: jupyter/base-notebook + papermill\n│   │                                  #   + uv + jupyterlab-lsp + code-server\n│   ├── lambda_cleanup_idle_session/   # EventBridge-triggered idle-session sweeper\n│   └── lambda_cleanup_unused_labels/  # Label garbage collector\n├── iac/                               # Terraform root module\n│   ├── lambda_backend_module/         #   Reusable Lambda + API Gateway integration module\n│   ├── backend_*_lambda.tf            #   One file per backend Lambda\n│   └── *.tf                           #   CloudFront, WAF, ALB, ECS, Cognito, EFS, …\n├── docs/                              # Standalone deployment + usage guides\n└── LICENSE                            # CC BY-NC 4.0\n```\n\n## License \u0026 Contributing\n\nLicensed under [Creative Commons Attribution-NonCommercial 4.0](LICENSE).\n\nThe source of truth for development is GitLab; this GitHub repository is a read-only mirror\nthat runs `semantic-release` on the `prod` branch. Commits must follow\n[Conventional Commits](https://www.conventionalcommits.org/) — release versioning is derived\nfrom commit messages.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferwan-simon%2Faws-serverless-notebook-platform","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferwan-simon%2Faws-serverless-notebook-platform","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferwan-simon%2Faws-serverless-notebook-platform/lists"}