Certifications · CBA · Practice Questions

CBA Practice Questions

Twenty-four single-best-answer questions, built the way the real CBA builds them: one stem, four options, exactly one option that answers this stem better than the other three. They're split across all four domains from the CBA blueprint in proportion to their weight — eight on Customizing Backstage, six on the Development Workflow, five each on Infrastructure and the Catalog — so a strong or weak score in one section tells you something real about where your marks would actually land. This page is untimed and open-book on purpose: work through it slowly, read every explanation even for questions you got right, and only once these twenty-four stop surprising you should you move on to the two full, weighted, timed papers — Mock Exam · Set 1 and Mock Exam · Set 2.

☺ Explain it like I'm 10

Picture a quiz card with four doors instead of a blank line. One door is right. The other three were built on purpose to feel almost right — one puts the right idea behind the wrong door of the workshop (the front-of-house door instead of the back-office door, or the other way round); one uses a big bossy word like "always," which real software almost never obeys; one is a command or a setting that sounds official but was never actually real. Reading these questions is a skill on top of knowing the material. This page hands you both at once: real CBA-shaped questions about the front desk you build and own, and a full explanation of every door — not just which one was right, but why each wrong one was built the way it was.

🦋🐰Your hosts for this topic: Mira the Butterfly & Remy the Rabbit — Mira already carries the CBA blueprint on this course (turning a raw catalog into a self-service front desk), so she's the one who knows exactly which door each question is really testing; Remy wants to answer everything in two seconds flat, which is precisely the instinct this bank exists to train and discipline.

How this bank is built

☺ Like you're 10: The biggest pile of questions covers the biggest part of the real test. Study in that order and you're spending your time where the marks actually are.

The CBA curriculum weights its four domains 32 / 24 / 22 / 22, and this bank mirrors that shape rather than splitting twenty-four questions evenly into four piles of six. Customizing Backstage gets the largest single share, because it's nearly a third of the real paper and, unlike everything else on the cloud-native shelf, it's mostly React. Infrastructure and the Catalog — the two domains that feel the most like "regular platform work" — still get five full questions each, because together they're 44% of the exam.

🦋Customizing Backstage
32%
🦫Development Workflow
24%
🦉Infrastructure
22%
🐿️Catalog
22%
DomainBlueprint weightQuestions hereNumbers
🦋 Customizing Backstage32%8Q1–Q8
🦫 Development Workflow24%6Q9–Q14
🦉 Infrastructure22%5Q15–Q19
🐿️ Catalog22%5Q20–Q24
Total24Q1–Q24
THE STEM a scenario, then one precise question A · The key Answers this exact stem, precisely — no hedging needed B · Wrong package True — about app when the stem asked about backend (or vice versa) C · Absolute "always," "never," "only" — real config is almost always conditional D · Fabrication A command, flag or annotation that sounds real but was never real
◆ Key idea

Every question below asks for the single best answer, not the only true sentence in the list. On several of these, two options are individually defensible — that's deliberate. Read the exact question being asked before you look at the options, form your own answer, then compare it to what's on offer. If your answer isn't there, you've likely misread the question rather than found a flaw in it. For the tool itself — the monorepo, the client-server split, the full curriculum table — the Platform Engineering course's own Backstage page and CBA overview are good background reading if any of this feels unfamiliar.

Customizing Backstage — 8 questions

☺ Like you're 10: This is the front desk's own construction kit — which drawer holds the screwdrivers, and which drawer you're never, ever supposed to leave unlocked.

Thirty-two percent of the real exam — the single largest domain — is Customizing Backstage: frontend versus backend plugins, editing React in App.tsx and EntityPage.tsx, Material UI, and the scaffolder's credentials. It's the domain that catches operations people off guard, because it's mostly software development, not configuration.

Q1. A team runs yarn workspace app add @backstage/plugin-kubernetes and nothing else. Afterwards, a "Kubernetes" tab appears on the entity page, but it stays permanently empty — no data, no error message beyond a failed network call in the browser console. What's the most likely cause?

Show answer & explanation

Answer: A. B is a fabrication — Material UI governs layout, not whether a network call succeeds. C misplaces the fix in the wrong domain entirely: catalog.locations registers entities, not plugins. D is simply false — Kubernetes is one of the most commonly wired entity-page tabs there is. This is the single most common real-world symptom of installing only the frontend half of a paired plugin: the tab renders because the React half is present, but there's no backend route behind it to hold the credentials and actually answer the call.

Q2. Which statement correctly distinguishes a frontend plugin from a backend plugin?

Show answer & explanation

Answer: B. A is the dangerous trap this whole competency exists to prevent — anything in a browser bundle is downloadable by anyone with a browser and dev tools open; "in practice it never leaves" is precisely the false comfort that leaks a real credential. C is false — many plugins ship as a pair, but the two halves install and version independently. D is backwards — tabs and cards are a frontend concern; the backend exposes routes, not UI.

Q3. A platform engineer needs to (a) add an entirely new top-level route reachable from the app's own sidebar, and (b) add a tab that appears only on Component entities of type website. Which two files does "Make changes to React code in Backstage App" point to for these two changes, respectively?

Show answer & explanation

Answer: A. B and D both scramble the two files' actual jobs — EntityPage.tsx has nothing to do with the app's own sidebar routes, and App.tsx has nothing to do with per-entity tabs. C is a category error: routing in a Backstage app is React code the curriculum explicitly names, not something declared in YAML. Keep the split simple: App.tsx is the app's own shell, EntityPage.tsx is what each entity's page looks like.

Q4. A team builds a custom card for the entity Overview page. It hardcodes its own raw CSS grid instead of Material UI's Grid, ignoring the layout every stock card on the page already uses. What's the most likely consequence, and which named competency does it bear on?

Show answer & explanation

Answer: B. A dodges the actual question by declaring a style preference rather than addressing consistency. C and D both fabricate consequences with no basis — raw CSS compiles fine, and nothing here is dark-mode-specific. The real, testable point is visual and structural: a custom layout that ignores the shared grid primitives sits awkwardly next to everything else on the page, because the rest of the app was never built to accommodate it.

Q5. A Software Template creates new repositories, grants team access, and opens pull requests on behalf of whoever clicks the golden-path button. Which credential pattern does the curriculum favor for the scaffolder backend that performs these actions, and why?

Show answer & explanation

Answer: B. A is a real anti-pattern the curriculum specifically warns against — tying powerful, repo-creating access to one employee's identity is a liability the moment they change teams or leave. C is false on its face; creating repositories and opening PRs is the scaffolder's whole job, and that requires reaching a remote Git host. D invents a mechanism Backstage doesn't use — the scaffolder acts with its own service identity, not the end user's session. B is the pattern this competency is actually testing: a scoped, revocable App credential the platform team controls.

Q6. A freshly generated app wires its backend with createBackend() and a series of backend.add(import(...)) calls inside packages/backend/src/index.ts, ending in backend.start(). What does this pattern reflect?

Show answer & explanation

Answer: B. A inverts the actual direction of travel — this pattern is the current default, not the deprecated one. C is simply false; this file is the backend process's own entry point. D fabricates a Kubernetes-specific meaning for a pattern that has nothing to do with Kubernetes reconciliation. Recognizing createBackend() and backend.add(...) on sight is worth marks on its own, since it's what every recent create-app output actually looks like.

// packages/backend/src/index.ts — the new backend system, plugin by plugin
import { createBackend } from '@backstage/backend-defaults';

const backend = createBackend();

backend.add(import('@backstage/plugin-catalog-backend'));
backend.add(import('@backstage/plugin-catalog-backend-module-github'));  // automated ingestion
backend.add(import('@backstage/plugin-kubernetes-backend'));             // the OTHER half of the tab
backend.add(import('@backstage/plugin-scaffolder-backend'));             // golden-path templates

backend.start();

Q7. Which file holds the logic that decides which tabs and cards appear on a Component of type service versus one of type website?

Show answer & explanation

Answer: B. A configures the app, not per-entity presentation logic. C describes one entity's own data, not the rules for what a whole class of entities displays. D is the backend's entry point, unrelated to which React components render for which entity type. EntityPage.tsx is specifically the file that branches on kind and type to decide layout — memorize its name and its job.

Q8. A team disables one default card on a third-party frontend plugin's page and swaps in their own card in the same slot, leaving the rest of that plugin's page untouched. Which single competency line item does this most precisely exercise?

Show answer & explanation

Answer: B. A, C and D each name a real domain, just the wrong one — nothing here touches local dev tooling, catalog data, or infrastructure config. Swapping out one default card for a custom one, while leaving the rest of a third-party plugin's page alone, is precisely what "customizing Backstage plugins" names as distinct from writing a plugin from scratch.

Development Workflow — 6 questions

☺ Like you're 10: This is muscle memory for running the workshop on your own laptop — install the tools, start the machine, and know exactly which half of it you're shipping in the box.

Twenty-four percent is a Node monorepo's day-to-day: create-app, Yarn workspaces, a real TypeScript gate, and a container image built from one specific Dockerfile. The reference sequence below is worth running yourself before attempting the six questions that follow.

# Create a portal — this is a monorepo you now OWN, not an install
npx @backstage/create-app@latest --path acme-portal

# Install dependencies (Yarn workspaces) and run both halves with hot reload
yarn install
yarn dev                       # app on :3000, backend on :7007

# Add a plugin: the frontend package AND its backend counterpart
yarn workspace app add @backstage/plugin-kubernetes
yarn workspace backend add @backstage/plugin-kubernetes-backend

# Type-check the whole workspace — a real error stops this
yarn tsc

# Production build, then a container image from the BACKEND Dockerfile
yarn build:all
docker image build . -f packages/backend/Dockerfile --tag acme/backstage:1.0

# Keep every @backstage/* package on one release line
npx @backstage/cli versions:bump

Q9. Running npx @backstage/create-app@latest produces a Yarn workspace. Which pairing correctly matches each package to what it actually contains?

Show answer & explanation

Answer: B. A swaps the two packages' actual roles. C and D both invent behavior create-app doesn't produce — the two packages are distinct from the very first scaffold, not mirrors, and neither requires a production build to exist. Knowing which package is which, cold, is the single most load-bearing fact in this whole domain.

Q10. After yarn install && yarn dev on a freshly created app, on which two ports do the frontend and backend serve by default, respectively?

Show answer & explanation

Answer: A. C simply reverses the correct pair, and B invents a port neither service defaults to. D is a fabrication about how the two processes relate — they're two distinct servers, and the frontend's dev server proxies API calls to the backend's own port rather than sharing one. :3000/:7007 is worth having cold.

Q11. A CI pipeline for a Backstage monorepo runs yarn tsc as a required step before yarn build:all. What does this step actually gate, and why does the curriculum treat it as a real gate rather than a formality?

Show answer & explanation

Answer: B. A undersells what tsc actually does — it's a compiler check, not a formatter. C conflates two separate tools; type-checking and testing are distinct steps with distinct commands. D invents an exemption that doesn't exist — if anything, production builds are exactly where you want this gate enforced. Because Backstage is TypeScript top to bottom, this one command is a genuine correctness gate, not decoration.

Q12. A team runs yarn build:all, then docker image build . -f packages/backend/Dockerfile --tag acme/backstage:1.0. Why is the image built specifically from the backend's Dockerfile, rather than from packages/app?

Show answer & explanation

Answer: A. B overstates the truth — the frontend absolutely is deployed, just bundled inside the backend's own image rather than shipped separately. C is a fabrication about Docker's capabilities with no real basis. D invents a Kubernetes-specific requirement the curriculum never makes. The real reason is architectural: the compiled React app is static assets the backend process serves itself, so one image, built from one Dockerfile, is the whole deployable unit.

Q13. A team wants both halves of Kubernetes-plugin functionality — the tab, and the data behind it. Which pair of commands correctly installs both?

Show answer & explanation

Answer: A. B and D both invent a global-install workflow Backstage doesn't use — plugins are workspace dependencies of a specific app, not machine-wide packages. C installs only the backend half twice, which never produces the frontend tab at all. A names the actual, correct pair — one command per workspace, one package per side.

Q14. What problem does npx @backstage/cli versions:bump most directly solve, and why does it matter operationally?

Show answer & explanation

Answer: B. A, C and D each name a real category of tooling task that simply isn't what this command does — formatting, secrets rotation, and package-manager migration are all unrelated concerns. versions:bump is specifically about keeping the @backstage/* family of packages aligned to one release, which is the practical upgrade story every portal owner eventually has to run.

Infrastructure — 5 questions

☺ Like you're 10: This is the wiring behind the front desk — which half talks to strangers, which half holds the safe combination, and what happens to the whole index if you unplug the wrong cable.

Twenty-two percent covers the client-server split, configuration layering, and what "production-ready" actually requires — a real database, real identity, and secrets that never sit in plaintext.

Q15. Which statement correctly describes Backstage's client-server architecture?

Show answer & explanation

Answer: A. B, C and D each invert or erase the split the competency is built around. A database connection and any credential belong on the backend precisely because the frontend is public code running on someone else's machine — that boundary is the whole architecture in one sentence.

Q16. A team ships a production Backstage instance on the default SQLite database "because it worked fine under yarn dev." What's the concrete operational risk, and what replaces it?

Show answer & explanation

Answer: B. A is precisely the false comfort this question is built to catch. C and D are both fabrications — SQLite has no licensing restriction and handles writes fine; the actual defect is durability. A pod restart wipes an ephemeral SQLite file, taking the whole catalog with it, which is why PostgreSQL is the only real answer for anything that has to stay up.

Q17. A team maintains app-config.yaml, app-config.local.yaml, and app-config.production.yaml, with secrets referenced as ${POSTGRES_PASSWORD}. What does this pattern demonstrate about Backstage configuration?

Show answer & explanation

Answer: B. A misdescribes the mechanism as simple concatenation rather than layered override. C and D both invent restrictions on which files get read and by whom, with no basis in how Backstage actually loads config. The real point is the pairing: layering handles environment differences, and ${ENV_VAR} substitution is specifically what keeps a real password out of a file that ends up in Git history.

# app-config.yaml — catalog.rules is an ALLOW-list, not a suggestion
catalog:
  rules:
    - allow: [Component, API, Resource]   # Template is missing — see Q18

Q18. Given the app-config.yaml snippet above, golden-path Software Templates have stopped appearing anywhere in the catalog UI, even though the template files themselves are still correctly registered. What's the most likely cause?

Show answer & explanation

Answer: B. A is unsupported — nothing in the symptom points at a missing plugin, and the question already states the template files are correctly registered. C and D are both fabrications with no basis in how the catalog works. catalog.rules is an explicit allow-list: omit a kind, and matching entities are silently dropped during ingestion — no error, just an empty result, which is exactly the trap this question sets.

Q19. Beyond simply pointing at a production-grade database, what does "Deploy Backstage to production" concretely require?

Show answer & explanation

Answer: B. A understates what "production" actually means for a service with real ownership data and real credentials flowing through it. C asserts the opposite of sound practice with no support. D fabricates a specific ingress requirement the curriculum never states — deployment topology is a choice, not a mandate. Identity and secret handling are the two concrete, testable pieces beyond "the database is real."

🦋 Mira's-eye view

"Every operations person who studies for this exam trips on the same thing eventually — expecting the trap to be about clusters and configuration, and instead it's about which package a file lives in. I stopped guessing and started asking one question first, every time: 'does this live in the browser, or does this live in Node?' Once I know which side of the wire I'm on, most of these questions answer themselves."

Catalog — 5 questions

☺ Like you're 10: This is the front desk's big index — every entry has a proper form, and the test wants to know exactly what happens when a page in that index goes missing or points at nothing.

Twenty-two percent, and the domain everyone talks about most while it's actually tied with Infrastructure, not ahead of it: entity kinds, annotations, the three ways entities get in, and troubleshooting ingestion when it goes wrong.

# catalog-info.yaml — at the ROOT of the checkout service repo
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: checkout
  annotations:
    backstage.io/techdocs-ref: dir:.          # lights up the Docs tab
    backstage.io/kubernetes-id: checkout      # wires the Kubernetes tab to real workloads
spec:
  type: service
  owner: group:default/payments-team

Q20. Which of the following is NOT one of the entity kinds the Backstage Catalog domain names?

Show answer & explanation

Answer: C. Component, System and Location are all real catalog entity kinds (alongside API, Resource, Domain, Group, User and Template). Deployment is a genuine, real term — but it's a Kubernetes API kind, not a Backstage catalog one, which makes it exactly the "adjacent, real-sounding but wrong box" trap this domain likes to set.

Q21. Given the catalog-info.yaml snippet above, what do the two annotations respectively control?

Show answer & explanation

Answer: B. A conflates two annotations with ownership, which is actually controlled by spec.owner, a separate field entirely. C swaps both annotations' real jobs for unrelated ones. D invents a kind restriction that doesn't exist — both annotations work on any entity kind that carries them. Annotations are free-form key/value pairs that specific plugins look for; these two are two of the most common examples.

Q22. A platform grows from 20 services to 400 across a GitHub organization. Manually registering each catalog-info.yaml URL by hand through "Register existing component" has become unmanageable. What's the correct fix, and why?

Show answer & explanation

Answer: A. B recommends the exact approach that doesn't scale — static locations are fine for a handful of org-wide files, not for hundreds of individually maintained URLs. C is simply false; automated ingestion is a named competency precisely because it exists. D treats manual registrations as something with a polling frequency to tune, which they don't have. Only a provider both discovers new entities and prunes stale ones without a human in the loop.

Q23. One entity's page shows the backstage.io/orphan annotation. A separate entity's spec.owner points at a Group that was never ingested. What do these two symptoms respectively indicate, and in what order should org data be ingested to avoid the second one?

Show answer & explanation

Answer: B. A invents a single cause for two structurally different symptoms. C swaps both annotations' actual meanings for unrelated failure types. D asserts a self-healing behavior that doesn't exist — a dangling reference just stays dangling until the Group is ingested. These are two of the three named troubleshooting symptoms in the curriculum, and the practical fix for the second is sequencing: ingest Groups and Users before the Components that claim to be owned by them.

Q24. Why is catalog-info.yaml conventionally placed at the root of the repository it describes, rather than centralized in one shared configuration repo?

Show answer & explanation

Answer: B. A fabricates a hard technical limitation — static locations exist specifically to register files that live wherever a team chooses. C ties the convention to an unrelated build concern. D invents a curriculum rule that doesn't exist; centralized locations are a legitimate, supported pattern for org-wide data. The real reason is about staying true over time: co-locating the description with the code is what keeps "who owns this, what does it depend on" from silently going stale.

🦋 Mira's ten-minute drill

Pick any repository you actually maintain. Write a catalog-info.yaml for it from memory — apiVersion, kind: Component, metadata.name, spec.type, spec.owner — then add one annotation you've never used before. Now name, out loud, which of the four CBA domains each field belongs to: the envelope is Catalog, and if you were wiring the plugin that reads your new annotation, that work would be Customizing. Ten minutes, and you'll have touched two of the four domains for real instead of just reading about them.

Scoring yourself, and what to do with a miss

☺ Like you're 10: Getting it wrong isn't the problem — not knowing why you got it wrong is. Every miss fits into one of four boxes, and each box has its own fix.

Count your correct answers and divide by 24 to get a rough percentage — this bank is too small to be a statistically precise rehearsal of the real paper, but it's plenty large enough to tell you whether a domain needs more reading before you attempt Mock Exam · Set 1.

⚠ 75% is the real bar — verify it officially

The Linux Foundation's Multiple Choice Exam FAQ states that a score of 75% or higher is required to pass any Linux Foundation multiple-choice exam, CBA included — see the CBA blueprint for the full logistics table, including the one figure that isn't published anywhere official: the question count. This site is an independent, unofficial study resource, not affiliated with the CNCF or The Linux Foundation. Treat 75% here as a useful training target, but confirm the current pass mark, format and every other exam-day detail on the official Linux Foundation CBA page before you register or pay for anything.

When you miss one, resist the urge to just note the correct letter and move on — that teaches you almost nothing. File it instead:

BucketSignatureThe fix
Didn't know itThe explanation names a term, file or command that's genuinely new to youContent gap — reread the matching section of the blueprint, then add it to flashcards
Knew it, misread itYou wince reading the explanation because you actually knew thisProcess gap — note which word you skipped (a negative, a qualifier), and underline lead-ins from now on
Confused two neighborsYou picked the concept next door — frontend for backend, Catalog for InfrastructureWrite a one-line discriminator for the pair and keep it somewhere you'll actually see it again
Guessed and got lucky, or unluckyYou can't explain why the other three options are wrong even though you picked correctly (or didn't)Treat it exactly like a miss — a right answer you can't defend is a gap wearing a disguise

Weigh whichever domain produced the most misses against its blueprint weight before deciding where to spend your next study session — a rough score in the 32%-weighted Customizing domain costs far more than the same rough score in a 22%-weighted one. The CBA study plan lays out exactly how to sequence reading, this bank, and the two mock exams across the days you have.

🎬 At Mission Control
🐰

Remy: Done! All twenty-four, three minutes flat.

🦋

Mira: And?

🐰

Remy: …I don't actually know why B was right on the annotations one. I just recognized the shape of it.

🦋

Mira: Then you've answered zero of them so far. Speed without the reasoning is a coin flip with extra steps.

👺

Gizmo: Easier trick — just install every plugin's frontend half and skip the backend one. Half the work, and the tab still shows up! 😈

🐢

Timmy: It shows up empty, Gizmo. That's not a shortcut, that's Q1 in disguise.

🐰

Remy: Fine. Back to the annotations question. Explaining it out loud until it actually makes sense.

🐢 Timmy's checkpoint

1. Why does this bank have eight Customizing questions but only five each on Infrastructure and the Catalog? 2. In Q1, why does the tab render at all if only the frontend half of a plugin was installed? 3. What's the difference between what Q9 (package roles) and Q15 (client-server split) are each testing? 4. Name the three distractor families the schematic on this page shows, besides the key itself. 5. What score should you treat as your training target, and where does that figure actually come from? 6. Give one example of a "confused two neighbors" miss from this bank, and its one-line discriminator. 7. Which two files together decide what a CBA-scoped catalog actually contains and displays, and how do their jobs differ?

Check your answers
  1. Because the bank mirrors the CBA's own domain weights (32/24/22/22) rather than splitting evenly — Customizing Backstage is the single heaviest domain at 32%, so it earns proportionally more practice.
  2. The frontend plugin's React code still renders the tab shell in the browser regardless of whether the backend half exists — React doesn't know the server-side route is missing until it actually tries to fetch data, which is when the request fails silently.
  3. Q9 tests whether you know which physical package (packages/app vs. packages/backend) holds which code. Q15 tests the architectural relationship between the two — who talks to whom over HTTP, and who's allowed to hold secrets.
  4. Wrong package (true, but about the other half of the split), absolute language ("always," "never," "only"), and confident fabrication (an invented command, flag or annotation that sounds real).
  5. 75%. It comes from the Linux Foundation's own Multiple Choice Exam FAQ, which applies to every LF multiple-choice exam including CBA — confirm it's still current on the official CBA page before you rely on it.
  6. Any pair from the bank works, for example: frontend vs. backend plugin — frontend is React, runs in the browser, and must never hold secrets; backend is Node, runs on the server, and may hold real credentials.
  7. catalog-info.yaml (per-entity, defines what an entity is — its kind, owner, annotations) and EntityPage.tsx (per-kind/type, defines what that entity's page shows). One describes the data, the other decides the display.