---
layout: docs
page_title: Consul Custom Resource Definitions
sidebar_title: Custom Resource Definitions
description: >-
  Consul supports managing configuration entries via Kubernetes Custom Resources.
  These custom resource can be used to manage the configuration for workloads
  deployed within the cluster.
---

# Custom Resource Definitions

-> This feature requires consul-helm >= 0.28.0, consul-k8s >= 0.22.0 and consul >= 1.8.4.

We support managing Consul [configuration entries](/docs/agent/config-entries)
via Kubernetes Custom Resources. Configuration entries are used to provide
cluster-wide defaults for the service mesh.

We currently support the follow configuration entry kinds:

- [`ProxyDefaults`](/docs/connect/config-entries/proxy-defaults)
- [`ServiceDefaults`](/docs/connect/config-entries/service-defaults)
- [`ServiceSplitter`](/docs/connect/config-entries/service-splitter)
- [`ServiceRouter`](/docs/connect/config-entries/service-router)
- [`ServiceResolver`](/docs/connect/config-entries/service-resolver)
- [`ServiceIntentions`](/docs/connect/config-entries/service-intentions) (requires Consul >= 1.9.0)
- [`IngressGateway`](/docs/connect/config-entries/ingress-gateway)
- [`TerminatingGateway`](/docs/connect/config-entries/terminating-gateway)

## Installation

Ensure you have at least version `0.28.0` of the helm chart:

```shell-session
$ helm search repo hashicorp/consul
NAME            	CHART VERSION	APP VERSION	DESCRIPTION
hashicorp/consul	0.28.0       	1.9.1      	Official HashiCorp Consul Chart
```

If you don't have `0.28.0`, you will need to update your helm repository cache:

```shell-session
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "hashicorp" chart repository
Update Complete. ⎈Happy Helming!⎈
```

Next, you must configure consul-helm via your `values.yaml` to install the custom resource definitions
and enable the controller that acts on them:

```yaml
global:
  name: consul

controller:
  enabled: true

connectInject:
  enabled: true
```

Note that:

1. `controller.enabled: true` installs the CRDs and enables the controller.
1. Configuration entries are used to configure Consul service mesh so it's also
   expected that `connectInject` will be enabled.

See [Install with Helm Chart](/docs/k8s/installation/install) for further installation
instructions.

## Upgrading An Existing Cluster to CRDs

If you have an existing Consul cluster running on Kubernetes you may need to perform
extra steps to migrate to CRDs. See [Upgrade An Existing Cluster to CRDs](/docs/k8s/crds/upgrade-to-crds) for full instructions.

## Usage

Once installed, you can use `kubectl` to create and manage Consul's configuration entries.

### Create

You can create configuration entries via `kubectl apply`.

```shell-session
$ cat <<EOF | kubectl apply -f -
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
  name: foo
spec:
  protocol: "http"
EOF

servicedefaults.consul.hashicorp.com/foo created
```

See [Configuration Entries](/docs/agent/config-entries) for detailed schema documentation.

### Get

You can use `kubectl get [kind] [name]` to get the status of the configuration entry:

```shell-session
$ kubectl get servicedefaults foo
NAME  SYNCED
foo   True
```

The `SYNCED` status shows whether the configuration entry was successfully created
in Consul.

### Describe

You can use `kubectl describe [kind] [name]` to investigate the status of the
configuration entry. If `SYNCED` is false, the status will contain the reason
why.

```shell-session
$ kubectl describe servicedefaults foo
Status:
  Conditions:
    Last Transition Time:  2020-10-09T21:15:50Z
    Status:                True
    Type:                  Synced
```

### Edit

You can use `kubectl edit [kind] [name]` to edit the configuration entry:

```shell
$ kubectl edit servicedefaults foo
# change protocol: http => protocol: tcp
servicedefaults.consul.hashicorp.com/foo edited
```

You can then use `kubectl get` to ensure the change was synced to Consul:

```shell-session
$ kubectl get servicedefaults foo
NAME  SYNCED
foo   True
```

### Delete

You can use `kubectl delete [kind] [name]` to delete the configuration entry:

```shell-session
$ kubectl delete servicedefaults foo
servicedefaults.consul.hashicorp.com "foo" deleted
```

You can then use `kubectl get` to ensure the configuration entry was deleted:

```shell-session
$ kubectl get servicedefaults foo
Error from server (NotFound): servicedefaults.consul.hashicorp.com "foo" not found
```

#### Delete Hanging

If running `kubectl delete` hangs without exiting, there may be
a dependent configuration entry registered with Consul that prevents the target configuration entry from being
deleted. For example, if you set the protocol of your service to `http` via `ServiceDefaults` and then
create a `ServiceSplitter`, you won't be able to delete the `ServiceDefaults`.

This is because by deleting the `ServiceDefaults` config, you are setting the
protocol back to the default which is `tcp`. Since `ServiceSplitter` requires
that the service has an `http` protocol, Consul will not allow the `ServiceDefaults`
to be deleted since that would put Consul into a broken state.

In order to delete the `ServiceDefaults` config, you would need to first delete
the `ServiceSplitter`.
