--- layout: docs page_title: Service Splitter configuration reference description: >- Service splitter configuration entries are L7 traffic management tools for redirecting requests for a service to multiple instances. Learn how to write `service-splitter` config entries in HCL or YAML with a specification reference, configuration model, a complete example, and example code by use case. --- # Service Splitter configuration reference This reference page describes the structure and contents of service splitter configuration entries. Configure and apply service splitters to redirect a percentage of incoming traffic requests for a service to one or more specific service instances. ## Configuration model The following list outlines field hierarchy, language-specific data types, and requirements in a service splitter configuration entry. Click on a property name to view additional details, including default values. - [`Kind`](#kind): string | required - [`Name`](#name): string | required - [`Namespace`](#namespace): string - [`Partition`](#partition): string - [`Meta`](#meta): map - [`Splits`](#splits): map | required - [`Weight`](#splits-weight): number | required - [`Service`](#splits-service): string | required - [`ServiceSubset`](#splits-servicesubset): string - [`Namespace`](#splits-namespace): string - [`Partition`](#splits-partition): string - [`RequestHeaders`](#splits-requestheaders): map - [`Add`](#splits-requestheaders): map - [`Set`](#splits-requestheaders): map - [`Remove`](#splits-requestheaders): map - [`ResponseHeaders`](#splits-responseheaders): map - [`Add`](#splits-responseheaders): map - [`Set`](#splits-responseheaders): map - [`Remove`](#splits-responseheaders): map - [`apiVersion`](#apiversion): string | required - [`kind`](#kind): string | required - [`metadata`](#metadata): object | required - [`name`](#metadata-name): string | required - [`namespace`](#metadata-namespace): string | optional - [`spec`](#spec): object | required - [`splits`](#spec-splits): list | required - [`weight`](#spec-splits-weight): float32 | required - [`service`](#spec-splits-service): string | required - [`serviceSubset`](#spec-splits-servicesubset): string - [`namespace`](#spec-splits-namespace): string - [`partition`](#spec-splits-partition): string - [`requestHeaders`](#spec-splits-requestheaders): HTTPHeaderModifiers - [`add`](#spec-splits-requestheaders): map - [`set`](#spec-splits-requestheaders): map - [`remove`](#spec-splits-requestheaders): map - [`responseHeaders`](#spec-splits-responseheaders): HTTPHeaderModifiers - [`add`](#spec-splits-responseheaders): map - [`set`](#spec-splits-responseheaders): map - [`remove`](#spec-splits-responseheaders): map ## Complete configuration When every field is defined, a service splitter configuration entry has the following form: ```hcl Kind = "service-splitter" ## string | required Name = "config-entry-name" ## string | required Namespace = "main" ## string Partition = "partition" ## string Meta = { ## map key = "value" } Splits = [ ## list | required { ## map Weight = 90 ## number | required Service = "service" ## string ServiceSubset = "v1" ## string Namespace = "target-namespace" ## string Partition = "target-partition" ## string RequestHeaders = { ## map Set = { "X-Web-Version" : "from-v1" } } ResponseHeaders = { ## map Set = { "X-Web-Version" : "to-v1" } } }, { Weight = 10 Service = "service" ServiceSubset = "v2" Namespace = "target-namespace" Partition = "target-partition" RequestHeaders = { Set = { "X-Web-Version" : "from-v2" } } ResponseHeaders = { Set = { "X-Web-Version" : "to-v2" } } } ] ``` ```json { "Kind" : "service-splitter", ## string | required "Name" : "config-entry-name", ## string | required "Namespace" : "main", ## string "Partition" : "partition", ## string "Meta" : { ## map "_key_" : "_value_" }, "Splits" : [ ## list | required { ## map "Weight" : 90, ## number | required "Service" : "service", ## string "ServiceSubset" : "v1", ## string "Namespace" : "target-namespace", ## string "Partition" : "target-partition", ## string "RequestHeaders" : { ## map "Set" : { "X-Web-Version": "from-v1" } }, "ResponseHeaders" : { ## map "Set" : { "X-Web-Version": "to-v1" } } }, { "Weight" : 10, "Service" : "service", "ServiceSubset" : "v2", "Namespace" : "target-namespace", "Partition" : "target-partition", "RequestHeaders" : { "Set" : { "X-Web-Version": "from-v2" } }, "ResponseHeaders" : { "Set" : { "X-Web-Version": "to-v2" } } } ] } ``` ```yaml apiVersion: consul.hashicorp.com/v1alpha1 # string | required kind: ServiceSplitter # string | required metadata: # object | required name: config-entry-name # string | required namespace: main # string spec: splits: # list - weight: 90 # floating point | required service: service # string serviceSubset: v1 # string namespace: target-namespace # string partition: target-partition # string requestHeaders: set: x-web-version: from-v1 # string responseHeaders: set: x-web-version: to-v1 # string - weight: 10 service: service serviceSubset: v2 namespace: target-namespace partition: target-partition requestHeaders: set: x-web-version: from-v2 responseHeaders: set: x-web-version: to-v2 ``` ## Specification This section provides details about the fields you can configure in the service splitter configuration entry. ### `Kind` Specifies the type of configuration entry to implement. #### Values - Default: none - This field is required. - Data type: String value that must be set to `service-splitter`. ### `Name` Specifies a name for the configuration entry. The name is metadata that you can use to reference the configuration entry when performing Consul operations, such as applying a configuration entry to a specific cluster. #### Values - Default: Defaults to the name of the node after writing the entry to the Consul server. - This field is required. - Data type: String ### `Namespace` Specifies the [namespace](/consul/docs/enterprise/namespaces) to apply the configuration entry. #### Values - Default: None - Data type: String ### `Partition` Specifies the [admin partition](/consul/docs/enterprise/admin-partitions) to apply the configuration entry. #### Values - Default: `Default` - Data type: String ### `Meta` Specifies key-value pairs to add to the KV store. #### Values - Default: none - Data type: Map of one or more key-value pairs - keys: String - values: String, integer, or float ### `Splits` Defines how much traffic to send to sets of service instances during a traffic split. #### Values - Default: None - This field is required. - Data type: list of objects that can contain the following fields: - `Weight`: The sum of weights for a set of service instances must add up to 100. - `Service`: This field is required. - `ServiceSubset` - `Namespace` - `Partition` - `RequestHeaders` - `ResponseHeaders` ### `Splits[].Weight` Specifies the percentage of traffic sent to the set of service instances specified in the [`Service`](#service) field. Each weight must be a floating integer between `0` and `100`. The smallest representable value is `.01`. The sum of weights across all splits must add up to `100`. #### Values - Default: `null` - This field is required. - Data type: Floating number from `.01` to `100`. ### `Splits[].Service` Specifies the name of the service to resolve. #### Values - Default: Inherits the value of the [`Name`](#name) field. - Data type: String ### `Splits[].ServiceSubset` Specifies a subset of the service to resolve. A service subset assigns a name to a specific subset of discoverable service instances within a datacenter, such as `version2` or `canary`. All services have an unnamed default subset that returns all healthy instances. You can define service subsets in a [service resolver configuration entry](/consul/docs/connect/config-entries/service-resolver), which are referenced by their names throughout the other configuration entries. This field overrides the default subset value in the service resolver configuration entry. #### Values - Default: If empty, the `split` uses the default subset. - Data type: String ### `Splits[].Namespace` Specifies the [namespace](/consul/docs/enterprise/namespaces) to use in the FQDN when resolving the service. #### Values - Default: Inherits the value of [`Namespace`](#Namespace) from the top-level of the configuration entry. - Data type: String ### `Splits[].Partition` Specifies the [admin partition](/consul/docs/enterprise/admin-partitions) to use in the FQDN when resolving the service. #### Values - Default: By default, the `service-splitter` uses the [admin partition specified in the top-level configuration entry](#partition). - Data type: String ### `Splits[].RequestHeaders` Specifies a set of HTTP-specific header modification rules applied to requests routed with the service split. You cannot configure request headers if the listener protocol is set to `tcp`. Refer to [Set HTTP Headers](#set-http-headers) for an example configuration. #### Values - Default: None - Values: Object containing one or more fields that define header modification rules - `Add`: Map of one or more key-value pairs - `Set`: Map of one or more key-value pairs - `Remove`: Map of one or more key-value pairs The following table describes how to configure values for request headers: | Rule | Description | Type | | --- | --- | --- | | `Add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings | | `Set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings | | `Remove` | Defines an list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings | #### Use variable placeholders For `Add` and `Set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` in your configuration entry allows you to pass a value that is generated when the split occurs. ### `Splits[].ResponseHeaders` Specifies a set of HTTP-specific header modification rules applied to responses routed with the service split. You cannot configure request headers if the listener protocol is set to `tcp`. Refer to [Set HTTP Headers](#set-http-headers) for an example configuration. #### Values - Default: None - Values: Object containing one or more fields that define header modification rules - `Add`: Map of one or more string key-value pairs - `Set`: Map of one or more string key-value pairs - `Remove`: Map of one or more string key-value pairs The following table describes how to configure values for response headers: | Rule | Description | Type | | --- | --- | --- | | `Add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings | | `Set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings | | `Remove` | Defines an list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings | #### Use variable placeholders For `Add` and `Set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` in your configuration entry allows you to pass a value that is generated when the split occurs. ### `apiVersion` Kubernetes-only parameter that specifies the version of the Consul API that the configuration entry maps to Kubernetes configurations. The value must be `consul.hashicorp.com/v1alpha1`. ### `kind` Specifies the type of configuration entry to implement. #### Values - Default: none - This field is required. - Data type: String value that must be set to `serviceSplitter`. ### `metadata.name` Specifies a name for the configuration entry. The name is metadata that you can use to reference the configuration entry when performing Consul operations, such as applying a configuration entry to a specific cluster. #### Values - Default: Inherits name from the host node - This field is required. - Data type: String ### `metadata.namespace` Specifies the Consul namespace to use for resolving the service. You can map Consul namespaces to Kubernetes Namespaces in different ways. Refer to [Custom Resource Definitions (CRDs) for Consul on Kubernetes](/consul/docs/k8s/crds#consul-enterprise) for additional information. #### Values - Default: None - Data type: String ### `spec` Kubernetes-only field that contains all of the configurations for service splitter pods. #### Values - Default: none - This field is required. - Data type: Object containing [`spec.splits`](#spec-splits) configuration ### `spec.meta` Specifies key-value pairs to add to the KV store. #### Values - Default: none - Data type: Map of one or more key-value pairs - keys: String - values: String, integer, or float ### `spec.splits` Defines how much traffic to send to sets of service instances during a traffic split. #### Values - Default: None - This field is required. - Data type: list of objects that can contain the following fields: - `weight`: The sum of weights for a set of service instances. The total defined value must add up to 100. - `service`: This field is required. - `serviceSubset` - `namespace` - `partition` - `requestHeaders` - `responseHeaders` ### `spec.splits[].weight` Specifies the percentage of traffic sent to the set of service instances specified in the [`spec.splits.service`](#spec-splits-service) field. Each weight must be a floating integer between `0` and `100`. The smallest representable value is `.01`. The sum of weights across all splits must add up to `100`. #### Values - Default: `null` - This field is required. - Data type: Floating integer from `.01` to `100` ### `spec.splits[].service` Specifies the name of the service to resolve. #### Values - Default: The service matching the configuration entry [`meta.name`](#metadata-name) field. - Data type: String ### `spec.splits[].serviceSubset` Specifies a subset of the service to resolve. This field overrides the `DefaultSubset`. #### Values - Default: Inherits the name of the default subset. - Data type: String ### `spec.splits[].namespace` Specifies the [namespace](/consul/docs/enterprise/namespaces) to use when resolving the service. #### Values - Default: The namespace specified in the top-level configuration entry. - Data type: String ### `spec.splits[].partition` Specifies which [admin partition](/consul/docs/enterprise/admin-partitions) to use in the FQDN when resolving the service. #### Values - Default: `default` - Data type: String ### `spec.splits[].requestHeaders` Specifies a set of HTTP-specific header modification rules applied to requests routed with the service split. You cannot configure request headers if the listener protocol is set to `tcp`. Refer to [Set HTTP Headers](#set-http-headers) for an example configuration. #### Values - Default: None - Values: Object containing one or more fields that define header modification rules - `add`: Map of one or more key-value pairs - `set`: Map of one or more key-value pairs - `remove`: Map of one or more key-value pairs The following table describes how to configure values for request headers: | Rule | Description | Type | | --- | --- | --- | | `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings | | `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings | | `remove` | Defines an list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings | #### Use variable placeholders For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` in your configuration entry allows you to pass a value that is generated when the split occurs. ### `spec.splits[].responseHeaders` Specifies a set of HTTP-specific header modification rules applied to responses routed with the service split. You cannot configure request headers if the listener protocol is set to `tcp`. Refer to [Set HTTP Headers](#set-http-headers) for an example configuration. #### Values - Default: None - Values: Object containing one or more fields that define header modification rules - `add`: Map of one or more string key-value pairs - `set`: Map of one or more string key-value pairs - `remove`: Map of one or more string key-value pairs The following table describes how to configure values for response headers: | Rule | Description | Type | | --- | --- | --- | | `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings | | `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings | | `remove` | Defines an list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings | #### Use variable placeholders For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` in your configuration entry allows you to pass a value that is generated when the split occurs. ## Examples The following examples demonstrate common service splitter configuration patterns for specific use cases. ### Two subsets of same service Split traffic between two subsets of the same service: ```hcl Kind = "service-splitter" Name = "web" Splits = [ { Weight = 90 ServiceSubset = "v1" }, { Weight = 10 ServiceSubset = "v2" }, ] ``` ```json { "Kind": "service-splitter", "Name": "web", "Splits": [ { "Weight": 90, "ServiceSubset": "v1" }, { "Weight": 10, "ServiceSubset": "v2" } ] } ``` ```yaml apiVersion: consul.hashicorp.com/v1alpha1 kind: ServiceSplitter metadata: name: web spec: splits: - weight: 90 serviceSubset: v1 - weight: 10 serviceSubset: v2 ``` ### Two different services Split traffic between two services: ```hcl Kind = "service-splitter" Name = "web" Splits = [ { Weight = 50 # will default to service with same name as config entry ("web") }, { Weight = 50 Service = "web-rewrite" }, ] ``` ```json { "Kind": "service-splitter", "Name": "web", "Splits": [ { "Weight": 50 }, { "Weight": 50, "Service": "web-rewrite" } ] } ``` ```yaml apiVersion: consul.hashicorp.com/v1alpha1 kind: ServiceSplitter metadata: name: web spec: splits: - weight: 50 # defaults to the service with same name as the configuration entry ("web") - weight: 50 service: web-rewrite ``` ### Set HTTP Headers Split traffic between two subsets with extra headers added so clients can tell which version: ```hcl Kind = "service-splitter" Name = "web" Splits = [ { Weight = 90 ServiceSubset = "v1" ResponseHeaders { Set { "X-Web-Version": "v1" } } }, { Weight = 10 ServiceSubset = "v2" ResponseHeaders { Set { "X-Web-Version": "v2" } } }, ] ``` ```json { "Kind": "service-splitter", "Name": "web", "Splits": [ { "Weight": 90, "ServiceSubset": "v1", "ResponseHeaders": { "Set": { "X-Web-Version": "v1" } } }, { "Weight": 10, "ServiceSubset": "v2", "ResponseHeaders": { "Set": { "X-Web-Version": "v2" } } } ] } ``` ```yaml apiVersion: consul.hashicorp.com/v1alpha1 kind: ServiceSplitter metadata: name: web spec: splits: - weight: 90 serviceSubset: v1 responseHeaders: set: x-web-version: v1 - weight: 10 serviceSubset: v2 responseHeaders: set: x-web-version: v2 ```