Using Crossplane in GitOps: Common Considerations

Deploying Order

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: crossplane-app
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "100"
...
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: olm-app
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "100"
...
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: sealed-secrets-controller
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "100"
...
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: crossplane-ext-app
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "150"
spec:
patches:
- fromObject:
apiVersion: v1
kind: ConfigMap
name: common-settings
namespace: crossplane-system
fieldPath: data.region
toFieldPath: spec.forProvider.region
---
apiVersion: kubernetes.crossplane.io/v1alpha1
kind: Object
metadata:
name: csv-my-logging-stack
annotations:
kubernetes.crossplane.io/managementType: "ObservableAndDeletable"
spec:
references:
- fromObject:
apiVersion: kubernetes.crossplane.io/v1alpha1
kind: Object
name: sub-my-logging-stack
fieldPath: status.atProvider.manifest.status.currentCSV
toFieldPath: spec.forProvider.manifest.metadata.name
forProvider:
manifest:
apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
namespace: operators
providerConfigRef:
name: provider-config-dev

Using Hooks

apiVersion: batch/v1
kind: Job
metadata:
name: post-install-job
namespace: argocd
annotations:
argocd.argoproj.io/hook: PostSync
spec:
template:
metadata:
name: post-install-job
spec:
containers:
- name: check-csv
image: quay.io/bitnami/kubectl:latest
command:
- /bin/sh
- -c
- |
current_seconds=0
limit_seconds=$(( $(date +%s) + 600 ))
installing=0

while [ ${current_seconds} -lt ${limit_seconds} ]; do
if [ $(kubectl get csv -n "{{.Values.metadata.namespace}}" -o name | grep -c clusterserviceversion) -eq 0 ] || \
[ $(kubectl get csv -n "{{.Values.metadata.namespace}}" --no-headers | grep -vc Succeeded) -gt 0 ]; then
installing=1
echo "INFO: CSVs still installing."
sleep 1
else
installing=0
break
fi
current_seconds=$(( $(date +%s) ))
done

if [ ${installing} -eq 0 ]; then
echo "INFO: All CSVs are ready."
else
echo "ERROR: CSVs still not ready."
exit 1
fi
restartPolicy: Never
serviceAccountName: argocd-application-controller
backoffLimit: 1

Health Check

---
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
resource.customizations.health.operators.coreos.com_ClusterServiceVersion: |
hs = {}
hs.status = "Progressing"
hs.message = ""
if obj.status ~= nil then
if obj.status.phase == "Succeeded" then
hs.status = "Healthy"
end
hs.message = obj.status.message
end
return hs
resource.customizations.health.elasticsearch.k8s.elastic.co_Elasticsearch: |
hs = {}
hs.status = "Progressing"
hs.message = ""
if obj.status ~= nil and obj.status.health ~= nil and obj.status.phase ~= nil then
if obj.status.health == "green" and obj.status.phase == "Ready" then
hs.status = "Healthy"
end
hs.message = "health = " .. obj.status.health .. " phase = " .. obj.status.phase
end
return hs
resource.customizations.health.kubernetes.crossplane.io_Object: |
hs = {}
hs.status = "Progressing"
hs.message = ""
if obj.status ~= nil and obj.status.atProvider ~= nil then
kind = obj.spec.forProvider.manifest.kind
res = obj.status.atProvider.manifest
if res ~= nil then
if kind == "ClusterServiceVersion" then
if res.status ~= nil then
if res.status.phase == "Succeeded" then
hs.status = "Healthy"
end
hs.message = res.status.message
end
elseif kind == "Elasticsearch" then
if res.status ~= nil and res.status.health ~= nil and res.status.phase ~= nil then
if res.status.health == "green" and res.status.phase == "Ready" then
hs.status = "Healthy"
end
hs.message = "health = " .. res.status.health .. " phase = " .. res.status.phase
end
end
end
end
return hs

Organizing Configuration

├── config
│ ├── argocd-apps
│ ├── infra
│ ├── services
│ └── apps
└── environments
├── base
└── overlays
├── dev
├── staging
└── prod

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store