One of the great technologies included in Tanzu Application Platform is the Learning Center Operator.
Learning Center provides a platform for creating and self-hosting workshops. It allows content creators to create workshops from markdown files that are displayed to the learner in a terminal shell environment with an instructional wizard UI. The UI can embed slide content, an integrated development environment (IDE), a web console for accessing the Kubernetes cluster, and other custom web applications.
TLDR
tanzu accelerator create lc-workshop \
--git-repository https://github.com/vrabbi/learning-center-workshop-accelerator.git \
--git-branch main \
--display-name "Learning Center Workshop" \
--icon-url https://avatars.githubusercontent.com/u/58150231?s=280&v=4
How To Build A Workshop Officially
To get started building a workshop, VMware provide a zip file on Tanzu Network with samples for getting started.
While the idea of a sample repository is great, the content is not up to date, and does not work as is.
The changes one would be required to make include, changing the apiVersion for the kubernetes versions of the Custom resources, change the image being used as the base image as it is not compatible, update the Dockerfile for building a custom base image if needed to use the compatible base image, and then they can start building out there custom content.
Application Accelerator To The Rescue
As I have been working on building out a lot of workshops for many different technologies and use cases, I wanted to streamline the process of getting started on a new workshop, and immediately thought of Application Accelerator as a great way to set this up.
When approaching the task, I started looking deeply into the docs of learning center and seeing what could be configured, and the amount of customization capabilities is huge, and would be way too much for an accelerator, so I decided to limit the scope to only the main fields i typically would want to have control over, and then if additional customizations are needed afterwards, that can be done manually on a case by case basis.
What does the UX look like
The user first will go to TAP GUI or to their VSCode where the application accelerator plugin has been configured and click on the relevant accelerator:

Next they are greeted with a form to fill out basic information about the workshop:

These settings are the most general and settings, and are required for every workshop you generate.
Next we include settings about the workshop in terms of difficulty, duration, and max concurrent sessions:

We then have some resource settings that are set to the operators defaults, but depending on your use case, may need to be changed. This includes, resource quotas for the sessions namespace, as well as how much memory to allocate to the pod that the workshop will be running in:

We then get to the workshop environment settings, where we can enable or disable different features in the environment based on the needs of our specific workshop.
This includes things like the terminal layout, whether to include the embedded VSCode instance, enabling a kubernetes UI Console and if so choosing whether to use octant or the kubernetes default dashboard, as well as some more interesting and specialized features like deploying a container registry per session, or adding docker to the workshop environment, to allow users to build images within the workshop itself:

We then have a mandatory field one must fill out with the list of workshop exercises they want to build. This list effect the generated files, as we need to update in multiple files, what modules we want in our workshop, so doing it via the accelerator, greatly streamlines the process of building a workshop, and allows you to focus solely on the content itself without dealing with the configuration needed to make it come together:

And finally we have the last section which is gated behind an advanced features checkbox, as it is not really needed to be configured in most cases, but can be extremely beneficial when you need these settings:

Behind this advanced features checkbox, I have currently added 3 features.

Using vCluster
A really great thing in learning center is the level of isolation we get between each workshop session, which is needed as we are allowing users to dynamically create workshop sessions in our shared environment. Learning center does this by isolating each workshop session to a dedicated namespace.
While this is great for many use cases, when building workshops around kubernetes technologies, many times we may need our users to be able to have higher level permissions then we can offer them in the shared environment. This could include things like installing CRDs, creating namespaces and so on.
A great solution for this is to integrate our workshop with another really cool project called vCluster which is build and maintained by Loft.
vCluster enables us to deploy a virtual kubernetes cluster on a real kubernetes cluster, which basically entails deploying a kubernetes control plane using K3s a lightweight distribution of kubernetes in a pod, alongside another component called a syncer.
The syncer is in charge of syncing resources between the hosting cluster (where our workshop instance is running) and the virtual cluster running on top of it when needed.
The reason this is so cool, is that while in the virtual cluster, we can provide our end users, with cluster admin access, the pods themselves which get synced down to the actual cluster in order to run, are all confined into a single namespace. this means that we can still benefit from the namespace isolation we get in Learning Center, while unblocking our users, from playing around with kubernetes with full admin rights.
Installing Carvel CLIs
This can be extremely helpful when dealing with kubernetes based workshops, especially in the Tanzu ecosystem, where carvel is everywhere!
Because carvel is a rapidly growing and evolving toolset, keeping a workshop environment up to date with the latest carvel tools installed can be a challenge. therefore in this approach, I added a script that runs when the workshop session is created that will download the latest binaries and install them for you. While this does slow down the startup time of a workshop slightly, i believe the tradeoff is worth it in many cases, and it prevent you from needing to build and maintain a custom container image for the workshop.
Installing Kubectl Plugins
While kubectl is a very powerful CLI on its own, one of the key strengths it has is actually the ease of extending it via plugins.
Plugins can be installed and configured manually, or one could use krew, which is the kubectl plugin management tool, which itself is a kubectl plugin!
When enabling this feature, krew gets installed in the workshop, and a set of some of my favorite plugins get installed as well.
An example of a plugin I have included is the view-secret plugin.
Many tasks we do in kubernetes are repetitive tasks, and some of them are not so fun to do from the CLI. for example, if a want to get the value of a key in a secret i would typically need to run a command similar to:
kubectl get secret my-secret -o json | jq -r .data.my_key | base64 --decode
While this works, would it be nice to have a way of doing it without shelling out to other commands, and with a much shorter syntax like:
kubectl view-secret my-secret my_key
Well this is just an example of one of the 9 plugins I have included!
Back to the UX
Now that the form has been filled out, lets explore the files this will generate for us

As we can see, we have a full layout of our workshop generated for us, with all the configuration needed.
If we look for example at the file modules.yaml under the workshop folder we can see that this required file, contains basically the navigation and flow of our workshop pointing at the relevant markdown files of each exercise.

By templating this out, It simply streamlines the process, and make your only requirement for building the workshop to be writing the content itself.
This same thing goes for the fact that we auto generate the markdown files for each of the exercises you have filled out in the form, making it easy for you to simply go to the workshop/content/exercises directory and to begin adding your content.

One other key thing i added, is some documentation to help you start building the workshop content.
The docs for learning center are very detailed and as mentioned, the ammount of possible customizations is huge! As such i decided to copy into the repo, the pages from the documentation that i believe are the most useful for a workshop author so that the docs are accessible to them in an easy and streamlined manner.

The Final Step
The final step is to push this content to git and start working on the content.
As of TAP 1.3 we can now have TAP GUI automatically create a git repository for us and push the generated accelerator based project to it!

Once we fill out the details of what we want the repo called and under which user or org it should be created, we can generate the accelerator:

And within just a few seconds:

We can now clone the repository locally and start working on the content!
Summary
This I believe is a great example of how Application Accelerator can be extremely useful for use cases that are not necessarily code or dev related.
Learning Center is a truly awesome piece of technology and bringing a simple UX for getting started building a workshop can hopefully help people start to use it more and more for their own unique use cases.
Building labs, is a great way of introducing new technologies or for teaching new company standards to your users, and is also a great way to do workshops where we don’t need each participant to pre configure a bunch of things on his machine to get hands on experience!
If you want to try out the accelerator it can be found in the following git repository and can be simply added to your environment via one simple command:
tanzu accelerator create lc-workshop \
--git-repository https://github.com/vrabbi/learning-center-workshop-accelerator.git \
--git-branch main \
--display-name "Learning Center Workshop" \
--icon-url https://avatars.githubusercontent.com/u/58150231?s=280&v=4