Using Crossplane in GitOps: What to Check in Git

Store Manifests in Git Repository

Now that you have launched the environment with the prerequisites ready including Crossplane, its providers, and all the necessary configuration, you can start to check application manifests in git to trigger the application provisioning driven by GitOps. There are several ways that we can consider.

Managed Resources

In Crossplane, managed resource is Kubernetes custom resource defined and handled by Crossplane Provider. You can think of Crossplane with its provider equivalent to Kubernetes controller or operator. As such, when you check managed resource as manifest in git, it will be synchronized by Argo CD from git to target cluster, then detected by the provider and drive the actual application provisioning.

---
apiVersion: kubernetes.crossplane.io/v1alpha1
kind: Object
metadata:
name: elasticsearch-my-logging-stack
spec:
references:
- fromObject:
apiVersion: kubernetes.crossplane.io/v1alpha1
kind: Object
name: csv-my-logging-stack
fieldPath: status.atProvider.manifest.status.phase
forProvider:
manifest:
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: my-logging-stack
namespace: default
spec:
version: 7.13.3
nodeSets:
- name: default
count: 1
config:
node.store.allow_mmap: false
providerConfigRef:
name: provider-config-dev

Using Kustomize

Per environment configuration can be done by Kustomize. By using Kustomize, you can have the manifests with their default configuration at base layer, then specify the custom settings at overlays layer to override the base one.

Managed Resources As Template

Helm dynamically generates the configuration based on functions and parameters. It results in more reusable manifests stored in git. By using Helm, you can extract customizable configuration out of the managed resources, and put them into values.yaml with default values provided. With that, the managed resources stored in git will be templated manifests.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: capabilities-logging-app
namespace: argocd
spec:
destination:
namespace: dev
server: 'https://kubernetes.default.svc'
source:
path: config/capabilities/crossplane-helm/logging
repoURL: 'https://github.com/morningspace/capabilities-shim-gitops'
targetRevision: HEAD
helm:
parameters:
- name: metadata.name
value: dev-env-logging-stack
project: default

Composition and CompositeResourceDefinition

Crossplane has a powerful composition engine. By defining Composition resource, it can compose multiple resources at different level from infrastructure to application all driven by providers at backend from different vendors.

apiVersion: capabilities.morningspace.io/v1alpha1
kind: LoggingClaim
metadata:
name: my-logging-stack
spec:
parameters:
esVersion: 7.13.3
kibanaVersion: 7.13.3
compositionSelector:
matchLabels:
capability: logging
provider: olm

When to Check Composition, CompositeResourceDefinition in Git

It depends on whether or not you want to expose these details to Ops or SREs. For example, if you want them to understand how the managed resources are organized, to be able to modify these compositions, or even define their own compositions as needed, then you should check Composition and CompositeResourceDefinition in git.

Using Kustomize

The CompositeResourceClaim resource is usually environment specific. That means you can put it into environment specific folder in git. However, if you want the resource to be reusable and only override it partially per environment, you can also use Kustomize. Below is a sample folder structure:

└── environments
├── base
│ ├── logging-claim.yaml
│ └── kustomization.yaml
└── overlays
└── dev
├── logging-claim.yaml
└── kustomization.yaml
apiVersion: capabilities.morningspace.io/v1alpha1
kind: LoggingClaim
metadata:
annotations:
capabilities.morningspace.io/provider-config: provider-config-dev
name: my-logging-stack
spec:
parameters:
esVersion: 7.15.0
kibanaVersion: 7.15.0

Crossplane vs. Helm

When use Composition, you may notice that it is very similar to Helm templates since essentially they both compose a set of Kubernetes resources. From application deployment point of view, Crossplane, as a deployment tool, provides some building blocks that are very similar to what Helm does, but they also have differences. In this section, I will explore them and make side-by-side comparison between Crossplane and Helm.

Crossplane Composition vs. Helm Templates

A Crossplane Composition resource defines way of composing a set of Kubernetes resources. It is equivalent to Helm templates which include a set of template files and each file maps to one or more Kubernetes resources. A Crossplane Configuration package typically includes a set of Compositions, which map to multiple charts or sub-charts in Helm. The difference is that Composition organizes resources in a monolithic way where all resources are defined in the same file. But for Helm templates, they are separate files in the same folder or different folders. Certainly you can combine these files together as a single file to make it very similar to a Crossplane Composition resource, but they do have some differences in nature as below:

  • Instead of templating, Crossplane renders Composition resource by extracting values from CompositeResource (XR) or CompositeResourceClaim (XRC) resource and patching them to specific fields on managed resources. This is very similar to Kustomize.
  • At a much higher level, we usually see Crossplane Composition is used to composing modules from infrastructure, service, to application in more coarse grained way. On the other hand, Helm usually focuses on “composing” modules at application level in more fine grained way. But this does not mean you cannot compose infrastructure using Helm. For example, with the combined use of Crossplane Provider and Helm, you can compose infrastructure, service, and application too.

XR, XRC, XRD vs. values.yaml

The Crossplane CompositeResource (XR) or CompositeResourceClaim (XRC) resource is essentially equivalent to the values.yaml file in Helm. Just like values.yaml, XR/XRC is aimed to extract the configurable settings out of the original resources for people to consume.

metadata:
name: my-logging-stack
namespace: default
spec:
parameters:
esVersion: 7.13.3
kibanaVersion: 7.13.3

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
MorningSpace

MorningSpace

Life is coding and writing! I am a software engineer who have been in IT field for 10+ years. I would love to write beautiful code and story for people.