Skip to main content

How to Build a Self-Service Platform on Upbound: Day 1

The previous blog post in this series showcased how Upbound makes it easy for organizations to get up and running with their first instance of Crossplane in minutes. Today’s entry in the series covers a typical Day 1 operation for users of Upbound: configuring your control planes for GitOps flows.

GitOps is an approach for managing a system by declaratively describing desired resources’ configurations in Git and using controllers to realize the desired state. Crossplane is compatible with this pattern and it’s strongly recommended you integrate GitOps in your platforms built on Crossplane–and you can do this with Upbound managed control planes!

Want to learn more? Here are the links to other blog posts showcasing new features for platform operators:

GitOps and Crossplane

Every managed control plane in Upbound comes with a control plane portal by default. This portal is a convenient CRUD (create, read, update, and delete) graphical interface to interact with the APIs on your control plane. Think of using the control plane portal as talking directly to your control plane. The GitOps flows we will describe in this post are yet another flow you can use to interact with your control plane, and likely one you will want to use for production scenarios.

Integrating GitOps flows with Crossplane is useful in three ways:

  1. You can use git to store the definition of your control plane configuration. This is something users of Upbound get as a built-in feature of Upbound, since the platform supports automatically syncing the definition of your control plane’s configuration from GitHub. Read about how control plane configurations work on Upbound.
  2. You can use Git as an interface to invoking your control plane’s APIs. Whenever a user needs a resource from your control plane, a claim must get created. Claims themselves are resources with a configuration (a spec), and as such can and should be declaratively stored in Git. This is the one we’ll demonstrate in today’s blog.
  3. Use Git to store the infrastructure definition that backs your control plane. In Upbound’s Crossplane Architecture Framework, we call this out as a third way you can integrate with git. In the case of Upbound, this is not relevant because managed control planes by nature shift this responsibility away from you and over to Upbound.

By the end of this blog, our goal is to have:

  1. A managed control plane with a custom API running in Upbound.
  2. A GitHub repository that is the source of all the claims I want to have against my control plane’s APIs.
  3. An engine that observes when new claims get committed to my Git repository and syncs them over to my control plane. Conversely, when a claim is removed from the Git repository, it will get cleaned up from my control plane.
  4. Once a claim is on the control plane, the control plane will fulfill its API contract and create all the resources that need composing.


If you want to follow along with this blog post, it requires that you have an account on Upbound and have already created a managed control plane. The configuration you choose for your control plane doesn’t matter; pick whichever one you like. You should also make sure you have installed the up CLI on your machine.

Set up a GitOps engine

If you are already familiar with Kubernetes, it's likely you’ve heard of the GitOps pattern. There is already popular tooling available in the Kubernetes ecosystem to solve these problems. Argo CD and Flux are two examples of projects in the Kubernetes ecosystem commonly used for GitOps. You can use them in tandem with Upbound managed control planes to achieve GitOps flows.

Today, we demonstrate how to integrate Flux. Check back to our blog or documentation for an update when Argo CD integration becomes available.

In order to integrate Flux with a managed control plane, you first need an instance of Flux installed into a Kubernetes cluster. Flux is not installable inside of Upbound, so you need to provision it on your own cloud infrastructure. For production scenarios, it’s recommended you designate a cluster for running Flux. For the purpose of this blog, we installed Flux into a local kind cluster.

You install Flux into a cluster by bootstrapping it and pointing it at the repo it should monitor. You would run something like this (assuming you are connecting to GitHub):

Once Flux is installed, you should see pods deployed in the flux-system namespace.

Connect Flux to your managed control plane

When Flux observes a change in a Git repository, it syncs those changes to a target. In a traditional installation of Flux on Kubernetes, the assumption is that Flux is installed as an add-on in the same cluster you wish to sync changes to. That’s not the case for a managed control plane on Upbound, so you need to tell Flux about the managed control plane. You do this by providing the managed control plane’s API server endpoint.

All managed control planes have a deterministic Kubernetes API server endpoint in the following form:

Fetch your managed control plane’s API server endpoint so you can provide it to Flux. In the step below, use the up CLI to fetch the kubeconfig of your managed control plane and write it to a file. The up CLI uses personal access tokens to authenticate to Upbound. You can generate a personal access token from the Upbound Console. This is the token passed in the following command:

Next, create a secret on the external Kubernetes cluster where you installed Flux. This secret should contain the kubeconfig from the previous step.

Then, define a new Flux Kustomization resource representing your managed control plane and apply to your Flux cluster. The example manifest below assumes you store claims in your Git repository under a claims folder.

Finally, apply a Kustomization to the cluster where Flux is running to tell Flux about this resource.

Use Git to drive control plane interactions

You can now commit claims in the Git repository that Flux is monitoring. When you do, Flux will sync them to your managed control plane running in Upbound. Your control plane will create and compose resources accordingly.

What’s Next?

To get the full rundown on the end-to-end flow of building an internal developer platform using control planes, I explain it in depth in this webinar with the Linux Foundation, “//TODO Enable Developer Self-Service Using Kubernetes and Control Planes Powered by Crossplane”.

To follow along with this blog series as well as the webinar above, be sure to sign up for a free trial of Upbound today. You will be able to create and configure your first managed control plane in minutes!