---
# System prepended metadata

title: Build NGINX Operator
tags: [gitops]

---

![](https://hackmd.io/_uploads/B1gD_2Tah.png)

The kubectl utility allows watching for resource changes using the get command with the `--watch` flag. The `--output-watch-events` command instructs kubectl to output the change type, which takes one of the following values: ADDED, MODIFIED, or DELETED.

The `kubectl get --watch` command outputs a new line every time a ConfigMap resource is created, changed, or deleted. The script will consume the output of `kubectl get --watch` and either create a new Deployment or delete a Deployment depending on the output ConfigMap event type.

```bash
#!/bin/bash
kubectl get --watch --output-watch-events cm -o=custom-columns=type:type,name:object.metadata.name --no-headers | \
while read next; do
  NAME_FULL=$(echo $next | cut -d' ' -f2)
  EVENT=$(echo $next | cut -d' ' -f1)

  echo "Controller trigger $EVENT event for $NAME_FULL"

  if [[ $next == *-nginx-data ]]; then
    echo "NGINX data"

    NAME=$(echo $NAME_FULL | cut -d'-' -f1)

    case $EVENT in
      ADDED|MODIFIED)
        kubectl apply -f - << EOF
apiVersion: apps/v1
kind: Deployment
metadata: { name: $NAME }
spec:
  selector:
    matchLabels: { app: $NAME }
  template:
    metadata:
      labels: { app: $NAME }
      annotations: { kubectl.kubernetes.io/restartedAt: $(date) }
    spec:
      containers:
      - image: nginx
        name: $NAME
        ports:
        - containerPort: 80
        volumeMounts:
        - name: data
          mountPath: /usr/share/nginx/html
      volumes:
      - name: data
        configMap:
          name: $NAME
EOF
        ;;
      DELETED)
        kubectl delete deploy $NAME
      ;;
    esac

  fi

done
```

Basic GitOps operator

![](https://hackmd.io/_uploads/SkQf8pTp2.png)

While this control loop could be implemented in any number of ways, most simply, it could be implemented as a Kubernetes CronJob.

```yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: gitops-cron
  namespace: gitops
spec:
  schedule: "*/5 * * * *"                            #A
  concurrencyPolicy: Forbid                          #B
  jobTemplate:                                       #D
    spec:
      backoffLimit: 0                                #C
      template:
        spec:
          restartPolicy: Never                       #E
          serviceAccountName: gitops-serviceaccount  #F
          containers:
          - name: gitops-operator
            image: gitopsbook/example-operator:v1.0  #G
            command: [sh, -e, -c]                    #H
            args:
            - git clone https://github.com/gitopsbook/sample-app-deployment.git /tmp/example &&
              find /tmp/example -name '*.yaml' -exec kubectl apply -f {} \;
```













