Skip to content

Instantly share code, notes, and snippets.

Manual (Without GitOps)

go test --tag unit

docker image build --tag ghcr.io/vfarcic/silly-demo:v1.2.3 --push

yq --inplace ".spec.template.spec.containers[0].image = \"ghcr.io/vfarcic/silly-demo:v1.2.3\"" staging/deployment.yaml

kubectl --namespace staging apply --filename dev/deployment.yaml

Introduction

Imagine if you could create, for people in your company, a platform that would provide them with the same experience they have when working with AWS, Google Cloud, Azure, or any other public Cloud provider. Imagine if there would be a service for everything they do.

Do you need a database that works exactly as we expect it to work in this company with all the security, backup, compliance, and other policies we have?

Well...

There is a service for that.

Intro

Crossplane v2 is here!

We got some very cool features that I want to go through.

We'll see the changes to Crossplane Composition schemas, a shift to Namespace-scoped resources, direct composition of any resources without the need to rely only on Crossplane Managed resources, new API versions, removal of deprecated features, and more.

I'm sure that, by the end of this walkthrough you'll see that two most requested features are here and that autoring Compositions is now easier.

Intro

Crossplane v2 is here!

We got some very cool features that I want to go through.

We'll see the changes to Crossplane Composition schemas, a shift to Namespace-scoped resources, direct composition of any resources without the need to rely only on Crossplane Managed resources, new API versions, removal of deprecated features, and more.

I'm sure that, by the end of this walkthrough you'll see that two most requested features are here and that autoring Compositions is now easier.

Intro

TODO: Volume is now lower

TODO: Show images conversation-* (6 of them) by adding them one on top or beside each other starting from when I say "like those" (it's like that one in the text) and keep them until the end of the paragraph. Show them starting from conversation-06 moving in descending order towards conversation-01 since that is the most important one.

During recent months I saw a lot of conversation and questions sparked by the release of kro, like the one in the picture. Many of them are related to comparison with Helm. Some people think that kro is, more or less, doing the same work as Helm. Others think that it is a different syntax that accomplishes the same result as Helm. Some are asking whether kro is a replacement for Helm.

Intro

TODO: Volume is now lower

"Crossplane is too complicated!" "Crossplane is only for infrastructure! I need something else for applications."

I hear those and other similar statement very often so I decided to clarify a few things and, hopefully, eliminate some missconceptions.

To be more precise, today I want to debunk one missconception about Crossplane and, at the same time, show how Crossplane addressed one semi-legitimate complaint in the recent v2 release.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
dev.okteto.com/generate-host: "true"
ingress.kubernetes.io/ssl-redirect: "false"
kubectl.kubernetes.io/last-applied-configuration: '{"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{"dev.okteto.com/generate-host":"true","ingress.kubernetes.io/ssl-redirect":"false"},"labels":{"app.kubernetes.io/name":"silly-demo"},"name":"silly-demo","namespace":"staging"},"spec":{"ingressClassName":"contour","rules":[{"host":"staging.silly-demo.34.74.187.90.nip.io","http":{"paths":[{"backend":{"service":{"name":"silly-demo","port":{"number":8080}}},"path":"/","pathType":"ImplementationSpecific"}]}}]}}'
creationTimestamp: "2025-03-06T15:33:29Z"
generation: 1
labels:
apiVersion: v1
kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: '{"apiVersion":"v1","kind":"Service","metadata":{"labels":{"app.kubernetes.io/name":"silly-demo"},"name":"silly-demo","namespace":"staging"},"spec":{"ports":[{"name":"http","port":8080,"protocol":"TCP","targetPort":8080}],"selector":{"app.kubernetes.io/name":"silly-demo"},"type":"ClusterIP"}}'
creationTimestamp: "2025-03-06T15:33:29Z"
labels:
app.kubernetes.io/name: silly-demo
name: silly-demo
namespace: staging
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
kubectl.kubernetes.io/last-applied-configuration: '{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"labels":{"app.kubernetes.io/name":"silly-demo"},"name":"silly-demo","namespace":"staging"},"spec":{"selector":{"matchLabels":{"app.kubernetes.io/name":"silly-demo"}},"template":{"metadata":{"labels":{"app.kubernetes.io/name":"silly-demo"}},"spec":{"containers":[{"env":[{"name":"DB_ENDPOINT","valueFrom":{"secretKeyRef":{"key":"endpoint","name":"silly-demo-db"}}},{"name":"DB_PASSWORD","valueFrom":{"secretKeyRef":{"key":"password","name":"silly-demo-db"}}},{"name":"DB_PORT","valueFrom":{"secretKeyRef":{"key":"port","name":"silly-demo-db","optional":true}}},{"name":"DB_USERNAME","valueFrom":{"secretKeyRef":{"key":"username","name":"silly-demo-db"}}},{"name":"DB_NAME","value":"main"}],"image":"ghcr.io/vfarcic/idp-full-demo:0.0.7","livenessProbe":{"httpGet":{"path":"/","port":8080}},"name":"silly-demo"

Intro

FIXME: The goals: FIXME: Do whatever needs to do done to develop something and test it under similar conditions as if it's running in production. FIXME: Everything (or almost everything) is in the repo.

FIXME: Example: Backend up that depends on a front-end and a database

FIXME: Welcome to DevOps Toolkit, the channel where we...