A hands-on look into tools and their integrated usage can help kickstart your knowledge about Platform Engineering patterns. Therefore let's dive into two top frameworks when it comes to Platform Engineering today: Crossplane & ArgoCD. Both alone can already be great choices, but combining their powers can unlock a whole new level.
Should we talk about tooling in Platform Engineering?
There are lots of great claims about platform engineering: Why you should think in products instead of projects, why application developers are your customers, the importance of golden paths etc. Platform Engineering is essentially another mind shift that your organization needs to adapt to, but it’s also often said that it's not about tooling. Tooling isn't important.
If you’ve been around in the industry for a bit longer you know these kinds of claims. They're right. But at the same time, it is also missing something important. Why? At some point, you'll need tooling. You'll also need a framework to build abstractions that your overburdened application developers can use. This point in time comes faster than you might think when trying to implement Platform Engineering in your organization, people will soon start to ask you:
How do we build that platform? With the tools we're already using? New tooling? How does it integrate into our existing landscape?
And:
How can we provide our developers with abstractions they love to use?
So why not have a look into a concrete setup of frameworks you could use to kickstart the process in your Platform Engineering initiative? Something you could refer to, look at, play with, criticise, and just build a whole lot more refined in the end.
Personally, I'm a big fan of practical solutions and integrations of tooling. With this, you can really learn hands-on and differentiate marketing speech from reality. I also tend to learn concepts much better, if I see (or better: build) an actual working solution. It might not be perfect, but I see concepts in action and I get real answers to the before-mentioned questions. So let's have a look at some promising tools & how to actually use them combined.
Hand over human oversight to the Control Plane
One of the most promising frameworks in the space of Platform Engineering is Crossplane. This CNCF Incubating (and soon to be Graduated) project brings a whole new look at infrastructure provisioning and management to the table. Sure Crossplane could provision infrastructure in a huge variety of cloud providers. But that's something we're already used to in tools like Terraform / OpenTofu and Pulumi, but Crossplane also introduces a completely new approach to managing your infrastructure (and even more): the Control Plane pattern.
With Crossplane this pattern heavily relies on Kubernetes and uses its fundamental capabilities. You define the desired state of your infrastructure through manifests. The Crossplane operator will take care of creating and maintaining the infrastructure in the state like you defined beforehand.
The best explanation for this behavior I found is a thermostat you're used to from your heating system at home. In technical terms, the operator pattern in Kubernetes uses a reconciliation loop to implement kind of a thermostat. In the Control Plane pattern, the hand to define the temperature is represented by someone or something using Kubernetes manifests to declare desired behavior.
Figure 1: Crossplane reconciliation loop (blog.crossplane.io/crossplane-vs-terraform)
Practical Platform Engineering with Crossplane
The second key advantage of Crossplane to other tools is that it brings in another layer of abstraction: Compositions. They represent a mighty framework for platform teams to build their own organization specific abstractions, including the possibility to create multi-cloud setups. Compositions are defined through Composite Resource Definitions (XRDs) which are essentially Custom Resource Definitions (CRDs) in Kubernetes. They are solely in the ownership of the platform team.
Additionally, another Crossplane building block enables application developers to request their needed infrastructure through the control plane: Composite Resource Claims (XRC) or "Claims". They match a developer's view on infrastructure,and because of that these Claims are mostly designed to be quite simple. Imagine a developer needs a Postgres database, then the Claim manifest is made up of just a few lines of YAML. The same is true for a full-blown EKS cluster in AWS, where a developer might define the amount of nodes, the region, and the cluster name.
Figure 2: Crossplane basic concepts (blog.upbound.io/composing-a-platform-by-patching-crossplane-resources)
So in essence using Crossplane, we'll get 3 ingredients that play a key role in a platform engineering initiative:
- Multi-cloud capable infrastructure provisioning
- Control plane to take care of creating & maintaining our infrastructure
- Compositions/XRDs & Claims as a framework to build platform abstractions
We saw that Crossplane makes for a great fit in our Platform Engineering initiative. But it shouldn’t be used alone. And that is because in recent years the principles of GitOps have become indispensable. But what is actually the key point of GitOps? And how does it integrate with a Control Plane framework like Crossplane?
Combining the Control Plane with GitOps
To answer these questions we need to understand the difference between GitOps and the classic CI/CD approach. When we think about the classic approach both the application developers and the platform teams work on code that resides in a Git repository. On the developer side, this code is tested, built, and deployed through the CI/CD pipeline.
In the realms of the platform team, the pipeline is used to provision infrastructure step by step. Think of an EKS cluster where you would first need to create a network incl. VPC, SecurityGroups & Rules, then you would provision a NodeGroup with VMs in the second pipeline step. Once the pipeline has run successfully, all needed infrastructure components should be provisioned. And right at this point configuration drift starts to kick off. There are remedies for that, but these often involve human oversight.
Figure 3: Classic CI/CD approach incl. infrastructure provisioning (codecentric.de/wissens-hub/blog/from-classic-cicd-to-gitops)
This configuration drift is one of the reasons to implement GitOps. With GitOps we hand over the human oversight to an operator often running in Kubernetes. We trust the reconciliation loop of tools like ArgoCD, FluxCD, or Sveltos to make sure that the state defined in our Git repositories matches the state in our cluster.
Sound familiar? Exactly. This approach reminds us of the above-mentioned Control Plane pattern, where an operator takes care of creating and maintaining our infrastructure in a declared state. So why shouldn't we combine both approaches into a bi-directional reconciliation loop for our infrastructure? Essentially unlocking GitOps for Platform Engineering!
Crossplane & ArgoCD: a match made in heaven
Comparing Figure 3 and the classic CI/CD approach with Figure 4 you should notice a few crucial differences. First, we have a third pipeline to provision a second "management cluster", which implements our Control Plane pattern. Additionally, we can spot two "thermostats". One at the "Git deploy repo", where the deployment configuration for our applications resides. This is one of two Git repositories ArgoCD observes and deploys right after any change has been made there.
The second thermostat is the "Git Crossplane APIs" repo, where the current state of our infrastructure resides. If Argo spots a change here, it applies the new manifest versions to our management cluster. The Control Plane implemented by Crossplane notices the changes immediately and makes sure the modifications get provisioned to our cloud infrastructure providers. Now our bi-directional reconciliation loop is alive! That also puts our Git into the position of the central state for all our infrastructure. Any changes in our repository will be reflected to the cloud infrastructure our applications are deployed to. If you want to learn more about the exact steps to take, have a look at this post or you can take a look at the example implementation available on GitHub.
Figure 4: Crossplane & ArgoCD implement a bi-directional reconciliation loop (from my latest talk at ContinuousLifecycle).
Another benefit could be found in this setup. Observe the application pipeline and the infrastructure pipeline, where the latter is used to create Crossplane compositions. The important point is that both pipelines look exactly the same! Both implement a testing step, where either application code or infrastructure code is tested. With Crossplane you can use tools like kuttl or Kyverno Chainsaw to test your Compositions.
The second step in both app and infra pipelines build a container image. This is obvious in the app pipeline. It is a great design choice in Crossplane, where a Crossplane Package is also just an image that will be pushed to our container registry. The third step in both pipelines implement a commit to the respective configuration repository. These are observed by ArgoCD. If there are changes this GitOps operator takes care to apply them. Regardless if it is originated from the development or the platform teams. This means the whole organization picks up on equal practices which should greatly reduce communication overhead.
Key takeaways
Handing over human oversight to a machine can feel overwhelming at first, but the Control Plane pattern has your back. As one of the key implementers, Crossplane will take care of creating & maintaining your infrastructure using a Kubernetes-based reconciliation loop. It doesn't stop there, as it brings in a framework for your Platform Engineering initiative, leveraging Compositions/XRDs & Claims as a framework to build platform abstractions. This also enables organization specific multi-cloud setups.
Combining Crossplane with a GitOps tool like ArgoCD eliminates configuration drift and sets Git as the single source of state for your infrastructure. This is achieved by implementing a bi-directional reconciliation loop, where the two operators ArgoCD and Crossplane work together hand in hand. As a huge bonus, the communication will get a whole lot easier between your developers and platform teams, both use the same approach for developing applications as for provisioning infrastructure.
So why not give Crossplane and ArgoCD a try today? As mentioned this post is a great starting point. If you have any questions, feel free to reach out to me via social media.