Index templates in Elasticsearch apply the same shard settings, refresh interval, field mappings, and aliases whenever a new matching index is created. They are useful when an application owns a family of time-sliced indices and each new index must start with the same structure instead of relying on repeated create-index JSON.
Modern Elasticsearch uses composable templates through the /_index_template API. A template matches names through index_patterns, can store settings, mappings, and aliases under template, and can assemble reusable component templates with composed_of when several index families share the same blocks.
Template changes affect only indices or data stream backing indices created after the template is saved. Use application-specific patterns such as app-logs-* to avoid built-in Elastic templates, and use HTTPS plus credentials on secured clusters with a role that has the manage_index_templates cluster privilege.
Steps to create and manage index templates in Elasticsearch:
- Create the first version of the index template for an application log pattern.
$ curl --silent --show-error --fail --header "Content-Type: application/json" --request PUT "http://localhost:9200/_index_template/app-logs-template?create=true&pretty" --data '{ "index_patterns": ["app-logs-*"], "priority": 300, "version": 1, "_meta": { "description": "Defaults for application log indices" }, "template": { "settings": { "number_of_shards": 1, "number_of_replicas": 0, "refresh_interval": "30s" }, "mappings": { "properties": { "timestamp": { "type": "date" }, "level": { "type": "keyword" }, "message": { "type": "text" } } } } }' { "acknowledged" : true }The create=true query parameter prevents accidental replacement. Omit it only when intentionally updating an existing index template. A non-overlapping pattern such as app-logs-* avoids built-in templates; use a priority above 500 only when deliberately overriding a shared built-in or Fleet-managed pattern.
- Simulate template resolution for a matching index name.
$ curl --silent --show-error --fail --request POST "http://localhost:9200/_index_template/_simulate_index/app-logs-2026.04?pretty&filter_path=template.settings.index.number_of_shards,template.settings.index.number_of_replicas,template.settings.index.refresh_interval,template.mappings.properties,overlapping" { "template" : { "settings" : { "index" : { "refresh_interval" : "30s", "number_of_shards" : "1", "number_of_replicas" : "0" } }, "mappings" : { "properties" : { "level" : { "type" : "keyword" }, "message" : { "type" : "text" }, "timestamp" : { "type" : "date" } } } }, "overlapping" : [ ] }Simulation returns the configuration Elasticsearch would apply without creating the index. Remove filter_path when troubleshooting overlap or merge details.
- Create a test index that matches the template pattern.
$ curl --silent --show-error --fail --request PUT "http://localhost:9200/app-logs-2026.04?pretty" { "acknowledged" : true, "shards_acknowledged" : true, "index" : "app-logs-2026.04" }Index templates apply only at index-creation time, so creating a test index proves the template can be used by new matching indices.
- Verify the inherited shard, replica, and refresh settings on the test index.
$ curl --silent --show-error --fail "http://localhost:9200/app-logs-2026.04/_settings?pretty&filter_path=*.settings.index.number_of_shards,*.settings.index.number_of_replicas,*.settings.index.refresh_interval" { "app-logs-2026.04" : { "settings" : { "index" : { "refresh_interval" : "30s", "number_of_shards" : "1", "number_of_replicas" : "0" } } } }Using number_of_replicas 0 keeps a one-node validation cluster green. Raise the replica count when another data node should hold a copy.
- Verify the inherited field mappings on the test index.
$ curl --silent --show-error --fail "http://localhost:9200/app-logs-2026.04/_mapping?pretty&filter_path=*.mappings.properties" { "app-logs-2026.04" : { "mappings" : { "properties" : { "level" : { "type" : "keyword" }, "message" : { "type" : "text" }, "timestamp" : { "type" : "date" } } } } } - Retrieve the stored template definition for review.
$ curl --silent --show-error --fail "http://localhost:9200/_index_template/app-logs-template?pretty&filter_path=index_templates.name,index_templates.index_template.index_patterns,index_templates.index_template.priority,index_templates.index_template.version,index_templates.index_template._meta,index_templates.index_template.template.settings.index.number_of_shards,index_templates.index_template.template.settings.index.number_of_replicas,index_templates.index_template.template.settings.index.refresh_interval" { "index_templates" : [ { "name" : "app-logs-template", "index_template" : { "index_patterns" : [ "app-logs-*" ], "template" : { "settings" : { "index" : { "number_of_shards" : "1", "number_of_replicas" : "0", "refresh_interval" : "30s" } } }, "priority" : 300, "version" : 1, "_meta" : { "description" : "Defaults for application log indices" } } } ] } - Update the template with a higher version and additional defaults.
$ curl --silent --show-error --fail --header "Content-Type: application/json" --request PUT "http://localhost:9200/_index_template/app-logs-template?pretty" --data '{ "index_patterns": ["app-logs-*"], "priority": 300, "version": 2, "_meta": { "description": "Defaults for application log indices" }, "template": { "settings": { "number_of_shards": 1, "number_of_replicas": 0, "refresh_interval": "5s" }, "mappings": { "properties": { "timestamp": { "type": "date" }, "level": { "type": "keyword" }, "message": { "type": "text" }, "service": { "properties": { "name": { "type": "keyword" } } } } }, "aliases": { "app-logs-search": {} } } }' { "acknowledged" : true }Updating an index template changes only future indices that match the pattern. Existing indices keep the settings, mappings, and aliases they already received at creation time.
- Create a new matching index after the update.
$ curl --silent --show-error --fail --request PUT "http://localhost:9200/app-logs-2026.05?pretty" { "acknowledged" : true, "shards_acknowledged" : true, "index" : "app-logs-2026.05" } - Verify the updated refresh interval on the newly created index.
$ curl --silent --show-error --fail "http://localhost:9200/app-logs-2026.05/_settings?pretty&filter_path=*.settings.index.refresh_interval,*.settings.index.number_of_replicas" { "app-logs-2026.05" : { "settings" : { "index" : { "refresh_interval" : "5s", "number_of_replicas" : "0" } } } } - Verify the new alias on the newly created index.
$ curl --silent --show-error --fail "http://localhost:9200/_alias/app-logs-search?pretty" { "app-logs-2026.05" : { "aliases" : { "app-logs-search" : { } } } } - Verify the new field mapping on the newly created index.
$ curl --silent --show-error --fail "http://localhost:9200/app-logs-2026.05/_mapping?pretty&filter_path=*.mappings.properties.service.properties.name" { "app-logs-2026.05" : { "mappings" : { "properties" : { "service" : { "properties" : { "name" : { "type" : "keyword" } } } } } } }The original app-logs-2026.04 index keeps the older 30s refresh interval and does not gain the new alias or service.name mapping retroactively.
- List matching templates to confirm the stored version.
$ curl --silent --show-error --fail "http://localhost:9200/_index_template/app-logs-*?pretty&filter_path=index_templates.name,index_templates.index_template.version" { "index_templates" : [ { "name" : "app-logs-template", "index_template" : { "version" : 2 } } ] } - Delete the first test index after validation.
$ curl --silent --show-error --fail --request DELETE "http://localhost:9200/app-logs-2026.04?pretty" { "acknowledged" : true }Deleting an index permanently removes the documents and index-level metadata stored in it.
- Delete the second test index after validation.
$ curl --silent --show-error --fail --request DELETE "http://localhost:9200/app-logs-2026.05?pretty" { "acknowledged" : true } - Delete the example template after validation.
$ curl --silent --show-error --fail --request DELETE "http://localhost:9200/_index_template/app-logs-template?pretty" { "acknowledged" : true }Deleting the template stops its defaults from applying to future indices.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.