Module 10 · Ship it · 60 min · You are: Platform and product
Capstone: onboard team-payments
In this module
- You learn: Nothing new: the capstone checks you can use everything together.
- You do: As the platform team, add team-payments and its system. As team-payments, create
payments-apifrom the template. As the platform team, ship and prove it in the image. - You end with: team-payments exists, owns
payments-apiand thepaymentssystem, and you are a member. The image runs it all.
Onboarding a team is what a portal is for. If you can do it without the steps, you know where every piece lives and who owns it.
Open this module in the interactive course to track progress.
Concepts
- Acceptance criteria
- Each challenge lists what must be true at the end. Check them yourself before you open the solution.
Files to know
Open them in your editor or on GitHub; the bullets say what to look at.
portal/catalog/org.yaml(reference, your repo): Where teams are added.- Copy this shape L24–29
portal/catalog/systems.yaml(reference, your repo): Where systems are added.- A system in the commerce domain L13–17
Steps
1. Platform: add team-payments (Challenge)
Done when:
- A Group
team-payments(title Team Payments,type: team, parentacme), listed inacme's children - Your User is a member of it
- A System
paymentsin domaincommerce, owned byteam-payments - Merged through a pull request; Settings shows
group:default/team-paymentsunder Ownership Entities after you sign in again
Hint 1
Copy team-checkout's Group and the shop System and rename.
Hint 2
Ownership Entities are read at sign-in: sign out and in.
One solution
Three edits in the portal repo, one pull request.
Add to ~/work/portal/catalog/org.yaml after the team-checkout Group
---
apiVersion: backstage.io/v1alpha1
kind: Group
metadata:
name: team-payments
title: Team Payments
spec:
type: team
parent: acme
children: []
Change in ~/work/portal/catalog/org.yaml
- children: [platform, team-checkout]
+ children: [platform, team-checkout, team-payments]
Change in ~/work/portal/catalog/org.yaml
- memberOf: [platform, team-checkout]
+ memberOf: [platform, team-checkout, team-payments]
Add to ~/work/portal/catalog/systems.yaml at the end
---
apiVersion: backstage.io/v1alpha1
kind: System
metadata:
name: payments
description: Taking the money.
spec:
owner: team-payments
domain: commerce
cd ~/work/portal
Propose it as a pull request. Put it on its own branch and push it:
git switch -c onboard-team-payments && git add -A && git commit -qm "Catalog: onboard team-payments"
git push -qu origin HEAD
Open the pull request. It prints a link:
gh pr create --fill
Open that link in your browser. Files changed shows exactly your diff.
Merge it on GitHub (Squash and merge, then Delete branch), or from the terminal:
gh pr merge --squash --delete-branch
Either way, bring your copy up to date:
git switch -q main && git pull -q
2. team-payments: a new service (Challenge)
Done when:
- A repo
YOUR_GITHUB_USER/payments-apicreated by the template payments-apiisownedBy group:default/team-paymentsandpartOf system:default/payments- Its TechDocs say
Owned by Team Payments
Hint 1
Start the dev portal again (yarn start with .env loaded).
Hint 2
Check relations with the catalog API, like in module 03.
One solution
The template does it all; you only check.
Create → Node.js service: name payments-api, owner Team Payments, system payments, repository YOUR_GITHUB_USER/payments-api.
curl -s -H "Authorization: Bearer $PORTAL_API_TOKEN" localhost:7007/api/catalog/entities/by-name/component/default/payments-api | jq -r '.relations[] | .type + " " + .targetRef'
3. Platform: ship and prove it (Challenge)
Done when:
- A new image built from
main - Running against a fresh database, you can sign in
- The catalog in the container lists
payments-api, and Team Payments owns it
Hint 1
Same commands as module 09.
Hint 2
Discovery finds payments-api on its first scan, about 15 seconds after start.
One solution
Build, fresh database, run, check.
cd ~/work/portal && git switch -q main && git pull -q && yarn install --immutable && yarn tsc && yarn build:backend && yarn build-image
docker rm -f portal-prod-db && docker run -d --name portal-prod-db --network portal-net -e POSTGRES_PASSWORD=portal-prod postgres:17.11
cd ~/work/portal && set -a && . ./.env && set +a
docker run --rm --name portal --network portal-net -p 7007:7007 \
-e POSTGRES_HOST=portal-prod-db -e POSTGRES_PORT=5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=portal-prod \
-e PORTAL_API_TOKEN -e GITHUB_TOKEN -e AUTH_GITHUB_CLIENT_ID -e AUTH_GITHUB_CLIENT_SECRET \
backstage
curl -s -H "Authorization: Bearer $PORTAL_API_TOKEN" localhost:7007/api/catalog/entities/by-name/component/default/payments-api | jq -r '.relations[] | .type + " " + .targetRef'
4. Tear down
Your portal and checkout repos keep everything; the plugins course starts from them. Remove what you do not need.
docker rm -f portal-prod-db && docker network rm portal-net
Deleting repos needs an extra scope once:
gh auth refresh -s delete_repo && gh repo delete YOUR_GITHUB_USER/cart --yes && gh repo delete YOUR_GITHUB_USER/payments-api --yes
Quiz
- What did onboarding team-payments need from the platform team?
- A Group, a System and a membership in
org.yamlandsystems.yaml, through a pull request - A new plugin
- A new portal for the team
- A Group, a System and a membership in
- What did team-payments need from the platform team to create a service?
- A ticket per repo
- Nothing: the template and discovery do the rest
- Admin rights on the portal
- What would you automate next with a third team?
- Copying
org.yamlby hand - More hand-registered locations
- Importing teams and users from GitHub or your identity provider with an org provider
- Copying
Answers
- A Group, a System and a membership in
org.yamlandsystems.yaml, through a pull request The catalog files are the onboarding interface. - Nothing: the template and discovery do the rest That is the point of a golden path.
- Importing teams and users from GitHub or your identity provider with an org provider Typing people into YAML does not scale.
Field note
If you did this without the solutions, you can run a Backstage portal for a company. Plugins are the next step: the plugins course builds one on this portal.