Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
name: Deploy
on:
push:
branches: [main, master]
branches: [main]
pull_request:
workflow_dispatch:

permissions:
id-token: write # AWS access via OIDC
contents: write # platform commits generated Terraform to the branch
pull-requests: write # plan + review comment on PRs

# No secrets needed — see
# https://github.com/javaBin/platform/blob/main/docs/reusable-workflows.md
jobs:
javabin:
# The template repo itself never deploys; repos created from it do.
if: github.repository != 'javaBin/app-template'
uses: javaBin/platform/.github/workflows/javabin.yml@main
secrets: inherit
21 changes: 13 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,21 @@ GitHub template repository for creating new services on the Javabin platform.

1. Click **"Use this template"** on GitHub to create a new repo under `javaBin/`
2. Edit `app.yaml` — set your service name, team, compute settings, routing, and any resources
3. Ensure your team is registered in [javaBin/registry](https://github.com/javaBin/registry) (`teams/{name}.yaml`) and add the repo to your GitHub team
3. Ensure your team is registered in [javaBin/registry](https://github.com/javaBin/registry) (`teams/{name}.yaml`) and add the repo to the GitHub team named in `app.yaml` `team:` (CI verifies repo → team before vending credentials)
4. Push to `main` — the platform CI builds, plans, reviews, and deploys automatically
5. Set any secret values: `brew install javaBin/tap/javabin`, `javabin aws setup` (SSO permission set `javabin-team-<team>`), then `javabin secret set <name>`

## app.yaml Fields

- `name` — service name (required, lowercase + hyphens, max 20 chars)
- `team` — owning team, must exist in the registry (required)
- `compute` — CPU, memory, port, desired count, health check path
- `team` — owning team, lowercase letters only (max 12), must exist in the registry (required)
- `compute` — CPU, memory, port, desired count, health check path, `user` (default `"1000"`), `readonly_root_filesystem` (default `true`; only `/tmp` writable)
- `routing` — hostname under `javazone.no` and ALB priority
- `resources` — S3 buckets, DynamoDB tables, Secrets Manager secrets, SQS queues
- `auth` — Cognito integration: `internal`, `external`, `both`, or `none`
- `resources` — S3 buckets, DynamoDB tables / RDS PostgreSQL, SSM secrets (created as `PLACEHOLDER`, set with `javabin secret set`), SQS queues
- `auth` — Cognito: `internal`/`external` shorthand, or full form with `client: confidential|public|none`, `callback_urls` (https or `http://localhost`), `groups` (restricts sign-in), `env` (alias injected names)
- `environment` — custom environment variables
- `budget_alert_nok` — monthly budget alert threshold in NOK

Unknown fields fail the pipeline's `expand` step. Budgets are per team, set in the registry.

Full reference: [app.yaml reference](https://github.com/javaBin/platform/blob/main/docs/app-yaml-reference.md)

Expand All @@ -37,10 +39,13 @@ The default Dockerfile uses `eclipse-temurin:21` for a Java/Maven project. Repla

## CI

This template includes `.github/workflows/deploy.yml` which calls the platform's reusable workflow `javaBin/platform/.github/workflows/javabin.yml@main`. No additional workflow config needed.
This template includes `.github/workflows/deploy.yml` which calls the platform's reusable workflow `javaBin/platform/.github/workflows/javabin.yml@main`. No secrets are needed; keep the `permissions:` block (`id-token: write`, `contents: write`, `pull-requests: write`). The job's `if: github.repository != 'javaBin/app-template'` keeps the template itself from deploying; generated repos have another name, so it runs there.

Validate `app.yaml` locally against the generator from a platform checkout:
`GITHUB_WORKSPACE=. APP_SERVICE=my-service AWS_ACCOUNT_ID=553637109631 TF_ROOT=/tmp/gen python3 -I ../platform/scripts/generate-modules.py`

## Related

- [javaBin/platform](https://github.com/javaBin/platform) — shared infrastructure and reusable modules
- [javaBin/registry](https://github.com/javaBin/registry) — team registration
- [javaBin/javabin-cli](https://github.com/javaBin/javabin-cli) — `javabin register` automates team registration
- [javaBin/javabin-cli](https://github.com/javaBin/javabin-cli) — `javabin register-team`, `javabin aws setup`, `javabin secret set`
32 changes: 25 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,39 @@ A Javabin platform service.

## Getting Started

1. **Create from template**: Click "Use this template" on GitHub
2. **Register your team**: If not already registered, open a PR to [javaBin/registry](https://github.com/javaBin/registry) adding `teams/your-team.yaml`, then add this repo to your GitHub team
3. **Customize `app.yaml`**: Set your service name, team, compute, and routing
4. **Push to main**: The platform CI pipeline builds, plans, reviews, and deploys automatically
1. **Create from template**: Click "Use this template" on GitHub (repo under `javaBin/`)
2. **Register your team**: If not already registered, open a PR to [javaBin/registry](https://github.com/javaBin/registry) adding `teams/<team>.yaml` (or run `javabin register-team`). Merging creates the GitHub team and the team's AWS CI roles; members sign in to AWS with the SSO permission set `javabin-team-<team>`. Team names are lowercase letters only, max 12 chars.
3. **Add this repo to your GitHub team** — the one named in `app.yaml` `team:`; CI refuses to deploy otherwise:
`gh api -X PUT orgs/javaBin/teams/<team>/repos/javaBin/<repo> -f permission=push`
4. **Customize `app.yaml`**: Set your service name, team, compute, routing, and any resources/auth
5. **Push to main**: The platform CI pipeline builds, plans, reviews, and deploys automatically. Pull requests get a Terraform plan and review comment.

No repository secrets are needed. `.github/workflows/deploy.yml` must keep its `permissions:` block (`id-token: write`, `contents: write`, `pull-requests: write`). Its `if:` only stops the template repo itself from deploying; it is true in your repo.

## Secrets

`resources.secrets` entries are created with the value `PLACEHOLDER` on the first deploy. Set real values with the [javabin CLI](https://github.com/javaBin/javabin-cli) from this repo:

```bash
brew install javaBin/tap/javabin
javabin aws setup # SSO sign-in with javabin-team-<team>
javabin secret list # which secrets still hold PLACEHOLDER
javabin secret set api-key # prompts without echo; --stdin to pipe
```

The service restarts automatically within a minute to pick up the new value.

## Platform Features

- Automatic Docker build and ECR push
- Terraform infrastructure from `app.yaml` (S3, DynamoDB, SQS, Secrets Manager)
- Terraform infrastructure from `app.yaml` (S3, DynamoDB, RDS PostgreSQL, SQS, SSM secrets, Cognito clients)
- LLM-powered plan review with risk gating
- ECS Fargate deployment with health checks
- CloudWatch alarms and cost monitoring
- ECS Fargate deployment with health checks and circuit-breaker rollback
- CloudWatch alarms; budgets per team (set in the registry)

## References

- [app.yaml reference](https://github.com/javaBin/platform/blob/main/docs/app-yaml-reference.md)
- [Reusable workflows](https://github.com/javaBin/platform/blob/main/docs/reusable-workflows.md)
- [Platform documentation](https://github.com/javaBin/platform)
- [Registry](https://github.com/javaBin/registry)
45 changes: 30 additions & 15 deletions app.yaml
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
# app.yaml — Javabin Platform Service Configuration
# Full reference: https://github.com/javaBin/platform/blob/main/docs/app-yaml-reference.md
#
# Validated strictly: unknown or misspelled fields fail the pipeline's `expand` step.
# Budgets are not set here — they are per team (`budget_nok` in javaBin/registry teams/<team>.yaml).

# Service name (required) — lowercase + hyphens, max 20 chars
# Service name — starts with a letter; lowercase letters, digits, hyphens; max 20 chars (default: repo name)
name: my-service

# Owning team (required) — must match a team in javaBin/registry
team: my-team
# Owning team (required) — lowercase letters only, max 12 chars. Must exist in
# javaBin/registry (teams/<team>.yaml), and this repo must be in that GitHub team.
team: myteam

# Container compute settings (optional, defaults shown)
# Container compute settings (optional; omitted fields use platform defaults)
compute:
cpu: 512 # vCPU units (256, 512, 1024, 2048, 4096)
memory: 1024 # MB (512-30720, must match cpu)
port: 8080 # container port your app listens on
memory: 1024 # MB, must be a valid Fargate combination with cpu
port: 8080 # container port your app listens on (platform default: 8000)
desired_count: 1 # number of running tasks
health_check: /health
# user: "1000" # container user (default "1000", non-root)
# readonly_root_filesystem: true # default true — only /tmp is writable; set false if the app writes elsewhere

# ALB routing (required for web services)
# ALB routing — omit for a worker with no load balancer
routing:
host: my-service.javazone.no # DNS name, must be under javazone.no
priority: 100 # unique across all apps (1-50000)
Expand All @@ -26,22 +32,31 @@ routing:
# - name: data
# env: DATA_BUCKET
# databases:
# - name: cache
# - name: cache # DynamoDB (default)
# hash_key: id
# env: CACHE_TABLE
# secrets:
# - name: api-key
# - name: main # RDS PostgreSQL
# engine: postgres
# env: DATABASE_URL
# secrets: # created as PLACEHOLDER; set the value after the first deploy:
# - name: api-key # javabin aws setup && javabin secret set api-key
# env: API_KEY
# queues:
# - name: jobs
# env: JOBS_QUEUE_URL

# Cognito auth (optional) — internal, external, both, or none
# auth: internal
# Cognito auth (optional). Shorthand: `auth: internal` (Javabin heroes) or `auth: external` (public users).
# auth:
# pool: internal
# client: confidential # confidential (server-side login, id + secret) | public (browser PKCE, id only) | none (API that only verifies tokens)
# callback_urls: # default: https://<routing.host>/ and /auth/callback
# - https://my-service.javazone.no/auth/callback
# - http://localhost:8080/auth/callback # localhost allowed for local dev
# groups: # only members of these registry groups can sign in
# - team-myteam
# env: # also inject values under your own names
# COGNITO_CLIENT_ID: OIDC_CLIENT_ID

# Custom environment variables
# environment:
# LOG_LEVEL: info

# Monthly budget alert in NOK (default: 1000)
# budget_alert_nok: 500