# Migrate from v2 to v3

> Migrate from separate Agent and Applier Helm charts to a unified StormForge chart

---

Site [llms.txt](/llms.txt)

---

With v3, the separate `stormforge-agent` and `stormforge-applier` Helm charts are combined into a single `stormforge` chart.

## Prerequisites

Before you begin, ensure you have:

- [The StormForge CLI installed](/docs/installation/install-adv/#set-up-the-stormforge-cli)
- Your current v2 values (see [Convert your values](#convert-values))
- `clusterName` and your API credentials (`authorization.clientID` and `authorization.clientSecret`)

## Webhook considerations {#webhook-considerations}

The v3 chart's `MutatingWebhookConfiguration` reuses the name of the v2 Applier webhook. This means:

- **Helm-managed installs**: If a v2 Applier is still installed when you run `helm install stormforge`, Helm's release-ownership check will refuse to install.
- **GitOps users (ArgoCD, Flux, kubectl apply)**: There is no automatic conflict detection. You **must** fully remove the v2 Applier before applying the v3 manifests. Failing to do so will result in two conflicting `MutatingWebhookConfiguration` resources.

## CRD considerations {#crd-considerations}

When you uninstall the v2 Agent, the `optimize.stormforge.io` CustomResourceDefinitions (CRDs) — and all associated custom resources, such as optimization configurations — remain on your cluster. This is expected, as `helm uninstall` doesn't remove CRDs. **Don't delete them manually.** Deleting a CRD removes every associated custom resource from the cluster.

In step 4 of the migration, you'll use Helm to transfer ownership of the CRDs to the v3 release.

**GitOps users (ArgoCD, Flux, kubectl apply)**: No action is needed. There is no release-ownership check when applying rendered manifests; the existing CRDs are updated in place.

## Migration steps

<div class="alert alert-warning" role="alert">


There will be a brief period of downtime during the migration. Plan accordingly.
</div>


### 1. Convert your values {#convert-values}

Convert your v2 values into a single v3 `values.yaml`. At least one of `--agent-values` and `--applier-values` is required — omit `--applier-values` if the Applier isn't installed.

```sh
stormforge migrate helm-values \
  --agent-values ./agent-values.yaml \
  --applier-values ./applier-values.yaml \
  --output ./values.yaml
```

The command writes the converted values to the output file and reports any keys that require manual attention.

Review the output file and address any warnings before proceeding.

<div class="alert alert-info" role="alert">


If you don't have values files (for example, if you set your values using `--set`), export the configuration for each component using `helm get values`. If you don't have the Applier installed, skip its command. Don't use `-a`/`--all`, as this includes default values:

```sh
helm get values stormforge-agent -n stormforge-system -o yaml > agent-values.yaml
helm get values stormforge-applier -n stormforge-system -o yaml > applier-values.yaml
```

If `applier-values.yaml` contains only `null`, you did not customize that component, so you can ignore it.

</div>


### 2. Confirm required values {#required-values}

Your `values.yaml` must include `clusterName` and your API credentials. Values exported with `helm get values` already contain them. Add them if you started from a fresh file. At minimum:

```yaml
clusterName: my-cluster
authorization:
  clientID: CLIENT_ID
  clientSecret: CLIENT_SECRET
```

### 3. Uninstall the Applier and Agent

Remove the Applier (if it's installed), then the Agent:

```sh
helm uninstall stormforge-applier -n stormforge-system
helm uninstall stormforge-agent -n stormforge-system
```

### 4. Install the v3 unified chart {#complete-the-migration}

The `--take-ownership` flag (Helm 3.17 or later) lets Helm take ownership of the [CRDs left in place by the v2 Agent](#crd-considerations):

```sh
helm install stormforge oci://registry.stormforge.io/library/stormforge \
  --namespace stormforge-system \
  --create-namespace \
  --take-ownership \
  --values values.yaml
```

This installs the Agent, Forwarder, and Applier in a single chart, replacing the separate v2 installations.

If your Helm version doesn't support `--take-ownership`, label and annotate the existing CRDs to match the v3 release before installing:

```sh
for crd in workloadoptimizers optimizationconfigurations clusteroptimizationconfigurations; do
  kubectl label crd ${crd}.optimize.stormforge.io \
    app.kubernetes.io/managed-by=Helm --overwrite
  kubectl annotate crd ${crd}.optimize.stormforge.io \
    meta.helm.sh/release-name=stormforge \
    meta.helm.sh/release-namespace=stormforge-system --overwrite
done
```

## If migration fails

Migration issues are typically environment-specific and may require manual intervention. If you run into problems, [contact StormForge support](https://www.cloudbolt.io/company/contact-us/).

## Values reference {#values-mapping}

The `stormforge migrate helm-values` command handles these conversions automatically. These tables are a reference for what changed between v2 and v3.

### Renamed values

| v2 key | v3 key |
|---------|---------|
| `authSecret` | `authSecretName` |
| `envSecret` | `envSecretName` |
| `commonMetaLabels` | `commonLabels` |
| `manageAuthSecret` | `createAuthSecret` |
| `rbac.additional` | `clusterAgent.rbac.additionalRules` |
| `rbac.*` (all other keys) | `clusterAgent.rbac.*` |
| `serviceAccount.*` | `clusterAgent.serviceAccount.*` |
| `workload.allowNamespaces` | `clusterAgent.allowNamespaces` |
| `workload.denyNamespaces` | `clusterAgent.denyNamespaces` |
| `workload.inactiveWorkloadsGC` | `clusterAgent.garbageCollectInactiveWorkloads` |
| `prom.extraScrapeConfigs` | `forwarder.additionalScrapeConfigs` |
| `workloadResourceTypes` | Merged into `workloadResourceKinds` |

### Removed values

| v2 key | Action in v3 |
|---------|---------------|
| `clusterDefaultConfig` | Deprecated, but still accepted as a migration aid — prefer a [ClusterOptimizationConfiguration resource](/docs/configure/optimization-configurations/) |
| `featureGates.optimizeCronJobs` | Removed — an enabled gate is converted to the equivalent `workloadResourceKinds` entry |
| `featureGates.optimizeSparkOperator` | Removed — an enabled gate is converted to the equivalent `workloadResourceKinds` entry |
| `featureGates.optimizeGithubARC` | Removed — an enabled gate is converted to the equivalent `workloadResourceKinds` entry |
| `patchTargetTypes` | Removed — use `workloadResourceKinds` |
| `enableOptimizationConfigurationCRDs` | Always-on |
| `extraEnvVars` | Removed — was a deprecated alias; use `additionalEnvVars` |

## Resource name changes

The following Kubernetes resource names changed in v3. Update any references to these names in monitoring, alerts, or scripts.

### Deployments

| v2 name | v3 name |
|----------|----------|
| `stormforge-agent-workload-controller` | `stormforge-cluster-agent` |
| `stormforge-agent-metrics-forwarder` | `stormforge-forwarder` |
| `{release}-stormforge-applier` (where `{release}` is your Helm release name) | `stormforge-applier` |

### Secrets

| v2 name | v3 name |
|----------|----------|
| `stormforge-agent-auth` | `stormforge-auth` |

## CI/CD automation updates

Update any CI/CD pipelines that reference the old chart URLs or release name:

| | v2 | v3 |
|---|---|---|
| **Agent chart URL** | `oci://registry.stormforge.io/library/stormforge-agent` | `oci://registry.stormforge.io/library/stormforge` |
| **Applier chart URL** | `oci://registry.stormforge.io/library/stormforge-applier` | Not needed — Applier is bundled |
| **Release name** | `stormforge-agent` | `stormforge` |
