Hey,

I recently created a series of articles and videos that goes through the development of Kubernetes custom resources and controllers (see gum.co/kubernetes-crds), but I missed that nice catchy example that would showcase what custom resources are all about.

So, why not implement the ultimate missing feature that Kubernetes should have?

tl;dr: see https://github.com/cirocosta/pizza-controller

usage

First, create a secret with the credit card information (yeah, this is fine, trust me) to be used during payment:

kind: Secret
apiVersion: v1
metadata:
  name: credit-card
stringData:
  number: 123343132314232
  expiration: 12/02
  securityCode: 123
  zip: m5d0l2

then, create a PizzaCustomer, the representation of you, the customer:

kind: PizzaCustomer
apiVersion: ops.tips/v1alpha1
metadata:
  name: you
spec:
  firstName: barack
  lastName: obama
  email: obama@gov.gov
  phone: "31241323"
  streetNumber: "20"
  streetName: King St
  city: Toronto
  state: "ON"
  zip: m5lz8j

With the PizzaCustomer object created, we can see what’s the closest store available for it:

$ kubectl get pizzacustomer

NAME              CLOSEST
you               store-123

Looking at the PizzaStore object, we can check out its menu:

$ kubectl get pizzastore store-123 -o yaml

kind: PizzaStore
metadata:
  name: store-123
spec:
  address: |
    51 Niagara St
    Toronto, ON M5V1C3
  id: "10391"
  phone: 416-364-3939
  products:
    - description: Unique Lymon (lemon-lime) flavor, clear, clean and crisp with no caffeine.
      id: 2LSPRITE
      name: Sprite
      size: 2 Litre

Knowing what’s available to us, we can place the order:

kind: PizzaOrder
apiVersion: ops.tips/v1
metadata:
  name: ma-pizza
spec:
  yeahSurePlaceThisOrder: true  # otherwise, it'll just calculate the price
  storeRef: {name: store-123}
  customerRef: {name: you}
  payment:
    creditCardSecretRef: {name: cc}
  items:
    - ticker: 10SCREEN
      quantity: 1

To keep track of what’s going on with your pizza, check out the order’s status:

$ kubectl get pizzaorder ma-pizza

NAME    PRICE      ID                     CONDITION     AGE
order   9.030000   Wlz6HcE6BPlfQNlxDAXa   OrderPlaced   68m

and, there we go!

wait, but why?

no no, wait, why not?

see, with CI/CD being part of Kubernetes through projects like Argo and Tekton, where you declare what your pipeline/workflow will be in terms of Kubernetes resources, we’re now able to get that nice pizza for the team after a successfull release.

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: release-
spec:
  entrypoint: pi-tmpl
  templates:
  - name: main
    steps:
      - - name: unit-tests
          template: test
        - name: integration-tests
          template: test
          arguments:
            parameters:
              - name: type
                value: integration
      - - name: release
          template: release
      - - name: get-that-pizza
          template: order-pizza

  - name: order-pizza
    resource:
      action: create      
      manifest: |
        kind: PizzaOrder
        apiVersion: ops.tips/v1
        metadata:
          name: ma-pizza
        spec:
          yeahSurePlaceThisOrder: true
          storeRef: {name: store-123}
          customerRef: {name: you}
          payment:
            creditCardSecretRef: {name: cc}
          items:
            - ticker: 10SCREEN
              quantity: 2

i don’t know about you, but that sounds quite right to me ¯\_(ツ)_/¯

installation

being a legit Kubernetes custom resource, you install it just like you would install Tekton, kpack, or anything like that: you submit a manifest that contains the CustomResourceDefinition objects to Kubernetes, a Deployment that materializes the controller as a container in a pod, and then … that’s it!

git clone https://github.com/cirocosta/pizza-controller
cd pizza-controller

kapp deploy -a pizza-controller -f ./config/release.yaml


# OR .. plain old kubectl
#
kubectl apply -f ./config/release.yaml

but, that’s dumb

i disagree

I think it’s a pretty cool example of the concepts behind extending kubernetes via custom resources, and something that might bring you some thoughts of ways in which you could bring the declarative nature of Kubernetes objects plus the level-triggered approach to controllers to bring to Kubernetes the ability to request external resources.

for instance, projects like crossplane give you pretty much that, except that instead of ordering a pizza, you’re ordering … a database (or things like that).

what’s next?

are you really into ordering pizza using kubectl?

like, really? are you sure?

here’s what’s missing:

at the moment I got my pizza .. development finished :sweat_smile: maybe you’ll carry it forward? head to https://github.com/cirocosta/pizza-controller

want to know more?

check out https://gum.co/kubernetes-crds