Skip to main content

Use external Elasticsearch

If you already have an Elasticsearch cluster, you can connect the support stack to it instead of deploying one via ECK. This reduces resource usage and avoids running a second Elasticsearch instance.

warning

Kibana is automatically disabled in external mode because the ECK Kibana CR requires an ECK-managed Elasticsearch instance. Use your existing Kibana or access Elasticsearch directly.

Install with external Elasticsearch

  1. Set the following environment variables:

    export EXTERNAL_ELASTICSEARCH=true
    export EXTERNAL_ES_URL="https://my-es.example.com:9200"
    export EXTERNAL_ES_USERNAME="elastic"
    export EXTERNAL_ES_PASSWORD="YOUR_PASSWORD"

    If your external Elasticsearch uses a publicly-trusted certificate (e.g., Elastic Cloud), no additional configuration is needed. If it uses a private CA certificate, also set:

    export EXTERNAL_ES_CA_FILE="/path/to/ca.crt"

    The installer creates the CA secret automatically from this file.

  2. Run the quickstart:

    nf-quickstart

    The installer automatically:

    • Skips the ECK operator and CRD installation
    • Creates a Kubernetes secret (external-es-creds) with your credentials
    • Generates a support-values.yml configured for external Elasticsearch
    • Sets up ILM policies and index templates on your external cluster

What changes in external mode

  • The ECK operator and CRDs are not installed.
  • No Elasticsearch or Kibana custom resources are created.
  • Logstash, Grafana, and ILM jobs connect directly to your external Elasticsearch.
  • Uninstall skips ECK cleanup automatically.

Switch to external Elasticsearch after installation

If you already have a default installation and want to switch to an external Elasticsearch cluster:

  1. Update your support-values.yml:

    elasticsearch:
    enabled: false
    external:
    url: "https://my-es.example.com:9200"
    credentialSecret: "my-es-creds"
    usernameKey: "username" # default
    passwordKey: "password" # default
    # Set to "" for publicly-trusted certificates
    # Set to a secret name if your ES uses a private CA (see below)
    tlsCaSecret: ""
  2. Create the credential secret:

    kubectl create secret generic my-es-creds \
    --from-literal=username=elastic \
    --from-literal=password='YOUR_PASSWORD' \
    -n support
  3. Upgrade the support Helm chart to apply the changes:

    helm upgrade --install support ./helm-charts/support/ --values support-values.yml -n support

If your external Elasticsearch uses a private CA, create a CA secret and set tlsCaSecret to its name:

kubectl create secret generic my-es-ca \
--from-file=ca.crt=/path/to/ca.crt \
-n support
elasticsearch:
tlsCaSecret: "my-es-ca"

After upgrading, you can remove the ECK-managed Elasticsearch and Kibana resources and uninstall the ECK operator if it is no longer needed.

Index template for keyword fields

The Grafana dashboards and Ziti Console Enterprise rely on .keyword sub-fields for aggregations and filtering (e.g., identity.name.keyword, service.name.keyword). Elasticsearch's built-in default index template normally creates these automatically by mapping every string field as both text and keyword. However, some managed or custom Elasticsearch clusters may not include this default dynamic mapping.

The support chart's ILM/index-template job automatically applies this mapping to all ziti* and *beat* indices. If you are managing index templates on your external cluster yourself, or if the job does not run against your cluster, ensure that your external Elasticsearch has an index template covering ziti* patterns with the following dynamic mapping:

PUT _index_template/ziti-template
{
"index_patterns": ["ziti*", "*beat*"],
"template": {
"settings": {
"index": {
"lifecycle": {
"name": "default_policy"
},
"number_of_shards": 1,
"number_of_replicas": 1
}
},
"mappings": {
"dynamic_templates": [
{
"strings_as_keyword": {
"match_mapping_type": "string",
"mapping": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
]
}
},
"priority": 310
}

This ensures that every string field indexed under ziti* gets both a full-text text mapping and a .keyword sub-field suitable for terms aggregations, sorting, and filtering.

tip

If your dashboards show "No results" for panels that use .keyword fields, a missing dynamic template is the most likely cause. You can verify by checking the mapping of an existing index:

curl -s -u elastic:PASSWORD "https://YOUR_ES:9200/ziti.events/_mapping" | jq '.[][].mappings.properties' | head -20

String fields should show "type": "text" with a "keyword" sub-field. If they only show "type": "text" or "type": "keyword" without the other, apply the index template above and reindex or wait for new data.