Problem
When using the Consul Terraform provider to manage Consul configuration entries, you may encounter a protocol mismatch error when attempting to delete a service-defaults entry. This issue occurs if the service is still referenced by another configuration entry, such as a service-router.
This problem can affect operations on downstream services referenced by the following config entry kinds:
service-routerservice-resolveringress-gatewayservice-splitterapi-gatewayterminating-gateway
When you remove a service-defaultsconfig entry resource from your configuration and run terraform apply, the operation fails with an error similar to the following:
│ Error: │ failed to delete 'api-v1' config entry: │ Unexpected response code: │ 500 (discovery chain "api" │ uses inconsistent protocols; │ service "api-v1" │ has "tcp" which is not "http")
Cause
Consul validates configuration changes to ensure protocol consistency across a service mesh traffic path. For example, path-based routing requires the http protocol to be used consistently.
When a service-defaults config entry is deleted, the associated service reverts to the default protocol, tcp. If another config entry (like a service-router) still references that service with an expectation of the http protocol, Consul's validation blocks the deletion to prevent a temporary protocol mismatch in the service chain. This validation failure causes the terraform apply command to fail.
Procedure
To resolve the error, you must first update the referencing service-router to remove the dependency on the service you intend to delete. After applying that change, you can proceed with deleting the service-defaults config entry.
This example assumes your configuration includes three entries:
- A
service-defaultsfor a main service namedapi. - A
service-defaultsfor a destination service namedapi-v1. - A
service-routerthat routes traffic fromapitoapi-v1.
The initial service-router resource routes requests with a /v1 prefix to the api-v1 service.
resource "consul_config_entry" "service_router_api" {
depends_on = [
consul_config_entry.service_defaults_api,
consul_config_entry.service_defaults_api_v1
]
kind = "service-router"
name = "api"
config_json = jsonencode({
Routes = [
{
Match = {
HTTP = {
PathPrefix = "/v1"
}
}
Destination = {
Service = "api-v1"
}
}
]
})
}To successfully remove the service_defaults_api_v1 resource, follow these steps.
Step 1: Modify the service-router Configuration
In your Terraform configuration, modify the consul_config_entry resource for the service-router to remove the route that references the api-v1 service. You should also comment out or remove the depends_on block to isolate the update.
The updated resource should appear as follows.
resource "consul_config_entry" "service_router_api" {
## depends_on = [ ... ]
kind = "service-router"
name = "api"
config_json = jsonencode({
Routes = []
})
}Step 2: Apply the Targeted service-router Update
Use a targeted terraform apply to update only the service-router config entry. This command updates the routing rules in Consul without attempting to delete any other resources.
$ terraform apply -target=consul_config_entry.service_router_api
Step 3: Perform a Full Apply to Delete the service-defaults Entry
With the dependency removed from the service-router, run a standard terraform apply. Consul's validation will now pass, and Terraform can successfully destroy the service_defaults_api_v1 resource.
$ terraform apply
Outcome
After completing the procedure, the targeted service-defaults config entry is successfully removed from Consul using Terraform.