|  | 
|  | 1 | +--- | 
|  | 2 | +layout: post | 
|  | 3 | +title: 'Introducing Quarkus Backstage' | 
|  | 4 | +date: 2025-04-07 | 
|  | 5 | +tags: backstage, platform engineering  | 
|  | 6 | +synopsis: An introduction to the Quarkus extension for Backstage | 
|  | 7 | +author: iocanel | 
|  | 8 | +--- | 
|  | 9 | +:imagesdir: /assets/images/posts/quarkus-backstage/ | 
|  | 10 | + | 
|  | 11 | +ifdef::env-github,env-browser,env-vscode[:imagesdir: ../assets/images/posts/similarity-search-using-vector-dbs] | 
|  | 12 | + | 
|  | 13 | +== Introduction == | 
|  | 14 | +DevOps, for many, has been more of a linguistic rebranding than a true cultural shift. All too often, organizations stop at renaming their Ops team to DevOps and call it a day.  | 
|  | 15 | +But without real collaboration, without mutual understanding between developers and operators there is no actual DevOps. | 
|  | 16 | +Today, we witness the rise of Platform Engineering which is supposed to improve developer experience and productivity and act as an enabler for DevOps. | 
|  | 17 | + | 
|  | 18 | +The question is can this gap be bridged without tools that facilitate this collaboration? | 
|  | 19 | +Since, its early days Quarkus provided tools for developers that help them get closer to the Ops side of the house, but also communicate to the Ops what the  | 
|  | 20 | +dev actually needs. In this category we could classify the Quarkus Kubernetes and Helm extension. The latest addtion to this family of exntesion is now  | 
|  | 21 | +the https://docs.quarkiverse.io/quarkus-backstage/dev/index.html[Quarkus Backstage] extension that simplifies the integration of Quarkus and https://backstage.io[Backstage], one of the most prominent projects in the Platform Engineering space. | 
|  | 22 | + | 
|  | 23 | + | 
|  | 24 | +=== What is Backstage ? === | 
|  | 25 | +  https://backstage.io[Backstage] is an open framework for building developer portals. It was originally created by Spotify to help their engineers manage the complexity of Microservices and cloud-native architectures. | 
|  | 26 | +It builds developer portals that act as software component registries, allowing teams too easily: | 
|  | 27 | + | 
|  | 28 | +* Track component ownership | 
|  | 29 | +* Discover, explore and document services | 
|  | 30 | +* Communicate API changes | 
|  | 31 | +* Create and instantiate Software Templates (materializing DevOps practices) | 
|  | 32 | +* Aggregate all developer consoles in one place | 
|  | 33 | +and more | 
|  | 34 | + | 
|  | 35 | + | 
|  | 36 | +=== Backstage Challenges === | 
|  | 37 | +The idea is not new. I've seen similar tools come and go throughout my whole professional life. What makes https://backstage.io[Backstage] more relevant is the adoption of Microservice Architecture, which increases the  | 
|  | 38 | +amplifies the need for a developer portal. What's also not new is the challenge of using such a tool and making in it an integral part of the developer workflow. | 
|  | 39 | + | 
|  | 40 | +As always the challenge is the maintenance cost. | 
|  | 41 | +Maintenance, in terms of keeping the information served by https://backstage.io[Backstage] up to date. | 
|  | 42 | + | 
|  | 43 | +What happens when a Service adds / removes an API ?  | 
|  | 44 | +What happens when an API is migrated to new transport protocol ?  | 
|  | 45 | +What happens when we need to use a new framework version in our templates ? | 
|  | 46 | + | 
|  | 47 | +A development practice is as good as the tools that make it stick. | 
|  | 48 | + | 
|  | 49 | + | 
|  | 50 | +=== Quarkus Backstage Features === | 
|  | 51 | +How does https://docs.quarkiverse.io/quarkus-backstage/dev/index.html[Quarkus Backstage] help with the challenges above ? | 
|  | 52 | + | 
|  | 53 | +Short answer: By making Quarkus the Platform Engineers favorite application framework. | 
|  | 54 | +Long answer: While it's out of scope to solve all the challenges of https://backstage.io[Backstage], Quarkus aids the Platform Engineer in the following ways: | 
|  | 55 | + | 
|  | 56 | +* Generates Component and API entities for Quarkus applications | 
|  | 57 | +* Reverse engineers Templates from existing Quarkus applications | 
|  | 58 | +* Provides CLI for managing https://backstage.io[Backstage] entities | 
|  | 59 | +* Provides Dev Services for https://backstage.io[Backstage] | 
|  | 60 | +* Acts as a coordinator for all Quarkus DevOps extensions   | 
|  | 61 | + | 
|  | 62 | + | 
|  | 63 | +=== Using Quarkus Backstage === | 
|  | 64 | +https://docs.quarkiverse.io/quarkus-backstage/dev/index.html[Quarkus Backstage] comes in two shapes that can be used independently: | 
|  | 65 | + | 
|  | 66 | +* Quarkus CLI plugin | 
|  | 67 | +* Quarkus extension | 
|  | 68 | + | 
|  | 69 | + | 
|  | 70 | +==== As a CLI plugin ==== | 
|  | 71 | +Let's see how to use the https://docs.quarkiverse.io/quarkus-backstage/dev/index.html[Quarkus Backstage] CLI plguin in order to generate https://backstage.io[Backstage] entities for your Quarkus application. | 
|  | 72 | + | 
|  | 73 | +First, let's create a new Quarkus project: | 
|  | 74 | +[source,shell] | 
|  | 75 | +---- | 
|  | 76 | +quarkus create app hello-backstage -x rest | 
|  | 77 | +---- | 
|  | 78 | + | 
|  | 79 | +.... | 
|  | 80 | +Looking for the newly published extensions in registry.quarkus.io | 
|  | 81 | +----------- | 
|  | 82 | +selected extensions:  | 
|  | 83 | +- io.quarkus:quarkus-rest | 
|  | 84 | +
 | 
|  | 85 | +
 | 
|  | 86 | +applying codestarts... | 
|  | 87 | +📚 java | 
|  | 88 | +🔨 maven | 
|  | 89 | +📦 quarkus | 
|  | 90 | +📝 config-properties | 
|  | 91 | +🔧 tooling-dockerfiles | 
|  | 92 | +🔧 tooling-maven-wrapper | 
|  | 93 | +🚀 rest-codestart | 
|  | 94 | +
 | 
|  | 95 | +----------- | 
|  | 96 | +[SUCCESS] ✅  quarkus project has been successfully generated in: | 
|  | 97 | +--> /home/iocanel/blog/hello-backstage | 
|  | 98 | +----------- | 
|  | 99 | +Navigate into this directory and get started: quarkus dev | 
|  | 100 | +.... | 
|  | 101 | + | 
|  | 102 | + | 
|  | 103 | + | 
|  | 104 | +Then, navigate to the project directory: | 
|  | 105 | + | 
|  | 106 | +From within your Quarkus project, run the following command: | 
|  | 107 | + | 
|  | 108 | +[source,shell] | 
|  | 109 | +---- | 
|  | 110 | +quarkus plugin add io.quarkiverse.backstage:quarkus-backstage-cli:0.6.0 | 
|  | 111 | +---- | 
|  | 112 | + | 
|  | 113 | +.... | 
|  | 114 | +Looking for the newly published extensions in registry.quarkus.io | 
|  | 115 | +Added plugin: | 
|  | 116 | +    Name      	 Type  	 Scope   	 Location                                             	 Description 	 | 
|  | 117 | + *  backstage 	 maven 	 project 	 io.quarkiverse.backstage:quarkus-backstage-cli:0.6.0 	             	 | 
|  | 118 | +.... | 
|  | 119 | + | 
|  | 120 | + | 
|  | 121 | +If you want to install it globally and make it available for all your Quarkus projects, run the following command: | 
|  | 122 | + | 
|  | 123 | +[source,shell] | 
|  | 124 | +---- | 
|  | 125 | +quarkus plugin add io.quarkiverse.backstage:quarkus-backstage-cli:0.6.0 --user | 
|  | 126 | +---- | 
|  | 127 | + | 
|  | 128 | +.... | 
|  | 129 | +Added plugin: | 
|  | 130 | +    Name      	 Type  	 Scope 	 Location                                             	 Description 	 | 
|  | 131 | + *  backstage 	 maven 	 user  	 io.quarkiverse.backstage:quarkus-backstage-cli:0.6.0 	             	 | 
|  | 132 | +
 | 
|  | 133 | +[WARN] 🔥  Plugin was added in the user scope, but another with the same name exists in the project scope! | 
|  | 134 | +The project scoped one will take precedence when invoked from within the project! | 
|  | 135 | +.... | 
|  | 136 | + | 
|  | 137 | + | 
|  | 138 | +To get an idea of the available commands, run: | 
|  | 139 | +[source,shell] | 
|  | 140 | +---- | 
|  | 141 | +quarkus backstage --help | 
|  | 142 | +---- | 
|  | 143 | + | 
|  | 144 | +.... | 
|  | 145 | +Backstage CLI | 
|  | 146 | +Usage: backstage [-h] [COMMAND] | 
|  | 147 | +  -h, --help   Display this help message. | 
|  | 148 | +Commands: | 
|  | 149 | +  entities  Backstage Entities | 
|  | 150 | +  location  Backstage Location | 
|  | 151 | +  template  Backstage Template | 
|  | 152 | +  mcp       Start backstage MCP server. | 
|  | 153 | +.... | 
|  | 154 | + | 
|  | 155 | + | 
|  | 156 | +To generate a https://backstage.io[Backstage] entities for your Quarkus application, run the following command: | 
|  | 157 | + | 
|  | 158 | +[source,shell] | 
|  | 159 | +---- | 
|  | 160 | +quarkus backstage entities generate | 
|  | 161 | +---- | 
|  | 162 | + | 
|  | 163 | +.... | 
|  | 164 | +Backstage entities generated: | 
|  | 165 | + API Version           	 Kind                  	 Name            	 UUID 	 | 
|  | 166 | + backstage.io/v1alpha1 	 Component             	 hello-backstage 	      	 | 
|  | 167 | +
 | 
|  | 168 | +.... | 
|  | 169 | + | 
|  | 170 | + | 
|  | 171 | + | 
|  | 172 | +[source,shell] | 
|  | 173 | +---- | 
|  | 174 | +cat catalog-info.yaml | 
|  | 175 | +---- | 
|  | 176 | + | 
|  | 177 | +.... | 
|  | 178 | +  | 
|  | 179 | +apiVersion: backstage.io/v1alpha1 | 
|  | 180 | +kind: Component | 
|  | 181 | +spec: | 
|  | 182 | +  type: application | 
|  | 183 | +  lifecycle: production | 
|  | 184 | +  owner: user:guest | 
|  | 185 | +metadata: | 
|  | 186 | +  name: hello-backstage | 
|  | 187 | +  labels: | 
|  | 188 | +    app.kubernetes.io/name: hello-backstage | 
|  | 189 | +    app.kubernetes.io/version: 1.0.0-SNAPSHOT | 
|  | 190 | +    app.quarkus.io/version: 3.18.3 | 
|  | 191 | +  tags: | 
|  | 192 | +  - java | 
|  | 193 | +  - quarkus | 
|  | 194 | +.... | 
|  | 195 | + | 
|  | 196 | +The generated component is available under the `catalog-info.yaml`. The file can | 
|  | 197 | +be added to git, pushed to a git repository and then registered in Backstage. | 
|  | 198 | + | 
|  | 199 | +Pretty much any Backstage installation should be able to read the component from github. | 
|  | 200 | +To do the registration, starting from the Home screen: | 
|  | 201 | + | 
|  | 202 | +* Click on the "Create" button | 
|  | 203 | +* Click on "Register existing component" | 
|  | 204 | +* Paste the link to the `catalog-info.yaml` file in the git repository | 
|  | 205 | +* Click on "Analyze" | 
|  | 206 | +* Click on "Register"   | 
|  | 207 | + | 
|  | 208 | +The registered component should look like: | 
|  | 209 | + | 
|  | 210 | +image::hello-backstage-component-view.png[scaledwidth=100%] | 
|  | 211 | + | 
|  | 212 | +This is not very impressive given that the file could be generated by Backstage itself. | 
|  | 213 | +However, that would be the last thing that Backstage would do for you.  | 
|  | 214 | +What would happen next time your application changes and changes need to be reflected in Backstage ? | 
|  | 215 | + | 
|  | 216 | +Let's expose an API for our application. We'll add the openapi extension and we'll configure it so | 
|  | 217 | +that it generates the openapi schema in the same directory as the `catalog-info.yaml` file. | 
|  | 218 | + | 
|  | 219 | +[source,shell] | 
|  | 220 | +---- | 
|  | 221 | +quarkus ext add smallrye-openapi | 
|  | 222 | +echo "quarkus.smallrye-openapi.store-schema-directory=." >> src/main/resources/application.properties  | 
|  | 223 | +---- | 
|  | 224 | + | 
|  | 225 | +.... | 
|  | 226 | +Looking for the newly published extensions in registry.quarkus.io | 
|  | 227 | +[SUCCESS] ✅  Extension io.quarkus:quarkus-smallrye-openapi has been installed | 
|  | 228 | +.... | 
|  | 229 | + | 
|  | 230 | + | 
|  | 231 | +Let's rebuild the application and see how our `catalog-info.yaml` file looks like: | 
|  | 232 | + | 
|  | 233 | +[source,shell] | 
|  | 234 | +---- | 
|  | 235 | +cat catalog-info.yaml | 
|  | 236 | +---- | 
|  | 237 | + | 
|  | 238 | +.... | 
|  | 239 | +  | 
|  | 240 | +apiVersion: backstage.io/v1alpha1 | 
|  | 241 | +kind: API | 
|  | 242 | +spec: | 
|  | 243 | +  type: openapi | 
|  | 244 | +  lifecycle: production | 
|  | 245 | +  owner: user:guest | 
|  | 246 | +  definition: | 
|  | 247 | +    $text: ./openapi.yaml | 
|  | 248 | +metadata: | 
|  | 249 | +  name: hello-backstage-api | 
|  | 250 | +---  | 
|  | 251 | +apiVersion: backstage.io/v1alpha1 | 
|  | 252 | +kind: Component | 
|  | 253 | +spec: | 
|  | 254 | +  type: application | 
|  | 255 | +  lifecycle: production | 
|  | 256 | +  owner: user:guest | 
|  | 257 | +  providesApis: | 
|  | 258 | +  - hello-backstage-api | 
|  | 259 | +metadata: | 
|  | 260 | +  name: hello-backstage | 
|  | 261 | +  labels: | 
|  | 262 | +    app.kubernetes.io/name: hello-backstage | 
|  | 263 | +    app.kubernetes.io/version: 1.0.0-SNAPSHOT | 
|  | 264 | +    app.quarkus.io/version: 3.18.3 | 
|  | 265 | +  tags: | 
|  | 266 | +  - java | 
|  | 267 | +  - quarkus | 
|  | 268 | +.... | 
|  | 269 | + | 
|  | 270 | +The refreshed component now looks like: | 
|  | 271 | + | 
|  | 272 | +image::hello-backstage-component-with-api-view.png[scaledwidth=100%] | 
|  | 273 | + | 
|  | 274 | + | 
|  | 275 | +==== As an extension ==== | 
|  | 276 | +An alternative to using the https://docs.quarkiverse.io/quarkus-backstage/dev/index.html[Quarkus Backstage] CLI plugin is to use the https://docs.quarkiverse.io/quarkus-backstage/dev/index.html[Quarkus Backstage] extension. | 
|  | 277 | +Usually, an extension is needed when the application itself requires a library, a framework, or a code | 
|  | 278 | +generator. In this case, the extension adds the Backstage entity generation to the application build process. | 
|  | 279 | + | 
|  | 280 | +To add the extension to the project: | 
|  | 281 | + | 
|  | 282 | +[source,shell] | 
|  | 283 | +---- | 
|  | 284 | +quarkus ext add io.quarkiverse.backstage:quarkus-backstage:0.6.0 | 
|  | 285 | +---- | 
|  | 286 | + | 
|  | 287 | +.... | 
|  | 288 | +[SUCCESS] ✅  Extension io.quarkiverse.backstage:quarkus-backstage:0.6.0 has been installed | 
|  | 289 | +.... | 
|  | 290 | + | 
|  | 291 | + | 
|  | 292 | +At the time of writing the extension is not part of the Extension catalog, and thus it needs to be added using | 
|  | 293 | +its full maven coordinates. | 
|  | 294 | + | 
|  | 295 | +Now, let's remove the existing `catalog-info.yaml` file and let's generate a new one using the extension: | 
|  | 296 | + | 
|  | 297 | +[source,shell] | 
|  | 298 | +---- | 
|  | 299 | +rm catalog-info.yaml | 
|  | 300 | +ls -al | 
|  | 301 | +---- | 
|  | 302 | + | 
|  | 303 | +.... | 
|  | 304 | +total 76 | 
|  | 305 | +drwxr-xr-x 7 iocanel users  4096 Apr  3 19:29 . | 
|  | 306 | +drwxr-xr-x 3 iocanel users  4096 Apr  3 16:38 .. | 
|  | 307 | +-rw-r--r-- 1 iocanel users    75 Apr  3 16:38 .dockerignore | 
|  | 308 | +drwxr-xr-x 8 iocanel users  4096 Apr  3 19:21 .git | 
|  | 309 | +-rw-r--r-- 1 iocanel users   423 Apr  3 16:38 .gitignore | 
|  | 310 | +drwxr-xr-x 3 iocanel users  4096 Apr  3 16:38 .mvn | 
|  | 311 | +-rwxr-xr-x 1 iocanel users 11172 Apr  3 16:38 mvnw | 
|  | 312 | +-rw-r--r-- 1 iocanel users  7697 Apr  3 16:38 mvnw.cmd | 
|  | 313 | +-rw-r--r-- 1 iocanel users   710 Apr  3 19:19 openapi.json | 
|  | 314 | +-rw-r--r-- 1 iocanel users   454 Apr  3 19:19 openapi.yaml | 
|  | 315 | +-rw-r--r-- 1 iocanel users  5332 Apr  3 19:31 pom.xml | 
|  | 316 | +drwxr-xr-x 3 iocanel users  4096 Apr  3 16:39 .quarkus | 
|  | 317 | +-rw-r--r-- 1 iocanel users  2053 Apr  3 16:38 README.md | 
|  | 318 | +drwxr-xr-x 4 iocanel users  4096 Apr  3 16:38 src | 
|  | 319 | +drwxr-xr-x 4 iocanel users  4096 Apr  3 19:21 target | 
|  | 320 | +.... | 
|  | 321 | + | 
|  | 322 | + | 
|  | 323 | +Finally, let's rebuild: | 
|  | 324 | + | 
|  | 325 | +And check that the file is properly generated: | 
|  | 326 | + | 
|  | 327 | + | 
|  | 328 | +=== Conclusion === | 
|  | 329 | +https://backstage.io[Backstage] is a great tool for organizations to survive the Microservice Architecture chaos. | 
|  | 330 | +A tool, can't help if it's not used nor if it's feed with stale data. | 
|  | 331 | +The https://docs.quarkiverse.io/quarkus-backstage/dev/index.html[Quarkus Backstage] project was created to leverage the power of the Quarkus build system in order to keep | 
|  | 332 | +the catalog entities of Quarkus components up to day. In Quarkus lingo, to bring "Platform Engineer joy". | 
|  | 333 | + | 
|  | 334 | +A video walkthrough on the basics of the extension is available at https://www.youtube.com/watch?v=XAiF-opDtpw[here]. | 
0 commit comments