kubectl create pizza
Tags: kubernetes, go
Published: 2020-12-11 16:04:47

---
title: kubectl create pizza
published: true
description: making kubernetes do what it was always meant to do - order pizza
tags: kubernetes,go
canonical_url: https://ops.tips/notes/kubernetes-pizza
cover_image: https://user-images.githubusercontent.com/3574444/101926015-9d03a500-3ba0-11eb-9ad0-da932d18267c.png
---

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](https://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?

<img width="300px" src="https://user-images.githubusercontent.com/3574444/101922101-b81fe600-3b9b-11eb-95a3-9a5f2a067997.JPG" />

*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:

```yaml
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:


```yaml
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:


```console
$ kubectl get pizzacustomer

NAME              CLOSEST
you               store-123
```

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

```console
$ 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:

```yaml
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:

```console
$ kubectl get pizzaorder ma-pizza

NAME    PRICE      ID                     CONDITION     AGE
order   9.030000   Wlz6HcE6BPlfQNlxDAXa   OrderPlaced   68m
```

and, there we go!

<img width="300px" src="https://user-images.githubusercontent.com/3574444/101922114-bb1ad680-3b9b-11eb-8850-5fca08598d2d.JPG" />


## 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.

```yaml
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!

```bash
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](https://crossplane.io/) 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:

- well, any .. tests :horse:
- order tracking (it's `xml`-based - SOAP stuff)
- being more flexible with non-canadian folks (it's currently hardcoded for
  Canada, but could easily be changed)

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