diff --git a/README.md b/README.md
index b67e629f..01db016c 100644
--- a/README.md
+++ b/README.md
@@ -79,8 +79,6 @@ template:
   preserveJobs: false
   replicas: 1
   resources: {}
-  route:
-    routeName: horizon
   secret: osp-secret
 ```
 
@@ -110,8 +108,6 @@ template:
   preserveJobs: false
   replicas: 1
   resources: {}
-  route:
-    routeName: horizon
   secret: osp-secret
   memcachedInstance: my-custom-memcached #<<-- Custom memcached instance supplied here.
 ```
diff --git a/api/bases/horizon.openstack.org_horizons.yaml b/api/bases/horizon.openstack.org_horizons.yaml
index d7bb6b54..8656484b 100644
--- a/api/bases/horizon.openstack.org_horizons.yaml
+++ b/api/bases/horizon.openstack.org_horizons.yaml
@@ -83,6 +83,172 @@ spec:
                 description: NodeSelector to target subset of worker nodes running
                   this service
                 type: object
+              override:
+                description: Override, provides the ability to override the generated
+                  manifest of several child resources.
+                properties:
+                  service:
+                    description: Override configuration for the Service created to
+                      serve traffic to the cluster.
+                    properties:
+                      endpointURL:
+                        type: string
+                      metadata:
+                        description: EmbeddedLabelsAnnotations is an embedded subset
+                          of the fields included in k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta.
+                          Only labels and annotations are included.
+                        properties:
+                          annotations:
+                            additionalProperties:
+                              type: string
+                            description: 'Annotations is an unstructured key value
+                              map stored with a resource that may be set by external
+                              tools to store and retrieve arbitrary metadata. They
+                              are not queryable and should be preserved when modifying
+                              objects. More info: http://kubernetes.io/docs/user-guide/annotations'
+                            type: object
+                          labels:
+                            additionalProperties:
+                              type: string
+                            description: 'Map of string keys and values that can be
+                              used to organize and categorize (scope and select) objects.
+                              May match selectors of replication controllers and services.
+                              More info: http://kubernetes.io/docs/user-guide/labels'
+                            type: object
+                        type: object
+                      spec:
+                        description: OverrideServiceSpec is a subset of the fields
+                          included in https://pkg.go.dev/k8s.io/api@v0.26.6/core/v1#ServiceSpec
+                          Limited to Type, SessionAffinity, LoadBalancerSourceRanges,
+                          ExternalName, ExternalTrafficPolicy, SessionAffinityConfig,
+                          IPFamilyPolicy, LoadBalancerClass and InternalTrafficPolicy
+                        properties:
+                          externalName:
+                            description: externalName is the external reference that
+                              discovery mechanisms will return as an alias for this
+                              service (e.g. a DNS CNAME record). No proxying will
+                              be involved.  Must be a lowercase RFC-1123 hostname
+                              (https://tools.ietf.org/html/rfc1123) and requires `type`
+                              to be "ExternalName".
+                            type: string
+                          externalTrafficPolicy:
+                            description: externalTrafficPolicy describes how nodes
+                              distribute service traffic they receive on one of the
+                              Service's "externally-facing" addresses (NodePorts,
+                              ExternalIPs, and LoadBalancer IPs). If set to "Local",
+                              the proxy will configure the service in a way that assumes
+                              that external load balancers will take care of balancing
+                              the service traffic between nodes, and so each node
+                              will deliver traffic only to the node-local endpoints
+                              of the service, without masquerading the client source
+                              IP. (Traffic mistakenly sent to a node with no endpoints
+                              will be dropped.) The default value, "Cluster", uses
+                              the standard behavior of routing to all endpoints evenly
+                              (possibly modified by topology and other features).
+                              Note that traffic sent to an External IP or LoadBalancer
+                              IP from within the cluster will always get "Cluster"
+                              semantics, but clients sending to a NodePort from within
+                              the cluster may need to take traffic policy into account
+                              when picking a node.
+                            type: string
+                          internalTrafficPolicy:
+                            description: InternalTrafficPolicy describes how nodes
+                              distribute service traffic they receive on the ClusterIP.
+                              If set to "Local", the proxy will assume that pods only
+                              want to talk to endpoints of the service on the same
+                              node as the pod, dropping the traffic if there are no
+                              local endpoints. The default value, "Cluster", uses
+                              the standard behavior of routing to all endpoints evenly
+                              (possibly modified by topology and other features).
+                            type: string
+                          ipFamilyPolicy:
+                            description: IPFamilyPolicy represents the dual-stack-ness
+                              requested or required by this Service. If there is no
+                              value provided, then this field will be set to SingleStack.
+                              Services can be "SingleStack" (a single IP family),
+                              "PreferDualStack" (two IP families on dual-stack configured
+                              clusters or a single IP family on single-stack clusters),
+                              or "RequireDualStack" (two IP families on dual-stack
+                              configured clusters, otherwise fail). The ipFamilies
+                              and clusterIPs fields depend on the value of this field.
+                              This field will be wiped when updating a service to
+                              type ExternalName.
+                            type: string
+                          loadBalancerClass:
+                            description: loadBalancerClass is the class of the load
+                              balancer implementation this Service belongs to. If
+                              specified, the value of this field must be a label-style
+                              identifier, with an optional prefix, e.g. "internal-vip"
+                              or "example.com/internal-vip". Unprefixed names are
+                              reserved for end-users. This field can only be set when
+                              the Service type is 'LoadBalancer'. If not set, the
+                              default load balancer implementation is used, today
+                              this is typically done through the cloud provider integration,
+                              but should apply for any default implementation. If
+                              set, it is assumed that a load balancer implementation
+                              is watching for Services with a matching class. Any
+                              default load balancer implementation (e.g. cloud providers)
+                              should ignore Services that set this field. This field
+                              can only be set when creating or updating a Service
+                              to type 'LoadBalancer'. Once set, it can not be changed.
+                              This field will be wiped when a service is updated to
+                              a non 'LoadBalancer' type.
+                            type: string
+                          loadBalancerSourceRanges:
+                            description: 'If specified and supported by the platform,
+                              this will restrict traffic through the cloud-provider
+                              load-balancer will be restricted to the specified client
+                              IPs. This field will be ignored if the cloud-provider
+                              does not support the feature." More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/'
+                            items:
+                              type: string
+                            type: array
+                          sessionAffinity:
+                            description: 'Supports "ClientIP" and "None". Used to
+                              maintain session affinity. Enable client IP based session
+                              affinity. Must be ClientIP or None. Defaults to None.
+                              More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies'
+                            type: string
+                          sessionAffinityConfig:
+                            description: sessionAffinityConfig contains the configurations
+                              of session affinity.
+                            properties:
+                              clientIP:
+                                description: clientIP contains the configurations
+                                  of Client IP based session affinity.
+                                properties:
+                                  timeoutSeconds:
+                                    description: timeoutSeconds specifies the seconds
+                                      of ClientIP type session sticky time. The value
+                                      must be >0 && <=86400(for 1 day) if ServiceAffinity
+                                      == "ClientIP". Default value is 10800(for 3
+                                      hours).
+                                    format: int32
+                                    type: integer
+                                type: object
+                            type: object
+                          type:
+                            description: 'type determines how the Service is exposed.
+                              Defaults to ClusterIP. Valid options are ExternalName,
+                              ClusterIP, NodePort, and LoadBalancer. "ClusterIP" allocates
+                              a cluster-internal IP address for load-balancing to
+                              endpoints. Endpoints are determined by the selector
+                              or if that is not specified, by manual construction
+                              of an Endpoints object or EndpointSlice objects. If
+                              clusterIP is "None", no virtual IP is allocated and
+                              the endpoints are published as a set of endpoints rather
+                              than a virtual IP. "NodePort" builds on ClusterIP and
+                              allocates a port on every node which routes to the same
+                              endpoints as the clusterIP. "LoadBalancer" builds on
+                              NodePort and creates an external load-balancer (if supported
+                              in the current cloud) which routes to the same endpoints
+                              as the clusterIP. "ExternalName" aliases this service
+                              to the specified externalName. Several other fields
+                              do not apply to ExternalName services. More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types'
+                            type: string
+                        type: object
+                    type: object
+                type: object
               preserveJobs:
                 default: false
                 description: PreserveJobs - do not delete jobs after they finished
@@ -143,32 +309,6 @@ spec:
                       to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
                     type: object
                 type: object
-              route:
-                description: HorizonRoute holds all of the necessary options for configuring
-                  the Horizon Route object. This can be used to configure TLS TODO(bshephar)
-                  Implement everything about this. It's just a placeholder at the
-                  moment.
-                properties:
-                  routeLocation:
-                    description: TODO(bshephar) We need to implement TLS handling
-                      here to secure the route
-                    type: string
-                  routeName:
-                    default: horizon
-                    type: string
-                  routeTLSCA:
-                    description: TODO(bshephar) We need to implement TLS handling
-                      here to secure the route
-                    type: string
-                  routeTLSEnabled:
-                    description: TODO(bshephar) We need to implement TLS handling
-                      here to secure the route
-                    type: string
-                  routeTLSKey:
-                    description: TODO(bshephar) We need to implement TLS handling
-                      here to secure the route
-                    type: string
-                type: object
               secret:
                 description: Secret containing OpenStack password information for
                   Horizon Secret Key
diff --git a/api/go.mod b/api/go.mod
index a47269a7..f02c6095 100644
--- a/api/go.mod
+++ b/api/go.mod
@@ -3,17 +3,12 @@ module github.com/openstack-k8s-operators/horizon-operator/api
 go 1.19
 
 require (
-	github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230913075424-2680ce4b6ad2
+	github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216
 	k8s.io/api v0.26.9
 	k8s.io/apimachinery v0.26.9
 	sigs.k8s.io/controller-runtime v0.14.6
 )
 
-require (
-	go.uber.org/zap v1.26.0 // indirect
-	golang.org/x/tools v0.13.0 // indirect
-)
-
 require (
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
diff --git a/api/go.sum b/api/go.sum
index 0ae19d77..742ec4dc 100644
--- a/api/go.sum
+++ b/api/go.sum
@@ -221,8 +221,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
 github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
-github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230913075424-2680ce4b6ad2 h1:/ez+9PSwtucQ9v1I5X72xlP5UJztTMPH4M5gDAJAatc=
-github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230913075424-2680ce4b6ad2/go.mod h1:bG2JdbaO4bR4u8rtXZ7MgmMELuEseTkL2BPgk9JBYmY=
+github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216 h1:arYbQA6bLyXJkHm+6M6gPc4YpWMFjs5qkG16Yii4UDo=
+github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216/go.mod h1:Ge7Yf6AUmjEvJK9AIW2bT5udLzBIcK59b1QxqymncaQ=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -490,7 +490,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
 golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
-golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/api/v1beta1/horizon_types.go b/api/v1beta1/horizon_types.go
index a87810ee..fb825ba2 100644
--- a/api/v1beta1/horizon_types.go
+++ b/api/v1beta1/horizon_types.go
@@ -20,6 +20,7 @@ import (
 	"fmt"
 
 	condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
+	"github.com/openstack-k8s-operators/lib-common/modules/common/service"
 	"github.com/openstack-k8s-operators/lib-common/modules/common/util"
 
 	corev1 "k8s.io/api/core/v1"
@@ -80,16 +81,20 @@ type HorizonSpec struct {
 	// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
 	Resources corev1.ResourceRequirements `json:"resources,omitempty"`
 
-	// +kubebuilder:validation:Optional
-	// HorizonRoute holds all of the necessary options for configuring the Horizon Route object.
-	// This can be used to configure TLS
-	//TODO(bshephar) Implement everything about this. It's just a placeholder at the moment.
-	Route HorizonRoute `json:"route,omitempty"`
-
 	// +kubebuilder:validation:Required
 	// +kubebuilder:default=memcached
 	// Memcached instance name.
 	MemcachedInstance string `json:"memcachedInstance"`
+
+	// +kubebuilder:validation:Optional
+	// Override, provides the ability to override the generated manifest of several child resources.
+	Override HorizionOverrideSpec `json:"override,omitempty"`
+}
+
+// HorizionOverrideSpec to override the generated manifest of several child resources.
+type HorizionOverrideSpec struct {
+	// Override configuration for the Service created to serve traffic to the cluster.
+	Service *service.RoutedOverrideSpec `json:"service,omitempty"`
 }
 
 // HorizonDebug can be used to enable debug in the Horizon service
@@ -100,30 +105,6 @@ type HorizonDebug struct {
 	Service bool `json:"service"`
 }
 
-// HorizonRoute is used to define all of the information for the OpenShift route
-// todo(bshephar) implement
-type HorizonRoute struct {
-	// +kubebuilder:validation:Optional
-	// +kubebuilder:default=horizon
-	RouteName string `json:"routeName"`
-
-	//TODO(bshephar) We need to implement TLS handling here to secure the route
-	// +kubebuilder:validation:Optional
-	RouteTLSEnabled string `json:"routeTLSEnabled,omitempty"`
-
-	//TODO(bshephar) We need to implement TLS handling here to secure the route
-	// +kubebuilder:validation:Optional
-	RouteTLSCA string `json:"routeTLSCA,omitempty"`
-
-	//TODO(bshephar) We need to implement TLS handling here to secure the route
-	// +kubebuilder:validation:Optional
-	RouteTLSKey string `json:"routeTLSKey,omitempty"`
-
-	//TODO(bshephar) We need to implement TLS handling here to secure the route
-	// +kubebuilder:validation:Optional
-	RouteLocation string `json:"routeLocation,omitempty"`
-}
-
 // HorizonStatus defines the observed state of Horizon
 type HorizonStatus struct {
 	// ReadyCount of Horizon instances
diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go
index b9d9dd43..d78311cb 100644
--- a/api/v1beta1/zz_generated.deepcopy.go
+++ b/api/v1beta1/zz_generated.deepcopy.go
@@ -23,9 +23,30 @@ package v1beta1
 
 import (
 	"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
+	"github.com/openstack-k8s-operators/lib-common/modules/common/service"
 	"k8s.io/apimachinery/pkg/runtime"
 )
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HorizionOverrideSpec) DeepCopyInto(out *HorizionOverrideSpec) {
+	*out = *in
+	if in.Service != nil {
+		in, out := &in.Service, &out.Service
+		*out = new(service.RoutedOverrideSpec)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizionOverrideSpec.
+func (in *HorizionOverrideSpec) DeepCopy() *HorizionOverrideSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(HorizionOverrideSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *Horizon) DeepCopyInto(out *Horizon) {
 	*out = *in
@@ -115,21 +136,6 @@ func (in *HorizonList) DeepCopyObject() runtime.Object {
 	return nil
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *HorizonRoute) DeepCopyInto(out *HorizonRoute) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizonRoute.
-func (in *HorizonRoute) DeepCopy() *HorizonRoute {
-	if in == nil {
-		return nil
-	}
-	out := new(HorizonRoute)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *HorizonSpec) DeepCopyInto(out *HorizonSpec) {
 	*out = *in
@@ -154,7 +160,7 @@ func (in *HorizonSpec) DeepCopyInto(out *HorizonSpec) {
 		}
 	}
 	in.Resources.DeepCopyInto(&out.Resources)
-	out.Route = in.Route
+	in.Override.DeepCopyInto(&out.Override)
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizonSpec.
diff --git a/config/crd/bases/horizon.openstack.org_horizons.yaml b/config/crd/bases/horizon.openstack.org_horizons.yaml
index d7bb6b54..8656484b 100644
--- a/config/crd/bases/horizon.openstack.org_horizons.yaml
+++ b/config/crd/bases/horizon.openstack.org_horizons.yaml
@@ -83,6 +83,172 @@ spec:
                 description: NodeSelector to target subset of worker nodes running
                   this service
                 type: object
+              override:
+                description: Override, provides the ability to override the generated
+                  manifest of several child resources.
+                properties:
+                  service:
+                    description: Override configuration for the Service created to
+                      serve traffic to the cluster.
+                    properties:
+                      endpointURL:
+                        type: string
+                      metadata:
+                        description: EmbeddedLabelsAnnotations is an embedded subset
+                          of the fields included in k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta.
+                          Only labels and annotations are included.
+                        properties:
+                          annotations:
+                            additionalProperties:
+                              type: string
+                            description: 'Annotations is an unstructured key value
+                              map stored with a resource that may be set by external
+                              tools to store and retrieve arbitrary metadata. They
+                              are not queryable and should be preserved when modifying
+                              objects. More info: http://kubernetes.io/docs/user-guide/annotations'
+                            type: object
+                          labels:
+                            additionalProperties:
+                              type: string
+                            description: 'Map of string keys and values that can be
+                              used to organize and categorize (scope and select) objects.
+                              May match selectors of replication controllers and services.
+                              More info: http://kubernetes.io/docs/user-guide/labels'
+                            type: object
+                        type: object
+                      spec:
+                        description: OverrideServiceSpec is a subset of the fields
+                          included in https://pkg.go.dev/k8s.io/api@v0.26.6/core/v1#ServiceSpec
+                          Limited to Type, SessionAffinity, LoadBalancerSourceRanges,
+                          ExternalName, ExternalTrafficPolicy, SessionAffinityConfig,
+                          IPFamilyPolicy, LoadBalancerClass and InternalTrafficPolicy
+                        properties:
+                          externalName:
+                            description: externalName is the external reference that
+                              discovery mechanisms will return as an alias for this
+                              service (e.g. a DNS CNAME record). No proxying will
+                              be involved.  Must be a lowercase RFC-1123 hostname
+                              (https://tools.ietf.org/html/rfc1123) and requires `type`
+                              to be "ExternalName".
+                            type: string
+                          externalTrafficPolicy:
+                            description: externalTrafficPolicy describes how nodes
+                              distribute service traffic they receive on one of the
+                              Service's "externally-facing" addresses (NodePorts,
+                              ExternalIPs, and LoadBalancer IPs). If set to "Local",
+                              the proxy will configure the service in a way that assumes
+                              that external load balancers will take care of balancing
+                              the service traffic between nodes, and so each node
+                              will deliver traffic only to the node-local endpoints
+                              of the service, without masquerading the client source
+                              IP. (Traffic mistakenly sent to a node with no endpoints
+                              will be dropped.) The default value, "Cluster", uses
+                              the standard behavior of routing to all endpoints evenly
+                              (possibly modified by topology and other features).
+                              Note that traffic sent to an External IP or LoadBalancer
+                              IP from within the cluster will always get "Cluster"
+                              semantics, but clients sending to a NodePort from within
+                              the cluster may need to take traffic policy into account
+                              when picking a node.
+                            type: string
+                          internalTrafficPolicy:
+                            description: InternalTrafficPolicy describes how nodes
+                              distribute service traffic they receive on the ClusterIP.
+                              If set to "Local", the proxy will assume that pods only
+                              want to talk to endpoints of the service on the same
+                              node as the pod, dropping the traffic if there are no
+                              local endpoints. The default value, "Cluster", uses
+                              the standard behavior of routing to all endpoints evenly
+                              (possibly modified by topology and other features).
+                            type: string
+                          ipFamilyPolicy:
+                            description: IPFamilyPolicy represents the dual-stack-ness
+                              requested or required by this Service. If there is no
+                              value provided, then this field will be set to SingleStack.
+                              Services can be "SingleStack" (a single IP family),
+                              "PreferDualStack" (two IP families on dual-stack configured
+                              clusters or a single IP family on single-stack clusters),
+                              or "RequireDualStack" (two IP families on dual-stack
+                              configured clusters, otherwise fail). The ipFamilies
+                              and clusterIPs fields depend on the value of this field.
+                              This field will be wiped when updating a service to
+                              type ExternalName.
+                            type: string
+                          loadBalancerClass:
+                            description: loadBalancerClass is the class of the load
+                              balancer implementation this Service belongs to. If
+                              specified, the value of this field must be a label-style
+                              identifier, with an optional prefix, e.g. "internal-vip"
+                              or "example.com/internal-vip". Unprefixed names are
+                              reserved for end-users. This field can only be set when
+                              the Service type is 'LoadBalancer'. If not set, the
+                              default load balancer implementation is used, today
+                              this is typically done through the cloud provider integration,
+                              but should apply for any default implementation. If
+                              set, it is assumed that a load balancer implementation
+                              is watching for Services with a matching class. Any
+                              default load balancer implementation (e.g. cloud providers)
+                              should ignore Services that set this field. This field
+                              can only be set when creating or updating a Service
+                              to type 'LoadBalancer'. Once set, it can not be changed.
+                              This field will be wiped when a service is updated to
+                              a non 'LoadBalancer' type.
+                            type: string
+                          loadBalancerSourceRanges:
+                            description: 'If specified and supported by the platform,
+                              this will restrict traffic through the cloud-provider
+                              load-balancer will be restricted to the specified client
+                              IPs. This field will be ignored if the cloud-provider
+                              does not support the feature." More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/'
+                            items:
+                              type: string
+                            type: array
+                          sessionAffinity:
+                            description: 'Supports "ClientIP" and "None". Used to
+                              maintain session affinity. Enable client IP based session
+                              affinity. Must be ClientIP or None. Defaults to None.
+                              More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies'
+                            type: string
+                          sessionAffinityConfig:
+                            description: sessionAffinityConfig contains the configurations
+                              of session affinity.
+                            properties:
+                              clientIP:
+                                description: clientIP contains the configurations
+                                  of Client IP based session affinity.
+                                properties:
+                                  timeoutSeconds:
+                                    description: timeoutSeconds specifies the seconds
+                                      of ClientIP type session sticky time. The value
+                                      must be >0 && <=86400(for 1 day) if ServiceAffinity
+                                      == "ClientIP". Default value is 10800(for 3
+                                      hours).
+                                    format: int32
+                                    type: integer
+                                type: object
+                            type: object
+                          type:
+                            description: 'type determines how the Service is exposed.
+                              Defaults to ClusterIP. Valid options are ExternalName,
+                              ClusterIP, NodePort, and LoadBalancer. "ClusterIP" allocates
+                              a cluster-internal IP address for load-balancing to
+                              endpoints. Endpoints are determined by the selector
+                              or if that is not specified, by manual construction
+                              of an Endpoints object or EndpointSlice objects. If
+                              clusterIP is "None", no virtual IP is allocated and
+                              the endpoints are published as a set of endpoints rather
+                              than a virtual IP. "NodePort" builds on ClusterIP and
+                              allocates a port on every node which routes to the same
+                              endpoints as the clusterIP. "LoadBalancer" builds on
+                              NodePort and creates an external load-balancer (if supported
+                              in the current cloud) which routes to the same endpoints
+                              as the clusterIP. "ExternalName" aliases this service
+                              to the specified externalName. Several other fields
+                              do not apply to ExternalName services. More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types'
+                            type: string
+                        type: object
+                    type: object
+                type: object
               preserveJobs:
                 default: false
                 description: PreserveJobs - do not delete jobs after they finished
@@ -143,32 +309,6 @@ spec:
                       to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
                     type: object
                 type: object
-              route:
-                description: HorizonRoute holds all of the necessary options for configuring
-                  the Horizon Route object. This can be used to configure TLS TODO(bshephar)
-                  Implement everything about this. It's just a placeholder at the
-                  moment.
-                properties:
-                  routeLocation:
-                    description: TODO(bshephar) We need to implement TLS handling
-                      here to secure the route
-                    type: string
-                  routeName:
-                    default: horizon
-                    type: string
-                  routeTLSCA:
-                    description: TODO(bshephar) We need to implement TLS handling
-                      here to secure the route
-                    type: string
-                  routeTLSEnabled:
-                    description: TODO(bshephar) We need to implement TLS handling
-                      here to secure the route
-                    type: string
-                  routeTLSKey:
-                    description: TODO(bshephar) We need to implement TLS handling
-                      here to secure the route
-                    type: string
-                type: object
               secret:
                 description: Secret containing OpenStack password information for
                   Horizon Secret Key
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index cbf28dc3..30bdcd96 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -145,18 +145,6 @@ rules:
   - list
   - update
   - watch
-- apiGroups:
-  - route.openshift.io
-  resources:
-  - routes
-  verbs:
-  - create
-  - delete
-  - get
-  - list
-  - patch
-  - update
-  - watch
 - apiGroups:
   - security.openshift.io
   resourceNames:
diff --git a/controllers/horizon_controller.go b/controllers/horizon_controller.go
index 8b6bed57..782e9fae 100644
--- a/controllers/horizon_controller.go
+++ b/controllers/horizon_controller.go
@@ -23,7 +23,6 @@ import (
 	"time"
 
 	"github.com/go-logr/logr"
-	routev1 "github.com/openshift/api/route/v1"
 	horizonv1beta1 "github.com/openstack-k8s-operators/horizon-operator/api/v1beta1"
 	horizon "github.com/openstack-k8s-operators/horizon-operator/pkg/horizon"
 	memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1"
@@ -38,6 +37,7 @@ import (
 	labels "github.com/openstack-k8s-operators/lib-common/modules/common/labels"
 	common_rbac "github.com/openstack-k8s-operators/lib-common/modules/common/rbac"
 	oko_secret "github.com/openstack-k8s-operators/lib-common/modules/common/secret"
+	"github.com/openstack-k8s-operators/lib-common/modules/common/service"
 	util "github.com/openstack-k8s-operators/lib-common/modules/common/util"
 
 	appsv1 "k8s.io/api/apps/v1"
@@ -48,6 +48,7 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/rand"
 	"k8s.io/client-go/kubernetes"
+	"k8s.io/utils/ptr"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@@ -91,7 +92,6 @@ type HorizonReconciler struct {
 //+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete;
 //+kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create;update;patch;delete;
 //+kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete;
-//+kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=get;list;watch;create;update;patch;delete;
 //+kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneapis,verbs=get;list;watch;
 //+kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneendpoints,verbs=get;list;watch;
 //+kubebuilder:rbac:groups=memcached.openstack.org,resources=memcacheds,verbs=get;list;watch;
@@ -237,7 +237,6 @@ func (r *HorizonReconciler) SetupWithManager(mgr ctrl.Manager) error {
 		Owns(&corev1.Secret{}).
 		Owns(&corev1.ConfigMap{}).
 		Owns(&appsv1.Deployment{}).
-		Owns(&routev1.Route{}).
 		Owns(&corev1.ServiceAccount{}).
 		Owns(&rbacv1.Role{}).
 		Owns(&rbacv1.RoleBinding{}).
@@ -267,21 +266,33 @@ func (r *HorizonReconciler) reconcileInit(
 	l.Info("Reconciling Service init")
 
 	//
-	// expose the service (create service, route and return the created endpoint URLs)
+	// expose the service (create service and return the created endpoint URL)
 	//
-	var horizonPorts = map[endpoint.Endpoint]endpoint.Data{
-		endpoint.EndpointPublic: {
-			Port: horizon.HorizonPublicPort,
-		},
+	endpointName := horizon.ServiceName
+
+	svcOverride := instance.Spec.Override.Service
+	if svcOverride == nil {
+		svcOverride = &service.RoutedOverrideSpec{}
+	}
+	if svcOverride.EmbeddedLabelsAnnotations == nil {
+		svcOverride.EmbeddedLabelsAnnotations = &service.EmbeddedLabelsAnnotations{}
 	}
 
-	apiEndpoints, ctrlResult, err := endpoint.ExposeEndpoints(
-		ctx,
-		helper,
-		horizon.ServiceName,
-		serviceLabels,
-		horizonPorts,
-		time.Second * 5,
+	// Create the service
+	svc, err := service.NewService(
+		service.GenericService(&service.GenericServiceDetails{
+			Name:      endpointName,
+			Namespace: instance.Namespace,
+			Labels:    serviceLabels,
+			Selector:  serviceLabels,
+			Port: service.GenericServicePort{
+				Name:     endpointName,
+				Port:     horizon.HorizonPublicPort,
+				Protocol: corev1.ProtocolTCP,
+			},
+		}),
+		5,
+		&svcOverride.OverrideSpec,
 	)
 	if err != nil {
 		instance.Status.Conditions.Set(condition.FalseCondition(
@@ -290,9 +301,37 @@ func (r *HorizonReconciler) reconcileInit(
 			condition.SeverityWarning,
 			condition.ExposeServiceReadyErrorMessage,
 			err.Error()))
-		return ctrlResult, err
+
+		return ctrl.Result{}, err
 	}
-	if (ctrlResult != ctrl.Result{}) {
+
+	// add Annotation to whether creating an ingress is required or not
+	if svc.GetServiceType() == corev1.ServiceTypeClusterIP {
+		svc.AddAnnotation(map[string]string{
+			service.AnnotationIngressCreateKey: "true",
+		})
+	} else {
+		svc.AddAnnotation(map[string]string{
+			service.AnnotationIngressCreateKey: "false",
+		})
+		if svc.GetServiceType() == corev1.ServiceTypeLoadBalancer {
+			svc.AddAnnotation(map[string]string{
+				service.AnnotationHostnameKey: svc.GetServiceHostname(), // add annotation to register service name in dnsmasq
+			})
+		}
+	}
+
+	ctrlResult, err := svc.CreateOrPatch(ctx, helper)
+	if err != nil {
+		instance.Status.Conditions.Set(condition.FalseCondition(
+			condition.ExposeServiceReadyCondition,
+			condition.ErrorReason,
+			condition.SeverityWarning,
+			condition.ExposeServiceReadyErrorMessage,
+			err.Error()))
+
+		return ctrlResult, err
+	} else if (ctrlResult != ctrl.Result{}) {
 		instance.Status.Conditions.Set(condition.FalseCondition(
 			condition.ExposeServiceReadyCondition,
 			condition.RequestedReason,
@@ -300,12 +339,20 @@ func (r *HorizonReconciler) reconcileInit(
 			condition.ExposeServiceReadyRunningMessage))
 		return ctrlResult, nil
 	}
+	// create service - end
+
+	// TODO: TLS, pass in https as protocol
+	apiEndpoint, err := svc.GetAPIEndpoint(
+		svcOverride.EndpointURL, ptr.To(service.ProtocolHTTP), "")
+	if err != nil {
+		return ctrl.Result{}, err
+	}
 	instance.Status.Conditions.MarkTrue(condition.ExposeServiceReadyCondition, condition.ExposeServiceReadyMessage)
 
 	//
-	// Update instance status with service endpoint url from route host information
+	// Update instance status with service endpoint url information
 	//
-	instance.Status.Endpoint = apiEndpoints[string(endpoint.EndpointPublic)]
+	instance.Status.Endpoint = apiEndpoint
 
 	// expose service - end
 
@@ -489,7 +536,7 @@ func (r *HorizonReconciler) reconcileNormal(ctx context.Context, instance *horiz
 
 	depl := deployment.NewDeployment(
 		deplDef,
-		time.Second * 5,
+		time.Second*5,
 	)
 
 	ctrlResult, err = depl.CreateOrPatch(ctx, helper)
diff --git a/go.mod b/go.mod
index 54cddb69..5ce89854 100644
--- a/go.mod
+++ b/go.mod
@@ -9,12 +9,11 @@ require (
 	github.com/google/uuid v1.3.1
 	github.com/onsi/ginkgo/v2 v2.12.0
 	github.com/onsi/gomega v1.27.10
-	github.com/openshift/api v3.9.0+incompatible
 	github.com/openstack-k8s-operators/horizon-operator/api v0.1.1-0.20230828060631-f5678c16313e
 	github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230914145253-116f307c7875
-	github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230914163026-da9aa9de960a
-	github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230913075424-2680ce4b6ad2
-	github.com/openstack-k8s-operators/lib-common/modules/test v0.1.2-0.20230913075424-2680ce4b6ad2
+	github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230920085319-92ae0260bbf3
+	github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216
+	github.com/openstack-k8s-operators/lib-common/modules/test v0.1.2-0.20230919113507-d74c2f31d216
 	k8s.io/api v0.26.9
 	k8s.io/apimachinery v0.26.9
 	k8s.io/client-go v0.26.9
@@ -24,7 +23,7 @@ require (
 
 require (
 	github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0 // indirect
-	github.com/openstack-k8s-operators/mariadb-operator/api v0.1.1-0.20230912174650-9fb4c4a76e55 // indirect
+	github.com/openstack-k8s-operators/mariadb-operator/api v0.1.1-0.20230913081601-9e4fc8aadad5 // indirect
 	golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
 )
 
@@ -57,7 +56,8 @@ require (
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
-	github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230913075424-2680ce4b6ad2 // indirect
+	github.com/openshift/api v3.9.0+incompatible // indirect
+	github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230919113507-d74c2f31d216 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/prometheus/client_golang v1.14.0 // indirect
 	github.com/prometheus/client_model v0.3.0 // indirect
diff --git a/go.sum b/go.sum
index c935c13d..acb54c3d 100644
--- a/go.sum
+++ b/go.sum
@@ -237,16 +237,16 @@ github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 h1:rncLxJBpFGqBztyxC
 github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7/go.mod h1:ctXNyWanKEjGj8sss1KjjHQ3ENKFm33FFnS5BKaIPh4=
 github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230914145253-116f307c7875 h1:DUlCjbi3XxH66oL97MFZF5wgL28HdU+r8TkBZVw7WIc=
 github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230914145253-116f307c7875/go.mod h1:NgrvT3CKMu6fE8Nt1H79qHx11L3I7Bb2eItniM7c9ow=
-github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230914163026-da9aa9de960a h1:MFYwi2Xk9r3OMPToCSbvqYVNrm7P+aFzGDN0eVNpgu8=
-github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230914163026-da9aa9de960a/go.mod h1:nxrbUOIGMJ1h2pNlawhURdt/XJ95dW2wZGedmOVo2aw=
-github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230913075424-2680ce4b6ad2 h1:/ez+9PSwtucQ9v1I5X72xlP5UJztTMPH4M5gDAJAatc=
-github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230913075424-2680ce4b6ad2/go.mod h1:bG2JdbaO4bR4u8rtXZ7MgmMELuEseTkL2BPgk9JBYmY=
-github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230913075424-2680ce4b6ad2 h1:4L5DRfSnomBfyRwCfAzqQwk0+osnIbyJ1VvKBy+tzyY=
-github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230913075424-2680ce4b6ad2/go.mod h1:NZ6weu5xOAkNPTqg1luC22DO7ZbyqiilRkvrFfhjFm0=
-github.com/openstack-k8s-operators/lib-common/modules/test v0.1.2-0.20230913075424-2680ce4b6ad2 h1:TJpuax2pifQbOtsPv78DjoC+f/7+/3Tw+CdXBxxDxAs=
-github.com/openstack-k8s-operators/lib-common/modules/test v0.1.2-0.20230913075424-2680ce4b6ad2/go.mod h1:fuKZmOKDEx/2f1+VLQyXF6iH9FX0ynbtyuvC/XjuJzg=
-github.com/openstack-k8s-operators/mariadb-operator/api v0.1.1-0.20230912174650-9fb4c4a76e55 h1:iwa4MpjFHCl+qfiimlUwVm1BV+LGjbGYtXIwLe/QHwk=
-github.com/openstack-k8s-operators/mariadb-operator/api v0.1.1-0.20230912174650-9fb4c4a76e55/go.mod h1:rh0jKCJYeHXVWfJnXl22AuaTRkYfHwmKuK6O3IeTG4A=
+github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230920085319-92ae0260bbf3 h1:6VCz/ZBTJEQJTx4+z8UxLv3WITa4Bgx5CSP237wJ5xM=
+github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230920085319-92ae0260bbf3/go.mod h1:ta6w/29i4WuWkQp6I4cOLwMGQ5/vJI0y8Em7u+M34jo=
+github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216 h1:arYbQA6bLyXJkHm+6M6gPc4YpWMFjs5qkG16Yii4UDo=
+github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216/go.mod h1:Ge7Yf6AUmjEvJK9AIW2bT5udLzBIcK59b1QxqymncaQ=
+github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230919113507-d74c2f31d216 h1:h76faqi4WAXBs3D2B0GLUdlCjS0dh78wRL0d5RZUwhk=
+github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230919113507-d74c2f31d216/go.mod h1:GHi64tgyC75/vuT8Crda0yN5iCIYiSyS4bpzYJjX7MA=
+github.com/openstack-k8s-operators/lib-common/modules/test v0.1.2-0.20230919113507-d74c2f31d216 h1:QyzzvG8iaDFwx6Lo44dCyf2tRtgk0sqniXjgJpiW32g=
+github.com/openstack-k8s-operators/lib-common/modules/test v0.1.2-0.20230919113507-d74c2f31d216/go.mod h1:RfLOPJbmPzPZ4XHwwDc2tFbbw5zxZL15JFGwb5c6VaU=
+github.com/openstack-k8s-operators/mariadb-operator/api v0.1.1-0.20230913081601-9e4fc8aadad5 h1:dQcSQuXfgzgOhc4v+zD0jE6WWhn6FHr5nALOjJBPxyI=
+github.com/openstack-k8s-operators/mariadb-operator/api v0.1.1-0.20230913081601-9e4fc8aadad5/go.mod h1:mJyhm/YiQZaYhLvOuLng/ITpwx8HvsYVht+VotS1Ed8=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
diff --git a/main.go b/main.go
index 0f4585c2..4654c406 100644
--- a/main.go
+++ b/main.go
@@ -34,7 +34,6 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/healthz"
 	"sigs.k8s.io/controller-runtime/pkg/log/zap"
 
-	routev1 "github.com/openshift/api/route/v1"
 	memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1"
 	keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1"
 
@@ -52,13 +51,9 @@ func init() {
 	utilruntime.Must(clientgoscheme.AddToScheme(scheme))
 
 	utilruntime.Must(horizonv1beta1.AddToScheme(scheme))
-	//+kubebuilder:scaffold:scheme
-
-	// As we are creating routes, it's necessary to register the routev1.Route
-	// type with the scheme
-	utilruntime.Must(routev1.AddToScheme(scheme))
 	utilruntime.Must(keystonev1.AddToScheme(scheme))
 	utilruntime.Must(memcachedv1.AddToScheme(scheme))
+	//+kubebuilder:scaffold:scheme
 }
 
 func main() {
diff --git a/tests/functional/horizon_controller_test.go b/tests/functional/horizon_controller_test.go
index e86d72d6..418e3fe0 100644
--- a/tests/functional/horizon_controller_test.go
+++ b/tests/functional/horizon_controller_test.go
@@ -212,10 +212,6 @@ var _ = Describe("Horizon controller", func() {
 				ContainSubstring("OPENSTACK_KEYSTONE_URL = \"http://keystone-public-openstack.testing/v3\""))
 			Expect(cm.Data["local_settings.py"]).Should(
 				ContainSubstring("'LOCATION': [ 'memcached-0.memcached:11211', 'memcached-1.memcached:11211', 'memcached-2.memcached:11211' ]"))
-			th.AssertRouteExists(types.NamespacedName{
-				Name:      "horizon-public",
-				Namespace: horizonName.Namespace,
-			})
 		})
 	})
 
diff --git a/tests/functional/suite_test.go b/tests/functional/suite_test.go
index b1e6fe4e..dcf53aaa 100644
--- a/tests/functional/suite_test.go
+++ b/tests/functional/suite_test.go
@@ -37,8 +37,6 @@ import (
 	logf "sigs.k8s.io/controller-runtime/pkg/log"
 	"sigs.k8s.io/controller-runtime/pkg/log/zap"
 
-	routev1 "github.com/openshift/api/route/v1"
-
 	horizonv1 "github.com/openstack-k8s-operators/horizon-operator/api/v1beta1"
 	memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1"
 	keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1"
@@ -88,8 +86,6 @@ var _ = BeforeSuite(func() {
 	memcachedCRDs, err := test.GetCRDDirFromModule(
 		"github.com/openstack-k8s-operators/infra-operator/apis", "../../go.mod", "bases")
 	Expect(err).ShouldNot(HaveOccurred())
-	routev1CRDs, err := test.GetOpenShiftCRDDir("route/v1", "../../go.mod")
-	Expect(err).ShouldNot(HaveOccurred())
 
 	By("bootstrapping test environment")
 	testEnv = &envtest.Environment{
@@ -97,7 +93,6 @@ var _ = BeforeSuite(func() {
 			filepath.Join("..", "..", "config", "crd", "bases"),
 			keystoneCRDs,
 			memcachedCRDs,
-			routev1CRDs,
 		},
 		ErrorIfCRDPathMissing: true,
 		WebhookInstallOptions: envtest.WebhookInstallOptions{
@@ -120,8 +115,6 @@ var _ = BeforeSuite(func() {
 	Expect(err).NotTo(HaveOccurred())
 	err = memcachedv1.AddToScheme(scheme.Scheme)
 	Expect(err).NotTo(HaveOccurred())
-	err = routev1.AddToScheme(scheme.Scheme)
-	Expect(err).NotTo(HaveOccurred())
 
 	//+kubebuilder:scaffold:scheme