# Migrate Elasticsearch to the ECK operator (staged)

> Learn how to migrate from the deprecated Elasticsearch for version 1.4

## Migrate Elasticsearch to the ECK operator (staged)

For version 1.4 and newer.

We are deprecating the `elasticsearch` StatefulSet chart and will remove it in a future release.

You need to migrate to ECK. There's no data loss or downtime, but expect a brief write pause during the final copy, because `catalog-writer` is scaled to zero while data is copied.

### Prerequisites

Plan capacity for the parallel run of the ECK and existing Elasticsearch.

The ECK cluster needs about 5.5 CPU and 22 GiB of memory. This is in addition to the existing cluster, until you retire it. In total, you need three dedicated primary nodes and two data nodes at 4 CPU and 8 GiB limits, sized so that org-wide asset search stays fast.

### Upgrade

To migrate:

1. Upgrade to this release with `enable_elasticsearch_eck = true`.

2. Run `make apply-<region>`.

   The ECK operator and an empty `elastic-eck-cluster` come up alongside your existing Elasticsearch.

   Catalog services keep using the existing cluster, so nothing changes yet.

3. Stop writes during the copy:

   ```sh
   kubectl scale deploy/asset-catalog-writer --replicas=0 -n asset-solutions
   ```

4. Copy your data into the ECK cluster.

   The script runs as a one-shot pod streamed over standard input, and uses the public `nicolaka/netshoot` debug image for its `bash`, `curl`, and `jq` tooling.

   If your nodes can't pull from Docker Hub, substitute any image that has those three tools.

   The Elasticsearch password is injected from the `elasticsearch-apps-credentials` secret, so it never appears in your shell or in the pod spec:

   ```sh
   kubectl run es-reindex -n asset-solutions --restart=Never --rm -i \
    --pod-running-timeout=10m \
    --image=docker.io/nicolaka/netshoot:v0.14 \
    --overrides='{
     "spec": {
       "securityContext": {"runAsNonRoot": true, "runAsUser": 1001, "runAsGroup": 1001, "seccompProfile": {"type": "RuntimeDefault"}},
       "containers": [{
         "name": "es-reindex",
         "image": "docker.io/nicolaka/netshoot:v0.14",
         "stdin": true,
         "stdinOnce": true,
         "command": ["bash", "-s"],
         "securityContext": {"allowPrivilegeEscalation": false, "capabilities": {"drop": ["ALL"]}},
         "resources": {"requests": {"cpu": "100m", "memory": "128Mi"}, "limits": {"cpu": "500m", "memory": "256Mi"}},
         "env": [{"name": "ELASTIC_PASSWORD", "valueFrom": {"secretKeyRef": {"name": "elasticsearch-apps-credentials", "key": "password"}}}]
       }]
     }
    }' < scripts/elasticsearch-reindex.sh
   ```

   To pass the optional overrides, add them to the `env` array. For example, pass `{"name": "DST_SHARDS", "value": "2"}`. The optional overrides are `DST_SHARDS`, `DST_REPLICAS`, `SRC`, `DST`, or `ES_USER`. The script header documents each one.

   Each index's shard count is based on its actual data size: one primary shard for each started 25 GB, and one replica. Set `DST_SHARDS` and `DST_REPLICAS` if you need a specific layout.

   Re-running the script only creates indices that are missing on the destination. An index that already exists there keeps its current shard layout, and the script reports it. To re-cut such an index, delete it on the destination first.

5. Cut over: set `use_eck_elasticsearch = true`.

6. Run `make apply-<region>`.

7. Scale `asset-catalog-writer` back up.

8. Verify search and catalog operations.

9. Retire the existing cluster: set `enable_elasticsearch = false` and reapply.

10. A later release removes the existing chart, and you can then delete the old `elasticsearch-master-*` PersistentVolumeClaims to reclaim storage.

### Rollback

To rollback before you scale `asset-catalog-writer`: set `use_eck_elasticsearch = false` and reapply. Catalog services return to the still-running existing cluster with no data loss.

If you've started writing against the ECK cluster, the existing cluster is stale. If you roll back at this point, catalog services return to a dataset that's missing everything written since cutover. This means that you need to copy the new data before you rollback:

1. Stop writes again.
2. Delete the affected indices on the existing cluster (the script skips indices that already exist on the destination).
3. re-run the script with `SRC` and `DST` swapped.
4. Set `use_eck_elasticsearch = false` and reapply.
