<p>I'm currently writing a Helm Chart for my multi-service application. In the application, I depend on <code>CustomResources</code>, which I apply before everything else with helm via the <code>"helm.sh/hook": crd-install</code> hook.</p>

<p>Now I want to upgrade the application. Helm fails because the CRDs are already installed.
In some GH issues, I read about the builtin <code>.Capabilities</code> variable in Helm templates. I want to wrap my CRDs with an "if" checking if the CRD is already installed:  </p>

<pre><code>{{- if (not (.Capabilities.APIVersions.Has "virtualmachineinstancepresets.kubevirt.io")) }}
</code></pre>

<p>Unfortunately, I misunderstood the APIVersions property.<br>
So my question is, does Helm provide a way of checking whether a <code>CustomAPI</code> is already installed, so I can exclude it from my Helm pre-hook install?</p>

<p>The simple answer for Helm v2 is manually choose <code>--no-crd-hook</code> flag when running <code>helm install</code>.</p>

<p>The workaround by using builtin <code>.Capabilities</code> variable can be a workaround. E.g., using this:</p>

<pre><code>{{- if not (.Capabilities.APIVersions.Has "virtualmachineinstancepresets.kubevirt.io/v1beta1/MyResource") }}
apiVersion: ...
{{- end}}
</code></pre>

<p>However, it also means you will never be able to manage the installed CRDs by Helm again.</p>

<p>Checkout a long answer from blog post <a href="https://joejulian.name/post/helm-v2-crd-management/" rel="nofollow noreferrer">Helm V2 CRD Management</a> which explained different approaches. However, I quote this:</p>

<blockquote>
  <p>CRD management in helm is, to be nice about it, utterly horrible.</p>
</blockquote>

<p>personally I suggest managing CRDs via a separate chart out of app/library charts that depends on it, since they have totally different lifecycle.</p>
