
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

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 {} \;
```