Writing Software Catalog Entities
Goal
Write the eight entity kinds of the Backstage software catalog yourself, and get used to the relation declarations and reference format between them. At the end, you express the same ownership information on a real cluster workload and connect the two worlds.
Why it matters
A catalog is not a list but a relationship graph. If you declare spec.owner, spec.system, and spec.providesApis on only one side, the catalog computes the bidirectional relations — so which field you write where decides the shape of the graph. The owner in particular matters so much that, if only one thing in the catalog had to be accurate, it would be that. Outage calls, vulnerability tickets, cost attribution, and retirement decisions all branch from the owner. And the owner must always be a team, not a person — because people leave and teams are taken over. In real operations, the files you create in this lab are committed together at the root of the service's code repository and registered automatically by discovery. Backstage itself is not in this environment, so grading reads the files and cluster objects.
Steps
- In
/root/cba-catalog/catalog-info.yaml, write a Component —apiVersion: backstage.io/v1alpha1,kind: Component,metadata.name: checkout-service,metadata.descriptionany sentence,metadata.annotationswithbackstage.io/techdocs-ref: dir:.andbackstage.io/kubernetes-id: checkout-service,spec.type: service,spec.lifecycle: production,spec.owner: group:team-checkout,spec.system: commerce, andspec.providesApiswith the first itemcheckout-api. - In
/root/cba-catalog/api-checkout.yaml, write an API —kind: API,metadata.name: checkout-api,spec.type: openapi,spec.lifecycle: production,spec.owner: group:team-checkout,spec.system: commerce, andspec.definitionas a multi-line string (block scalar) that starts withopenapi: 3.0.0. - In
/root/cba-catalog/resource-db.yaml, write a Resource —kind: Resource,metadata.name: checkout-db,spec.type: database,spec.owner: group:team-checkout,spec.system: commerce. - In
/root/cba-catalog/system-commerce.yaml, write a System —kind: System,metadata.name: commerce,spec.owner: group:team-checkout,spec.domain: retail. In/root/cba-catalog/domain-retail.yaml, write a Domain —kind: Domain,metadata.name: retail,spec.owner: group:team-checkout. - In
/root/cba-catalog/group-team-checkout.yaml, write a Group —kind: Group,metadata.name: team-checkout,spec.type: team,spec.profile.displayNameany value,spec.children: []. In/root/cba-catalog/user-youngju.yaml, write a User —kind: User,metadata.name: youngju,spec.memberOfwith the first itemteam-checkout. - In
/root/cba-catalog/all.yaml, write a Location —kind: Location,metadata.name: cba-catalog-all,spec.type: url, and inspec.targetslist the seven entity files you created earlier as relative paths like./catalog-info.yaml(7 in total). - Express the same ownership information on the cluster. Create the namespace
cba-commerce(with the labelapp.kubernetes.io/part-of: commerce), and inside it create the Deploymentcheckout-service— in the metadata labels putbackstage.io/kubernetes-id: checkout-service,app.kubernetes.io/name: checkout-service, andapp.kubernetes.io/part-of: commerce, and also putbackstage.io/kubernetes-id: checkout-servicein the Pod template labels. The image isnginx:1.27-alpineand replicas is1. - In
/root/cba-catalog/refs.txt, write the normalized references of all the entities you created earlier (Component, API, Resource, System, Domain, Group, User — 7 in total), one per line. The format is<소문자 kind>:default/<이름>(the placeholders are the lowercase kind and the name). Example:component:default/checkout-service. Exclude the Location.
Notes
- The entity reference format is
[<kind>:][<namespace>/]<name>, and the namespace default isdefault. - Hold a multi-line string as a YAML block scalar (
|). - Common mistake 1: writing
spec.owneras a person's name. People leave and teams remain. - Common mistake 2: trying to also write
providesApisin the opposite direction on the API side. With a declaration on one side, the catalog computes the relation in both directions. - Common mistake 3: putting
backstage.io/kubernetes-idas a label on the entity and as an annotation on the workload. The direction is reversed — it is an annotation on the entity and a label on the workload.
Component entity
In /root/cba-catalog/catalog-info.yaml, write a Component — apiVersion: backstage.io/v1alpha1, kind: Component, metadata.name: checkout-service, metadata.description any sentence, metadata.annotations with backstage.io/techdocs-ref: dir:. and backstage.io/kubernetes-id: checkout-service, spec.type: service, spec.lifecycle: production, spec.owner: group:team-checkout, spec.system: commerce, and spec.providesApis with the first item checkout-api.
The required spec fields of a Component are type, lifecycle, and owner. Write the owner so that it points to a team, not a person, and spell out the first part of the reference format.
API entity
In /root/cba-catalog/api-checkout.yaml, write an API — kind: API, metadata.name: checkout-api, spec.type: openapi, spec.lifecycle: production, spec.owner: group:team-checkout, spec.system: commerce, and spec.definition as a multi-line string (block scalar) that starts with openapi: 3.0.0.
An API entity holds its definition as a string. If you use a YAML block scalar, you can hold several lines as they are.
Resource entity
In /root/cba-catalog/resource-db.yaml, write a Resource — kind: Resource, metadata.name: checkout-db, spec.type: database, spec.owner: group:team-checkout, spec.system: commerce.
A Resource is infrastructure a component needs. The field name that indicates the type is the same as in Component.
System and Domain
In /root/cba-catalog/system-commerce.yaml, write a System — kind: System, metadata.name: commerce, spec.owner: group:team-checkout, spec.domain: retail. In /root/cba-catalog/domain-retail.yaml, write a Domain — kind: Domain, metadata.name: retail, spec.owner: group:team-checkout.
A System is a group of things that work together, and a Domain is the higher-level area of systems. The field that links the two is on the System side.
Group and User
In /root/cba-catalog/group-team-checkout.yaml, write a Group — kind: Group, metadata.name: team-checkout, spec.type: team, spec.profile.displayName any value, spec.children: []. In /root/cba-catalog/user-youngju.yaml, write a User — kind: User, metadata.name: youngju, spec.memberOf with the first item team-checkout.
A Group is a team and a User is a person. The field that says which team a person belongs to is on the User side.
Group them with a Location
In /root/cba-catalog/all.yaml, write a Location — kind: Location, metadata.name: cba-catalog-all, spec.type: url, and in spec.targets list the seven entity files you created earlier as relative paths like ./catalog-info.yaml (7 in total).
A Location is a signpost that points to other entity files. It only makes sense if the targets it points to actually exist.
The same ownership as cluster labels
Express the same ownership information on the cluster. Create the namespace cba-commerce (with the label app.kubernetes.io/part-of: commerce), and inside it create the Deployment checkout-service — in the metadata labels put backstage.io/kubernetes-id: checkout-service, app.kubernetes.io/name: checkout-service, and app.kubernetes.io/part-of: commerce, and also put backstage.io/kubernetes-id: checkout-service in the Pod template labels. The image is nginx:1.27-alpine and replicas is 1.
The Kubernetes plugin looks for workload labels that have the same value as the entity's annotation. Tell apart which of annotation and label belongs to the entity and which to the workload.
Normalize entity references
In /root/cba-catalog/refs.txt, write the normalized references of all the entities you created earlier (Component, API, Resource, System, Domain, Group, User — 7 in total), one per line. The format is <소문자 kind>:default/<이름> (the placeholders are the lowercase kind and the name). Example: component:default/checkout-service. Exclude the Location.
The normalized format writes kind in lowercase and does not omit the namespace. All the entities you created earlier are targets.