I have the following check in my Helm chart to see if a rbac policy has already been applied:
{{- if not (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "") }}
apiVersion: "rbac.authorization.k8s.io/v1"
kind: "ClusterRole"
metadata:
name: {{ .Values.clusterrole.name }}
but the deploy still fails - what should the correct syntax be ?
In most cases you shouldn't use lookup. If you want it to be configurable whether to use this RBAC rule, put that in a specific Helm-values setting.
{{- if .Values.clusterrole.enabled -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ .Values.clusterrole.name }}
...
{{ end -}}
The other significant change in this fragment from what you've shown in the question is that I've removed all of the indentation. It might seem more natural from other languages to indent the contents of {{ if }}...{{ end }} and similar blocks, but that indentation winds up being visible in the YAML output of the template, and that can result in parse errors.
There are two problems with lookup, especially the way you show it. The practical one is that, if the chart installs once, the lookup test will pass; this results in the ClusterRole being removed from the Helm manifest, and so helm upgrade will uninstall the object that had been previously installed. The broader statement is that using lookup makes your chart dependent on what's already installed in the cluster, and so it becomes very hard to test or validate the behavior, and you can get unexpected results if the cluster contains some combination of objects you didn't foresee.